首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

马战士 struts2 笔记

2013-02-03 
马士兵 struts2笔记转自: 马士兵 struts2 笔记01 Struts2-Action一、Struts作用:将请求与结果分开二、搭建St

马士兵 struts2 笔记

转自: 马士兵 struts2 笔记

01 Struts2-Action一、Struts作用:将请求与结果分开二、搭建Struts2的运行环境:1、建立Web项目;2、建立Struts2的配置文件(struts.xml);     将Struts2的空项目中的配置文件(struts.xml)复制到项目的src目录下。     配置如下:<!--     struts.devMode : 是否设置为开发模式 true:是开发模式,否则不是           注:在开发模式下,修改Struts的配置文件后不需要重新启动Tomcat服务器即生效。             否则修改Struts配置文件后需要重新启动Tomcat服务器才生效。     -->   <constant name="struts.devMode" value="true" />       <!--      namespace :对应与项目名称后面的"/"(例如Struts2_0100_Introduction后面的"/")        (http://localhost:8080/Struts2_0100_Introduction/)      -->    <package name="default" namespace="/" extends="struts-default">        <action name="hello">            <result>                /hello.jsp            </result>        </action></package>3、复制Struts2相应的jar包及第三方包。     将空项目中lib目录中的除junit和spring-test之外的所有文件复制到项目的WebRoot/WEB-INF/lib目录下4、修改对应的web.xml,建立struts2的filter(参考struts自带的项目),添加如下配置:    <filter>        <filter-name>struts2</filter-name>        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>    </filter>     <filter-mapping>        <filter-name>struts2</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping> 三、NamespaceNamespace决定了action的访问路径,默认为“”,可以接收所有路径的action,如果没有找到相应的namespace时,则使用namespace为空的actionNamespace可以写为/,或者/xxx,或者/xxx/yyy,对应的action访问路径为/index.action、/xxx/index.action、或者/xxx/yyy/index.action.Namespace最好也用模块来进行命名。namespace :对应与项目名称后面的"/"(例如Struts2_0100_Introduction后面的"/")        (http://localhost:8080/Struts2_0100_Introduction/) 四、<package>标签<package>是用来解决重名的问题,例如当系统的前台和后台都有一个action名叫hello,这时就需要用package来区分。    前台<package name="front">后台<package name="back">struts2中的package与java的package是相同的作用的。五、Action具体视图的返回可以由用户自己定义的Action来决定具体的手段是根据返回的字符串找到对应的配置项,来决定视图的内容,有三种手段:<constant name="struts.devMode" value="true" />    <package name="front" extends="struts-default" namespace="/">        <action name="index" />…………注:<base>标签:当前页面中所有连接都会在前面加上base地址。七、Action的动态调用方法Action执行的时候并不一定要执行execute方法,我们可以指定Action执行哪个方法:1、   方法一(通过methed属性指定执行方法):可以在配置文件中配置Action的时候用method=来指定执行哪个方法<action name="userAdd" method="add">            <result>/user_add_success.jsp</result></action>    这样,只要在action的对象中有一个add的方法,并且返回类型为String就可以了。如果没有method属性,则默认执行execute()方法。import com.opensymphony.xwork2.ActionSupport;public class UserAction extends ActionSupport {    public String add() {       return SUCCESS;    }  }2、   动态方法调用DMI(推荐)可以在url地址中动态指定action执行那个方法。Url地址如下:http://localhost:8080/Struts2_0500_ActionMethod/user/user!add方法:action + ! + 方法名注:只要Action对象中有这个方法,并且返回类型为String就可以调用。这样Struts.xml配置文件中不需要配置methed属性。代码如下:<action name="user" extends="struts-default" namespace="/actions">        <action name="Student*" method="{1}">            <result>/Student{1}_success.jsp</result>        </action>               <action name="*_*" method="{2}">            <result>/{1}_{2}_success.jsp</result>            <!-- {0}_success.jsp -->        </action></package>解释:第一个Action的名称为name=”Student*” method=”{1}”,表示所有Action以Student开始的都会执行这个Action,并且执行Student后字符为方法名的方法,例如:访问的Action为Studentadd,会执行这个Action(Student*),并且执行add的方法.因为{1}在这里代表add,并且返回/Studentadd_success.jsp页面。第二个Action的名称name=”*_*” method=”{2}” class=”…action.{1}Action” 表示所有Action中包含下划线(“_”)都会执行这个Action,例如:Teacher_add,那么会执行这个Action,并且Action对应的类为TeacherAction,且执行Action中的add方法,返回结果页面为/Teacher_add_success.jsp,因为在这里的{1}表示Teacher,{2}表示add3、   匹配顺序当匹配的Action有两个以上时,则会按匹配精确度高的那个Action,当有个相同的匹配精确度时,则按先后顺序进行。 九、Action的属性接收参数Action中三种传递并接受参数:1、 在Action添加成员属性接受参数例如请求的URL地址:http://localhost:8080/Struts2_0700_ActionAttrParamInput/user/user!add?name=a&age=8其中传递了两个参数:name和age,其值分别为:a、8,此Action执行的是add()方法。那我们只要在user这个Action对象中添加这两个成员属性并生成set、get方法。public class UserAction extends ActionSupport {       private String name;    private int age;       public String add() {       System.out.println("name=" + name);       System.out.println("age=" + age);       return SUCCESS;    }    public String getName() {       return name;    }    public void setName(String name) {       this.name = name;    }    public int getAge() {       return age;    }    public void setAge(int age) {       this.age = age;    }  }2、 域模型(Domain Model)就是利用对象域来进行传递和接受参数例如请求的URL地址:http://localhost:8080/Struts2_0800_DomainModelParamInput/user/user!add?user.name=a&user.age=8其中,访问的是namespace=”/user” action的name=”user” Action所执行的方法method=”add”     利用对象域user来传递参数,为对象的属性赋值(user.name=a user.age=8)     注:需要一个对象user 并且这个对象需要有两个成员属性,且具有get、set方法。     然后在Action中添加一个User对象的成员属性。并且有get、set方法,就可以了。//User对象public class User {  private String name;  private int age;  public String getName() {     return name;  }  public void setName(String name) {     this.name = name;  }  public int getAge() {     return age;  }  public void setAge(int age) {     this.age = age;  }}     //Action类public class UserAction extends ActionSupport {  private User user;  //private UserDTO userDTO;  public String add() {     System.out.println("name=" + user.getName());     System.out.println("age=" + user.getAge());     return SUCCESS;  }   public User getUser() {     return user;  }  public void setUser(User user) {     this.user = user;  }}3、 ModelDriven接收参数使Action实现com.opensymphony.xwork2.ModelDriven<User>(在实现接口时需要使用泛型,否则使用时需要转型)中利用其getModel()方法返回对象模型,从而获得传入的参数。例如URL如下:http://localhost:8080/Struts2_0900_ModelDrivenParamInput/user/user!add?name=a&age=8其:访问的是namespace=”/user” action的name=”user” Action所执行的方法method=”add”,其传入了两个参数:name=a,age=8。参数被传入至Action后,会被ModelDriven对象根据参数名自动赋值给User对象相应的属性而生成User对象,并且由getModel()返回。那么我们在Action中就可以利用这个对象了。注意:传入的参数名需要与对象模型中的成员属性一致。对象模型User:public class User {    private String name;    private int age;    public String getName() {       return name;    }    public void setName(String name) {       this.name = name;    }    public int getAge() {       return age;    }    public void setAge(int age) {       this.age = age;    }}    Action对象import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.ModelDriven;public class UserAction extends ActionSupport implements ModelDriven<User>{  private User user = new User();  public String add() {     System.out.println("name=" + user.getName());     System.out.println("age=" + user.getAge());     return SUCCESS;  }  @Override  public User getModel() {     return user;  }   }  十、Action属性接收参数中文问题如果表单提交数据中有中文时,尽量使用post方式。需要在Struts.xml配置文件中加入一个常量配置,如下:<struts>    <constant name="struts.devMode" value="true" />    <constant name="struts.i18n.encoding" value="GBK" /><!-- internationalization -->    <package name="user" extends="struts-default" namespace="/user">        <action name="userAdd" method="add">            <result>/user_add_success.jsp</result>        </action>    </package></struts>但是,在Struts2 2.7之前,这个配置无效,需要其它方法设置。如下:手动在web.xml中在Struts过滤器之前配置一个过滤器用于解决中文的问题。十一、     简单数据验证使用addFieldError方法和s:fieldError标签简单处理数据校验场景:对一个用户名进行验证,如果用户名不合法,则显示给客户端查看信息。URL请求地址:http://localhost:8080/Struts2_1100_SimpleDataValiation/user/user!add?name=a 分析:访问的Struts2配置,namespace=”/user” action的name=”user” Action所执行的方法method=”add”并且传入了一个参数name=a.如下:<package name="user" extends="struts-default" namespace="/user">        <action name="user" theme="simple"/>    <br />    <s:property value="errors.name"/>    <s:debug></s:debug></body>注:使用<s:fielderror>标题,需要使用<%@taglib>命令引用Struts2的标签库如下:       <%@taglib uri="/struts-tags" prefix="s" %>1、<s:fielderror>标签:获取使用addFieldError()方法添加的信息。                   FiledName:指定信息的名称。                   Theme: 指定显示的主题。    注:使用此标签获取的错误信息,Struts强制添加了css的修饰。生成的HTML代码如下(不长用):<ul encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts>    <package name="login" extends="struts-default" namespace="/login">        <action name="login*" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts>    <constant name="struts.devMode" value="true" />    <include file="login.xml" /></struts> 十四、     默认的Action当用户访问的namespace下一个不存在的Action,则会将使用默认的Action。使用<default-action-ref name=”name”>标签 其中 name属性指向下面已经定义的Action名称了。<struts>    <constant name="struts.devMode" value="true" />       <package name="default" namespace="/" extends="struts-default">    <default-action-ref name="index"></default-action-ref>    <action name="index">        <result>/default.jsp</result>    </action>    </package></struts>当前访问namespace=”/”下不存在的Action时,则返回自动转到访问/default.jsp页面。 十五、     Action总结1、 实现一个Action的最常用的方式:从ActionSupport继承2、 DMI动态方式的调用:!3、 通配符配置:* {1} {2}4、 接收参数的方式(一般属性或DomainModel来接收)5、 简单参数验证addFieldErrora)   一般不使用Struts的UI标签6、 访问Web元素a)   Map类型              i.      IoC             ii.      依赖Struts2b)   原始类型              i.      IoC             ii.      依赖Struts27、 包含文件配置02 Struts2-Result一、Result类型 (type)1、 dispatcher运用服务器跳转 jsp forward不可以是Action,只可以跳转到视图2、 redirect客户端跳转(重定向)-url发生变化不可以是Action,只可以跳转到视图3、 chain跳转到Action (forward action)可以动用到Action在访问Action时,Action前面不要加”/”4、 redirectAction客户端跳转到Action――-url发生变化5、 freemarker6、 httpheader发送一个http头7、 stream下载8、 velocity9、 xslt10、   plaintext返回页面的源码11、   titles把页面分成几块,每个页面都可以动态的指定<struts>    <constant name="struts.devMode" value="true" />    <package name="resultTypes" namespace="/r" extends="struts-default">        <action name="r1">        <result type="dispatcher">/r1.jsp</result>        </action>               <action name="r2">        <result type="redirect">/r2.jsp</result>        </action>               <action name="r3">        <result type="chain">r1</result>        </action>               <action name="r4">        <result type="redirectAction">r2</result>        </action>           </package></struts> 注:当访问不同的namespace下的Action时,则使用如下方式:<result type="chain">            <param name="actionName">dashboard</param>//Action名称            <param name="namespace">/secure</param>//namespace值</result> 二、全局结果集(Globle Result)当有多个Action使用同一个结果集时,则可以使用全局结果集(Globle Result),如下:<package name="user" namespace="/user" extends="struts-default">      <global-results>        <result name="mainpage">/main.jsp</result>    </global-results>       <action name="index">        <result>/index.jsp</result>    </action>     <action name="user" namespace="/admin" extends="user">    <action name="admin" value="true" />    <package name="user" namespace="/user" extends="struts-default">           <action name="user" namespace="/user" extends="struts-default">           <action name="user" value="true"></constant> 使用一个实例如说明OGNL表达式语言,如下:Cat类package com.wjt276.struts2.ognl;public class Cat {  private Dog friend;   public Dog getFriend() {     return friend;  }  public void setFriend(Dog friend) {     this.friend = friend;  }  public String miaomiao() {     return "miaomiao";  }}Dog类package com. wjt276.struts2.ognl;public class Dog {  private String name;  public Dog() {    }  public Dog(String name) {     super();     this.name = name;  }    public String getName() {     return name;  }  public void setName(String name) {     this.name = name;  }  @Override  public String toString() {     return "dog: " + name;  }}S类package com. wjt276.struts2.ognl;public class S {  public static String STR = "STATIC STRING";    public static String s() {     return "static method";  }} User类package com. wjt276.struts2.ognl;public class User {  private int age = 8;  public User() {}   public User(int age) {     super();     this.age = age;  }  public int getAge() {     return age;  }  public void setAge(int age) {     this.age = age;  }    @Override  public String toString() {     return "user" + age;  }} OgnlAction类package com. wjt276.struts2.ognl;public class OgnlAction extends ActionSupport {  private Cat cat;  private Map<String, Dog> dogMap = new HashMap<String, Dog>();  private Set<Dog> dogs = new HashSet<Dog>();  private String password;  private User user;  private String username;  private List<User> users = new ArrayList<User>();   public OgnlAction() {     users.add(new User(1));     users.add(new User(2));     users.add(new User(3));      dogs.add(new Dog("dog1"));     dogs.add(new Dog("dog2"));     dogs.add(new Dog("dog3"));         dogMap.put("dog100", new Dog("dog100"));     dogMap.put("dog101", new Dog("dog101"));     dogMap.put("dog102", new Dog("dog102"));       }  public String execute() {     return SUCCESS;  }  public Cat getCat() {     return cat;  }    public Map<String, Dog> getDogMap() {     return dogMap;  }  public Set<Dog> getDogs() {     return dogs;  }    public String getPassword() {     return password;  }    public User getUser() {     return user;  }  public String getUsername() {     return username;  }  public List<User> getUsers() {     return users;  }  public String m() {     return "hello";  }  public void setCat(Cat cat) {     this.cat = cat;  }    public void setDogMap(Map<String, Dog> dogMap) {     this.dogMap = dogMap;  }  public void setDogs(Set<Dog> dogs) {     this.dogs = dogs;  }  public void setPassword(String password) {     this.password = password;  }  public void setUser(User user) {     this.user = user;  }  public void setUsername(String username) {     this.username = username;  }  public void setUsers(List<User> users) {     this.users = users;  }}Struts2.xml配置文件:<struts>    <constant name="struts.enable.DynamicMethodInvocation" value="false" />    <constant name="struts.devMode" value="true" />    <!-- 允许ognl访问静态方法 -->    <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>  <include file="/com/wjt276/struts2/ognl/ognl.xml"/></struts>Com.wjt276.struts2.ognl.ognl.xml配置文件    <package name="ognl" extends="struts-default">        <action name="ognl" /></li>       <li>访问值栈中action的普通方法:<s:property value="m()" /></li>       <hr />       <li>访问静态方法:<s:property value="@com.wjt276.struts2.ognl.S@s()"/></li>       <li>访问静态属性:<s:property value="@com.wjt276.struts2.ognl.S@STR"/></li>       <li>访问Math类的静态方法:<s:property value="@@max(2,3)" /></li>       <hr />       <li>访问普通类的构造方法:<s:property value="new com.bjsxt.struts2.ognl.User(8)"/></li><%--返回对象的toString()生成的数据--%>       <hr />       <li>访问List:<s:property value="users"/></li>       <li>访问List中某个元素:<s:property value="users[1]"/></li>       <li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>       <li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>       <li>访问Set:<s:property value="dogs"/></li>       <li>访问Set中某个元素:<s:property value="dogs[1]"/></li>       <li>访问Map:<s:property value="dogMap"/></li>       <li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[/"dog101/"]"/></li>       <li>访问Map中所有的key:<s:property value="dogMap.keys"/></li>       <li>访问Map中所有的value:<s:property value="dogMap.values"/></li>       <li>访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>       <hr />       <li>投影(过滤):<s:property value="users.{?#this.age==1}[0]"/></li>       <li>投影:<s:property value="users.{^#this.age>1}.{age}"/></li><%--头一个 --%>       <li>投影:<s:property value="users.{$#this.age>1}.{age}"/></li><%--最后一个--%>       <li>投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li>        <hr />       <li>[]:<s:property value="[0].username"/></li><%--值堆栈中的对象(Object),从上开始的第0个至堆栈底对象 --%>         </ol>    <s:debug></s:debug>访问后服务器返回给客户端的结果:1.        访问值栈中的action的普通属性: username = u2.        访问值栈中对象的普通属性(get set方法):9 | 9 | 9 | wrong:3.        访问值栈中对象的普通属性(get set方法):4.        访问值栈中对象的普通方法:15.        访问值栈中对象的普通方法:6.        访问值栈中action的普通方法:hello7.        访问静态方法:static method8.        访问静态属性:STATIC STRING9.        访问Math类的静态方法:310.     访问普通类的构造方法:user811.     访问List:[user1, user2, user3]12.     访问List中某个元素:user213.     访问List中元素某个属性的集合:[1, 2, 3]14.     访问List中元素某个属性的集合中的特定值:1 | 115.     访问Set:[dog: dog1, dog: dog2, dog: dog3]16.     访问Set中某个元素: <!—没有显示是因为在Set中没有排序就不存在的用下标访问了-->17.     访问Map:{dog102=dog: dog102, dog101=dog: dog101, dog100=dog: dog100}18.     访问Map中某个元素:dog: dog101 | dog: dog101 | dog: dog10119.     访问Map中所有的key:[dog102, dog101, dog100]20.     访问Map中所有的value:[dog: dog102, dog: dog101, dog: dog100]21.     访问容器的大小:3 | 322.     投影(过滤):user123.     投影:[2]24.     投影:[3]25.     投影:false26.     []:u27.     [Debug]04 Struts2-TagsStruts2标签目录1、  通用标签a)    Propertyb)    Set              i.      默认为action scope,会将值放入request和ActionContext中             ii.      page/request/session/applicationc)    beand)    include对中文文件支持的问题,不建议使用,如需要包含,改用jsp包含e)    paramf)    debug2、  控制标签a)    If elseif elseb)    Iterator              i.      collections map enumerateon iterator arrayc)    subset3、  UI标签a)    Theme              i.      Simple xhtml(默认) css_xhtml ajax4、  AJAX标签a)    补充5、  $ # % 的区别a)    $ 用于i18n和Struts配置文件b)    # 取得ActionContext的值c)    % 将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用              i.      参考<s:property>和<s:include> 一、 property标签格式:<s:property value=””default=”” escape=”true|false”/>     如果value中的内容为object,则Struts2都会把它解析成ognl表达式     如果里面需要表示为字符串,则需要将内容用单引号括起来1、  利用ognl表达式取值(例如:取值堆栈中的username值)<s:property value="username"/>2、  取值为字符串需要将内容用单引号括起来<s:property value="’username’"/>3、  设置默认值-default如果一个对象值取不到,则可以使用default设置一个默认值。<s:property value="admin" default=”管理员”/>4、  设定HTML-escape是否设置返回值为HTML原代码样式true:解析返回值的html代码 false:原封不动返回值<s:property value="'<hr/>'" escape="false"/>    二、 set标签注:var 用于设定变量名     value 变量值(可以是ognl表达式),也可以是字符串         scope 就是的作用范围 request session page application action(默认) <li>set 设定adminName值(默认为request 和 ActionContext): <s:set var="adminName" value="username" /></li>      <li>set 从request取值: <s:property value="#request.adminName" /></li><li>set 从ActionContext取值: <s:property value="#adminName" /></li>      <%--<li>set 设定范围: <s:set name="adminPassword" value="password" scope="page"/></li><li>set 从相应范围取值: <%=pageContext.getAttribute("adminPassword") %></li>       --%><li>set 设定var,范围为ActionContext: <s:set var="adminPassword" value="password" scope="session"/></li><li>set 使用#取值: <s:property value="#adminPassword"/> </li><li>set 从相应范围取值: <s:property value="#session.adminPassword"/> </li> 三、 bean标签    定义bean,并使用param来设定新的属性值     <s:bean name="com.bjsxt.struts2.tags.Dog" >              <s:param name="name" value="'pp'"></s:param>    </s:bean>定义bean,并使用一个变量(var)来接受创建的这个bean,取出值来<s:bean name="com.bjsxt.struts2.tags.Dog" var="myDog">               <s:param name="name" value="'oudy'"></s:param></s:bean>拿出值:因为在actionContext中,所以使用#<s:property value="#myDog.name"/> 当<s:bean>不指定var时,则对象相关属性会在值栈中。如果需要访问,则只能在<s:bean>标签内访问。当<s:bean>标签结束后,则值栈就不存在这个对象了。     <s:bean name="com.bjsxt.struts2.tags.Dog" >              <s:param name="name" value="'pp'"></s:param>              <s:property value="name"/>    </s:bean> 四、 <include>标签-少使用包含文件<li>include _include1.html 包含静态英文文件       <s:include value="/_include1.html"></s:include>       </li>             <li>include _include2.html 包含静态中文文件       <s:include value="/_include2.html"></s:include>       </li>             <li>include _include1.html 包含静态英文文件,说明%用法       <s:set var="incPage" value="%{'/_include1.html'}" />       <s:include value="%{#incPage}"></s:include>    </li>%{xxx} 强制将xxx内容转换成OGNL表达式<-- One: --><s:include value="myJsp.jsp" /><-- Two: --><s:include value="myJsp.jsp">   <s:param name="param1" value="value2" />   <s:param name="param2" value="value2" /></s:include><-- Three: --><s:include value="myJsp.jsp">   <s:param name="param1">value1</s:param>   <s:param name="param2">value2</s:param></s:include>五、 If elseif else<li>if elseif else:       age = <s:property value="#parameters.age[0]" /> <br />       <s:set var="age" value="#parameters.age[0]" />       <s:if test="#age < 0">wrong age!</s:if>       <s:elseif test="#parameters.age[0] < 20">too young!</s:elseif>       <s:else>yeah!</s:else><br />             <s:if test="#parameters.aaa == null">null</s:if></li> <s:if test="%{false}">    <div>Will Not Be Executed</div></s:if><s:elseif test="%{true}">    <div>Will Be Executed</div></s:elseif><s:else>    <div>Will Not Be Executed</div></s:else>    六、 Iterator标签<li>遍历集合:<br />       <s:iterator value="{1, 2, 3}" >           <s:property/> |      <!—不需要写其它的,就可以输出数组内的值-->       </s:iterator>       </li>       <li>自定义变量:<br />       <s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">           <s:property value="#x.toUpperCase()"/> |       </s:iterator>       </li>       <li>使用status:<br />       <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>             </li>             <li>       <s:iterator value="#{1:'a', 2:'b', 3:'c'}" >           <s:property value="key"/> | <s:property value="value"/> <br />       </s:iterator>       </li>             <li>       <s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x">           <s:property value="#x.key"/> | <s:property value="#x.value"/> <br />       </s:iterator>       </li> 七、 Theme1、  css(覆盖Struts2原来的css)2、  覆盖单个文件3、  定义自己的theme4、  实战a)    把所有主题定义为simpleb)    Fielderror特殊处理c)    自己控制其他标签的展现  05设计约定(编码规定)1、  原则:简单就是美2、  库名:项目名3、  表的命名:t_model名4、  字段:保持和属性名一致(尽量不要起和数据库命名冲突)5、  用层来划分包com.wjt276.bbs.action model(bean) service dto(vo)6、  Action: xxxAction7、  *.*8、  前台: /9、  后台: /admin10、Package: “action” adminAction 06 项目开发顺序1、  建立界面原型2、  建立Struts.xmla)    确定namespaceb)    确定packgec)    确定Action的名称d)    确定Resulte)    将界面原型页面进行修改,匹配现有设置f)    测试3、  建立数据库(或实体类)4、  建立Model层5、  建立Service层(后面讲hibernate后再完美)a)    此时可以使用Junit进行单元测试了6、  着手开发 07 声明式异常处理     注:Struts2支持声明式异常处理。    Struts2是通过拦截器(interceptor)来处理声明式异常处理。     要求在DAO、Service、Action层都需要抛出导演就可以了。其它的让Struts2来处理。详细过程如下:实例:如果在列表时出现错误,则方法如下:public List<Category> list() throws SQLException{     Connection conn = DB.createConn();     String sql = "select * from _category";     List<Category> categories = new ArrayList<Category>();     PreparedStatement ps = DB.prepare(conn, sql);     ResultSet rs = null;     try {         rs = ps.executeQuery();         Category c = null;         while(rs.next()){            c = new Category();            …………         }     } catch (SQLException e) {         e.printStackTrace();         throw(e);//此处向外抛出异常,让调用它的方法知道     } finally{         DB.close(rs);         DB.close(ps);         DB.close(conn);             }     return categories;}然后在调用它的Action也向上抛出异常public String list() throws SQLException{     categories = categoryService.list();     return SUCCESS;}注意重点:我们需要在Struts.xml配置文件中配置需要处理的异常就可以了。<action name="*-*" method="{2}">           <result>/admin/{1}-{2}.jsp</result>           <result name="input">/admin/{1}-{2}.jsp</result><!--   <exception-mapping>标签是映射异常处理。表示映射哪种异常,此处是java.lang.Exception,  如果出现异常,那么它会跳转到reslut="error"的结果集,也就是/error.jsp        -->           <exception-mapping result="error" exception="java.lang.Exception"/>           <result name="error">/error.jsp</result></action>当然,我们也可以将所有的异常使用同一个异常映射,那就是<global-exception-mappings>,需要映射的packge只需要继承此package就可以了。如下: <package name="bbs2009-deafult" extends="struts-default">       <global-results>           <result name="error">/error.jsp</result>       </global-results>             <global-exception-mappings>           <exception-mapping result="error" exception="java.lang.Exception"/>       </global-exception-mappings>    </package>     <!-- 后台Action的配置区 -->    <package name="admin" namespace="/admin" extends="bbs2009-default">       <default-action-ref name="index"></default-action-ref>       <action name="index">           <result>index.html</result>       </action>       <action name="*-*" method="{2}">           <result>/admin/{1}-{2}.jsp</result>           <result name="input">/admin/{1}-{2}.jsp</result>           <result name="error">/error.jsp</result>       </action>    </package>注意:如果使用全局异常映射(<global-exception-mappings>)和全局结果集(<global-results>)则需要全局结果集(<global-results>)在前。    如果局部(当前)Action、和全局结果集存在相同的<result>,则使用最近的那个结果。总结:1、  在Action中进行异常映射2、  在package中进行全局异常映射3、  使用继承共用异常映射4、  Struts2中异常处理由拦截器实现(观察struts-default.xml)a)    实际上Struts2的大多数功能都由拦截器实现。  08 国际化一、  国际化资源文件     命名格式:xxx_语言_国家.properties     例如:app_en_US.properties  表示美国 英语          app_zh_CN.properties  表示中国 汉语     资源文件的编码是使用UTF-8的编码,这样中文也必需是UTF-8的格式,则需要将中文转换成UTF-8的,你可以使用propertiesEditor插件来进行输入中文。 app_en_US.properties文件内容welcome.msg=hello world!app_zh_CN.propertieswelcome.msg=欢迎您!二、  Java国际化     要求:资源文件要求存放在classpath的根目录下(src下)。     然后再建立一个Java类和一个main方法如下:这样就可以进行国际化处理了。     public static void main(String[] args) {        ResourceBundle res = ResourceBundle.getBundle("app",Locale.CHINA);        System.out.println(res.getString("welcome.msg"));    }注:java.util.ResourceBundle是加载国际化资源文件的类。利用此类的getBundle()方法加载classpath下的指定开头的文件名的国际化资源文件。并且在加载时需要指定加载哪个国家的国际人资源文件。     此实例中的ResourceBundle.getBundle("app",Locale.CHINA);表示加载以"app"开头的国际化资源文件,并且是中国的(对应的zh_CN)的。     一但国际化资源文件加载上来后,就可以使用ResourceBundle类的getSring("welcome.msg")方法获取当前内容。三、 Struts2国际化Struts2国际化分为:Action级别、package级别、Application级别1、  Action级别条件:要求国际化资源文件名的前缀同相应的Action名,并且国际化资源文件需要与相应的Action在同一个包中例如:我们需要国际化登录页面。如下原始代码:<body>     Login_input <br>    <form action="admin/Login_login">    username:<input name="username" type="text"/><br/>    password:<input name="password" type="password"/>    <input type="submit" value="login">    </form> </body>这里需要对"Login_input"、"username"、"password"、"login"进行国际化。因为登录页面的请求URL为http://localhost:8080/struts2_3200_bbs2009_08/admin/Login-input根据Struts2.xml的配置文件可知对应的Action为LoginAction.java.因为国际化资源文件名应是LoginAction_开头(此处为LoginAction_zh_CN.properties、LoginAction_en_US.properties)如下注意:要求国际化资源文件需要与相应的Action在同一包中(见上第三个图),这样Struts2就可以保证当访问这个LoginAction时国际化资源文件会自动加载。我们在相应的文件中可以直接访问(利用ActionSupport类中的getText()方法。)了。我们现在只需要将登录页面代码修改就可以了。   <body>     <s:property value="getText('login.title')"/><br>    <form action="admin/Login-login" method="post">    <s:property value="getText('login.username')"/><input name="username" type="text"/><br/>    <s:property value="getText('login.password')"/><input name="password" type="password"/>    <input type="submit" value="<s:property value='getText("login.login")'/>">    </form>    <s:debug></s:debug>  </body>注意:Struts2国际化是使用<s:property value=”getText()”/>来获取信息的。格式:<s:property value="getText('login.title',defaultValue)"/>    其中:getText()是ActionSuppot类中的方法。因为<s:property>标签只可以直接使用Action的方法。方法中的参数一:表示国际化资源文件中的标签,因为要求是字符串,所以使用单引号括起来。    参数二:当没有取出数据时,则使用这个默认的值,可以省略此参数。      总结:国际化资源文件建立完、使用标签取值后,其它都将由Struts2来完成。 2、 Package级别Package级别的只是将国际化资源文件建立在package(包)下,要求资源文件名前缀同包名就可以了。其它的使用同Action级别的一样。例如:如果在com.wjt276.bbs2009.action包下建立国际化资源文件,则文件名必须以package开头         package_en_US.properties 及 package_zh_CN.properties总结:1、包级别的资源文件名,必须以package开头         2、包级别的资源文件可以给此包中的所有Action类使用。3、 Application级别Application级别也只是资源文件存放的位置不同,相同的所使用的范围也不一样。资源文件要求存放在classpath的根目录下。国际化资源文件以任何名称开头都可以,只是需要在Struts2.xml配置文件中告诉Struts2资源文件是以什么开头的。例如:现在以项目名为前缀:bbs2009      bbs2009_en_US.properties 及 bbs2009_en_US.properties告诉Struts2资源文件是以什么开头的<constant name="struts.custom.i18n.resources" value="bbs2009"/>四、 资源文件中的参数处理场景:如果一个登录系统,用户登录后页面提示“欢迎您,xxxx”,如果是英文:”Welcome,xxx”     正常应该如下处理:先取职欢迎信息 + 再显示登录的用户名。<s:property value="getText('welcome.msg')"/><s:property value="username"/>     注意:但是这要就需要两个Struts2的标签来完成这件事。         资源文件中welcome.msg的值如下:              welcome.msg=欢迎您, 或  welcome.msg=Welcome,     我们还有别外一种方式解决它,只需要一个Struts2标签,只是加入一个参数,这个标签是<s:text>。具体方式如下:首先是资源文件需要修改,如下      注意:需要在资源文件中使用{index}来表示传入参数是哪一个。这个index是从0开始 文件中的欢迎您,{0}或Welcome,{0}, 如果第一个参数传入值为wjt276,那么页面将显示欢迎您,wjt276或Welcome,wjt276其次需要使用<s:text>标签是获取信息。如下:    <s:text name="welcome.msg">        <s:param value="username"></s:param></s:text>注意:<s:text>标签中的name中的值不需要单引号括起来,因为是OGNL表达式,而<s:property>标签中value=”getText(‘welcome.msg’)”中的值需要用单引号括起来。因为需要传一个字符串五、 国际化-动态语言切换在某些网站中,会发现页面中有国家语言的选择,如:中文、英语、日语等语言供您选择。Struts2也可以实现这种动态语言切换的功能,方法非常的简单。     方法:只需要传入一个参数(参数名必需为request_locale),参数值为”语言_国家”(也就是资源文件的后缀,如zh_CN、en_US)就可以了。例:如果当前访问的页面为中文并且URL为http://localhost:8080/struts2_3200_bbs2009_08/admin/Login-input如果需要切换成英文,则只需要传入一个参数request_locale=en_US就可以了。URL如下http://localhost:8080/struts2_3200_bbs2009_08/admin/Login-input?request_locale=en_US这样当前进程的浏览器就可以访问这个网站的所有页面为英文,至到这个进程结束,因为Struts2向session中写入locale值WW_TRANS_I18N_LOCALE=en_US 09 自定义拦截器一般99.9%用不上 10 类型转换public class MyPointConverter extends DefaultTypeConverter{     @Override    public Object convertValue(Object value, Class toType) {       if(toType == Point.class) {           Point p = new Point();           String[] strs = (String[])value;           String[] xy = strs[0].split(",");           p.x = Integer.parseInt(xy[0]);           p.y = Integer.parseInt(xy[1]);           return p;       }       if(toType == String.class) {           return value.toString();       }       return super.convertValue(value, toType);    }}public class MyPointConverter extends StrutsTypeConverter{     @Override    public Object convertFromString(Map context, String[] values, Class toClass) {                 Point p = new Point();           String[] strs = (String[])values;           String[] xy = strs[0].split(",");           p.x = Integer.parseInt(xy[0]);           p.y = Integer.parseInt(xy[1]);           return p;                }     @Override    public String convertToString(Map context, Object o) {       // TODO Auto-generated method stub       return o.toString();    }} a)   三种注册方式:        i.      局部:XXXAction-conversion.properties1.   p(属性名称) =  converter       ii.      全局:xwork-conversion.properties1.   com.xxx.XXX(类名)= converter     iii.      Annotationb)   如果遇到非常麻烦的映射转换        i.      request.setAttribute();       ii.      session Struts2总结1.         Actiona)         namespace(掌握)b)         path(掌握)c)         DMI(掌握)d)         wildcard(掌握)e)         接收参数(掌握前两种)f)          访问request等(掌握Map IOC方式)g)         简单数据验证(掌握addFieldError和<s:fieldError)2.         Resulta)         结果类型(掌握四种,重点两种)b)         全局结果(掌握)c)         动态结果(了解)3.         OGNL表达式(精通)a)         # % $4.         Struts标签a)         掌握常用的5.         声明式异常处理(了解)6.         I18N(了解)7.         CRUD的过程(最重要是设计与规划)(精通)8.         Interceptor的原理(掌握)9.         类型转换(掌握默认,了解自定义)

?

热点排行