马士兵尚学堂struts2讲座_视频笔记_基础.doc
尚学堂马士兵struts2讲座_视频笔记_基础部分(1)关键字: struts2 strtus2的jar文件版本:2.1.6 作者:眼镜哥哥爱编程JDK版本选择办法:(1)先选择JDK版本,在window->Preferences->InstalledJREs,选择JDK1.6(2)在选择Compiler版本,在window->Preferences->Compiler,编译器选择1.6(3)最后Tomcat要选择编译器为1.6,在MyEclipse->Servers->Tomcat6.x->JDK,选择1.6 1.struts2的配置(1)struts.xml文件:struts2支持开发模式,这样改配置后不用重新启动Tomcat<constant name="struts.devMode" value="true" /> (2)struts2的.dtd文件加载在XML Catalog中加载dtd文件,首先点add,然后填写Location和key值KeyType:选择URILocation:(文件路径)C:TomcatTempstruts_2.1.6_blank_jarstruts-2.1.dtdKey:(dtd文件名称)http:/struts.apache.org/dtds/struts-2.1.dtd (3)namespace的作用namespace决定了Action的访问路径,默认为"",可以接收所有路径的Actionnamespace必须用"/"开头,可以写为/,或者/xxx,或者/xxx/yyy,对应的action访问路径为/index.action,/xxx/index.action,或/xxx/yyy/index.actionnamespace最好用模块来命名,用来区分重名的情况注意:在copy项目的时候一定要把Web Context-root的值改掉 (4)关于Action<1>action在struts1和struts2的区别:struts1中的action实例有很多时候用的是同一个实例,而struts2中的action每次都会new一个新的实例<2>struts.xml文件中没有action的class配置项默认执行ActionSupport类<3>action的静态和动态(DMI)方法调用静态:在action标签中添加method="(方法名)add"动态:在form标签中的action中写 action="user(ActionName)!add.action"<4>模块包含:把struts.xml里面的package拆开,分为一个一个的模块进行加载<5>DefaultAction(默认Action):如果URL里面没有指定后面的Action或错误的Action,添加默认指向actionName进行转向。e.g:<default-ref-action name="index"></default-ref-action> (5)Path路径问题struts2中的路径问题是根据action的路径而不是jsp路径来确定,所以尽量不要使用相对路径可以用redirect方式解决,但最好使用绝对路径。(用request.getContextRoot方式拿到webapp的路径)或者使用myeclipse经常用的,指定basePath(6)用ActionWildcard通配符来配置action调用路径优点:使用通配符可以将配置量降到最低,不过一定要遵守"约定优于配置"的原则<package name="actions" extends="struts-default" namespace="/actions"> <action name="Student_add"></action> <action name="Student_*" class="com.bjsxt.struts2.action.StudentAction" method="1"> <result>/Student_1_success.jsp</result> </action> <!- 更简便的配置法 -> <action name="*_*" class="com.bjsxt.struts2.action.1Action" method="2"> <result>/1_2_success.jsp</result> </action></package>说明:1.1代表name="Student*"后面第一个'*',同理2代表第二个'*'2.如果action之间有重复配置,struts2会匹配最精确的action。如果通配符配置之间有重复,则看前后配置顺序 (7)action接收参数<1>直接接收参数:URL地址中的参数可以和action中的属性一一对应e.g:http:/localhost:8080/struts2/user!add?name=aaa&age=23action属性->String name,int age<2>使用DomainModel(域模型)接收参数:其实就是把传递的参数当做对象的属性值来传递e.g:http:/localhost:8080/struts2/user!add?user.name=aaa&user.age=23说明:这种方式的使用率是最高的,建议在做项目时多用此方式!<3>使用ModelDriven(模型驱动)接收参数:action要实现ModelDriven<User>来进行参数接收好处是可以简化参数的传递字符数量,但是此方式并不常用地址栏依然是http:/localhost:8080/struts2/user!add?name=aaa&age=23但是action属性确是private User user =new User();/此处需要自己实例化对象实现ModelDriven中的getModel()方法:public User getModel()return user; (8)struts2.1.6中的中文乱码问题在struts.xml文件中写入常量:<constant name="struts.i18n.encoding" value="GBK" />但是由于版本问题在struts2.1.6中这是个bug,在2.1.7中才会解决解决方法1:用spring中的CharacterEncoding过滤器解决解决方法2:在<filter-class>标签中用struts2.0的过滤器e.g:<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> (9)SimpleDateValidate简单数据验证struts2中的标签设定了样式,这并不是我们需要的,我们可以用以下方法来取消格式action中内容:this.addFieldError("name","name is error");jsp页面内容: <s:fielderror fieldName="name" theme="simple" /><s:property value="errors.name0">或<s:property value="fieldErrors.name0">同时也可以用<s:debug>标签来查看ValueStack中的值 (10)访问web元素<1>方式一:获得赋值与显示request,session,applicationprivate Map request;private Map session;private Map application;request = (Map)ActionContext.getContext().get("request");session = ActionContext.getContext().getSession();application = ActionContext.getContext().getApplication();/-|赋值|-request.put("r1","r1");session.put("s1","s1");application.("a1","a1");/-|显示|-<s:property value="#request.r1" />|<%= request.getAttribute("r1")%><br><s:property value="#session.s1" />|<%= session.getAttribute("s1")%><br><s:property value="#application.a1" />|<%= application.getAttribute("a1")%><s:property value="#attr.r1" />|<s:property value="#attr.s1" />|<s:property value="#attr.a1" /> 注意:#attr会自动搜索属性名,但是如果有重名的情况就不好用了,所以建议不要用。<2>方式二:Action实现RequestAware,SessionAware,ApplicationAware接口获得相应对象public class LoginAction extends ActionSupport implements RequestAware private Map<String,Object> request; public String execute() request.put("r1","r1"); return SUCCESS; Override public void setRequest(Map<String,Object> request) this.request = request; <3>方式三:实现ServletRequestAware接口,通过依赖注入得到request实例public class LoginAction extends ActionSupport implements ServletRequestAware private HttpServletRequest request; private HttpSession session; private ServletContext application; public String execute() request.put("r1","r1"); session.put("s1","s1"); application.("a1","a1"); Override public void setServletRequest(HttpServletRequest request) this.request = request; this.session = request.getSession(); this.application = session.getServletContext(); (11)关于result<1>指定result的类型:result的类型有:dispatcher(默认),redirect,chain(可跳转到action,然后再由action指向到具体的jsp页面),redirectAction,此外还有freemarker(模板),httpheader(头信息),stream(上传下载),velocity,xslt,plaintext,tiles等等类型注意:chain类型如果action在另一个包下那么需要指定参数来实现跳转e.g:<result type="chain"><param name="actionName">dashboard</param><param name="namespace">/secure</param></result> <2>GlobelResult全局定向:GlobalResult可实现跳转结果的分类判断逻辑<global-results><result name="mainpage">/main.jsp</result></global-results>注意:如果其他的包也用到了全局跳转页面,需要在package的extends选项里填写上一个包的包名e.g:<package name="user" namespace="/" extends="struts-default"><global-results><result name="mainpage">/main.jsp</result></global-results></package><package name="student" namespace="/" extends="user"></package>说明:extends的用处很大,它让你写出一个公用包,然后通过继承使用公共配置 (12)result动态结果集<1>对action的跳转因为在action中属性都会被放入值栈ValueStack中,所以配置文件就可以通过值栈取得相应的值,$表达式就是用来从ValueStack中取值的。http:/localhost:8080/struts2/user?type=1->struts.xml文件:<package name="user" namespace="/" extends="struts-default"><action name="user" class="(包名).UserAction"><result>$r</result></action></package>->UserAction.java文件public class UserAction extends ActionSupport private int type; private String r; (属性set,get方法省略) Override public String execute() throws Exception if(type = 1) r="/user_success.jsp" else if(type = 2) r="/user_error.jsp" return SUCCESS; <2>对jsp页面的跳转区别:跳转到action是有ValueStack的,但是跳转到jsp没有ValueStack,所以需要用ONGL表达式来获得传递的参数http:/localhost:8080/struts2/user?type=1->struts.xml文件:<package name="user" namespace="/" extends="struts-default"><action name="user" class="(包名).UserAction"><result type="redirect">/user_success.jsp?t=$type</result></action></package>->user_success.jsp页面from valuestack:<s:property value="t" />from actioncontext:<s:property value="#parameters.t" />MyEclipse中HTML快速注释:ctrl+shift+/或者ctrl+shift+c尚学堂马士兵struts2讲座_视频笔记_基础部分(2)关键字: struts2 (13)struts2中的OGNL(Object Graph Navigation Language)表达式应用<1>domainModel对象:domainModel对象必须要提供一个空的构造方法,供容器使用。如果domainModel对象没有在action中实例化,那么在传值的时候,容器会帮助实例化。视频原文:想初始化domainModel,可以自己new也可以传参数值,但这时候需要保持参数为空的构造方法。 <2>ONGL表达式访问静态或动态对象的属性或方法动态对象的属性和方法:可以直接访问,用<对象.属性>或<对象.方法>的形式来取值,如果没有对象默认为当前action的对象中的属性或方法静态对象的属性和方法:首先要在struts.xml文件中加入以下字段<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>然后以包名.类名属性(或方法)来访问静态属性或方法e.g:访问静态属性:<s:property value="com.test.entity.StrstaticSTR" />访问静态方法:<s:property value="com.test.entity.StrstaticMethod()" />访问Math类的静态方法:<s:property value="max(2,3)" />访问普通类的构造方法:<s:property value="new com.test.entity.User(8)" /> <3>ONGL表达式访问集合这个与EL表达式大同小异,看下示例基本就能明白了e.g:访问List:<s:property value="users" />访问List中的某个元素:<s:property value="users1" />访问List中某个元素属性的集合:<s:property value="users.age" />访问List中某个元素属性集合的特定值:<s:property value="users0.age" />|<s:property value="users.age0" />访问Set中某个元素:<s:property value="dogs1" />访问Map中某个元素:<s:property value="dogMap.dog101"/>|<s:property value="dogMap'dog101'"/>|<s:property value="dogMap"dog101""/>访问Map中的所有key:<s:property value="keys"/>访问Map中的所有value:<s:property value="values"/>访问容器的大小:<s:property value="dogMap.size()"/>|<s:property value="users.size"/> <4>ONGL的投影(也叫过滤)ONGL表达式可以通过正则表达式来判断筛选合适的结果e.g: #this:表示遍历集合的临时变量<s:property value="users.?#this.age=1.age" /> /如果没有age属性限定那么OGNL拿到的就是符合条件的对象<s:property value="users.#this.age>1.age" /><s:property value="users.$#this.age>1.age" /><s:property value="users.#this.age>1.age=null" /> <5>在OGNL中的作用->代表值栈valuestack集合,0代表第一个action的valuestack集合。当struts2从一个action跳到另一个action中时候,valuestack就会有两个actione.g: <s:property value="0.username"/> /0可以直接调用valuestack中的对象->#parameters,用于获取参数集合e.g:age=<s:property value="#parameters.age0"/> (14)关于struts2的标签<1>通用标签:<s:property><s:set><s:property>标签,获取到valueStack的同时显示相关的值,多用于设置别名e.g:property:<s:property value="username"/> /此处的username是valuestack中的对象property取值为字符串:<s:property value="'username'"/>property设定默认值:<s:property value="admin" default="管理员"/>property设定HTML:<s:property value="'<hr/>'" escape="false" /> <s:set>标签,可以创建变量同时指定范围(默认为request和ActionContext),scope默认范围是为actionset设定adminName值:<s:property var="adminName" value="username"/>set从request取值:<s:property value="#request.adminName"/>set从ActionContext取值:<s:property value="#adminName"/>set设定范围:<s:property name="adminPassword" value="password" scope="page"/>set从相应范围取值:<%=pageContext.getAttribute("adminPassword")%>->struts2.0用set设定,取值set设定name,id,范围为ActionContext:<s:set name="adminPassword" value="password" var="a"/>set使用#取值:<s:property value="#a"/>->struts2.1用set设定,取值set设定var,范围为ActionContext:<s:set var="adminPassword" value="password"/>set使用#取值:<s:property value="#adminPassword"/> <s:bean>标签,定义bean,并使用param来设定新的属性值e.g:<s:bean name="com.test.entity.Dog" var="myDog"><s:param name="name" value="'oudy'"></s:param></s:bean>注意:如果没有加var属性,那么容器会把Dog类压到栈顶,当<s:bean>标签结束时就会从栈顶移走 <s:include>标签,因为struts2.1.6的中文编码Bug还没有解决,所以常用的是jsp标签的include包含e.g:<s:set var="incPage" value="'_include1.html'"/><s:include value="%#incPage"></s:include><2>控制标签:控制标签主要有<s:if><s:elseif><s:else>和<s:iterator>主要作用是进行流程控制复习下#parameters,用于获取参数集合e.g:age=<s:property value="#parameters.age0"/><s:if test="#parameters.age0 < 0">wrong age!</s:if><s:elseif test="#parameters.age0 < 20">too young!</s:elseif><s:else>yeah!</s:else><s:if test="#parameters.aaa = null">null</s:if>这段代码也可以用<s:set>标签进行简化e.g:<s:set var="age" value="#parameters.age0" /><s:if test="#age < 0">wrong age!</s:if><s:elseif test="#age < 20">too young!</s:elseif><s:else>yeah!</s:else><s:iteratro>标签中,value处填写集合,var表示临时变量(相当于for循环中的i),status记录了当前循环的状态。无value属性的<s:property/>标签可以把遍历元素都显示出来。iterator可遍历的集合有:collections,map,enumeration,iterator,arraye.g:<s:iterator value="'abc','def','ghi'" var="it"><s:property value="#it.toUpperCase()" /></s:iterator><!- 包含status的iterator标签 -><s:iterator value="'aaa','bbb','ccc'" status="status"><s:property />|遍历过的元素总数:<s:property value="#status.count"/>|便利过的元素索引:<s:property value="#status.index"/>|当前是偶数吗?<s:property value=""#status.even/>|当前是奇数吗?<s:property value="#status.odd"/>|是第一个元素吗?<s:property value="#status.first"/>|是最后一个元素吗?<s:property value="#status.last"/><br/></s:iterator><!- iterator遍历Map集合 -><s:iterator value="#1:'a',2:'b',3:'c'" ><s:property value="key"/>|<s:property value="value"/></s:iterator><s:iterator value="#1:'a',2:'b',3:'c'" var="x"><s:property value="#x.key"/>|<s:property value="#x.value"/></s:iterator> <3>UI标签:Struts2自带了theme(主题),这样很大程度上给程序员与美工带来了许多麻烦。struts官方推荐用模板覆盖法或者新建法来重新定义主题文件。我们可以在struts.xml文件中指定主题样式:<constant name="struts.ui.theme" value="simple" />e.g:覆盖法1.在src目录下新建template文件夹2.在template文件夹下新建simple文件夹3.在simple文件夹继续新建fielderror.flt文件,这样就可以完成<s:fieldError>标签的模板覆盖4.注意,在使用覆盖法时必须要懂得freemaker的写法,这样对技术水平要求很高,不推荐使用e.g:新建法新建法与覆盖法大同小异,只是在指定样式的使用用自定义的名称,同样也需要会修改freemaker所以推荐使用样式覆盖法,当你想要修改<s:fieldError>标签的样式的时候最好重写下.errorMessage <4>$#%的区别:(a)$用于i8n和struts配置文件(b)#取得ActionContext的值(c)%将原本的文本属性解析为ognl,对于本来就是ognl表达式的属性不起作用。参考<s:property>和<s:include>