Struts2总结

Struts2

1.    搭建Struts2的开发环境:

1)       导入相应的jar包;6个

2)       编写struts的配置文件;struts.xml

3)       struts2在web中的启动配置;web.xml

2.    第一个struts2应用

3.    actin属性的注入message是action中的变量

<paramname="message">注入参数的值</param>

4.    编写自定义类型转换器:建立自定义局部类型转换器,处理日期类型,通过继承DefaultTypeConverter,(推荐使用StrutsTypeConverter,它继承了DefaultTypeConverter)实现自己的DateTypeConverter,并且在action所在的包下创建HelloWorldAction3-conversion.properties文件;在文件中编写对应关系:birthday=com.lcq.type.converter.DateTypeConverter

将转换的属性和转换器进行绑定。如果是全局,类型转换器就要将properties文件放置在src的根目录下,同时修改文件的名称为:xwork-conversion.properties,修改里边的内容为:要转换的变量的类型=转换器的名称,

转换器的编写:

/**
 * 建立自定义类型转换器,处理日期类型,通过继承DefaultTypeConverter,实现自己的DateTypeConverter
 * @author lcq
 *
 */
public class DateTypeConverter extends DefaultTypeConverter {
 
    @Override
    public Object convertValue(Map<String, Object> context, Objectvalue,
           Class toType) {
       SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
       try {
           if (toType == Date.class) {
              String[] params = (String[]) value;
              return dateFormat.parse(params[0]);
           } else if (toType == String.class) {
              Date date = (Date) value;
              return dateFormat.format(date);
           }
       } catch (ParseException e) {
           // TODO Auto-generatedcatch block
           e.printStackTrace();
       }
       return super.convertValue(context, value, toType);
    }
 
}
 


例如定义的action为:

package com.lcq.action;
 
import java.util.Date;
 
public class HelloWorldAction3 {
    private Date birthday;
 
    public Date getBirthday() {
       return birthday;
    }
 
    public void setBirthday(Date birthday) {
       this.birthday = birthday;
    }
 
    public String addUI(){
   
       return "success";
    }
 
    public String execute(){
      
       return "success";
    }
 
}


5.    访问和添加request/session/application属性,并在页面进行打印输出

    //从struts2封装的ActionContext中获取request/session/application

 

      ActionContext ctx = ActionContext.getContext();
       ctx.getApplication().put("app", "application scope");
       ctx.getSession().put("session", "sessionscope");
       ctx.put("request", "request scope");

jsp中:

 ${applicationScope.app }<br>
        ${sessionScope.session }<br>
        ${requestScope.request }<br>

6.    得到request/session/application对象:

在action中利用ServletActionContext.getxxxx()方法得到

7.    文件上传实现:

1)上传页面:upload.jsp

<form enctype="multipart/form-data" action="${pageContext.request.contextPath}/employee/upload.action" method="post">
   
    file:<input type="file"name="image">
    <input type="submit" value="upload">
    </form>


2) xml中的配置

<action name="upload" class="com.lcq.action.FileUpLoadAction"
           method="execute">
           <result name="success">/WEB-INF/page/uploadMessage.jsp</result>
       </action>


3)Action中的方法

public String execute() throws Exception{
       //构建真实的存放路径
       String realPath = ServletActionContext.getServletContext().getRealPath("/image");
       System.out.println(realPath);
       if(image != null){
       File savefile = new File(new File(realPath),imageFileName);
       if(!savefile.getParentFile().exists()){
           savefile.getParentFile().mkdirs();
       }
       FileUtils.copyFile(image, savefile);
      
       ActionContext.getContext().put("message", "上传成功");
      
       }
       return "success";
}


4)结果页面输出上传信息

  <body>
${message }
 
  </body>


8.    多文件上传只要修改为:同时在action中将相应的参数变为数组即可

  

  <form enctype="multipart/form-data"   action="${pageContext.request.contextPath}/employee/upload.action" method="post">
   
    file1:<input type="file"name="image"><br>
       file2:<input type="file"name="image"><br>
           file3:<input type="file"name="image"><br>
    <input type="submit" value="upload">

action中

  

  private File[] image;// 定义上传文件的文件属性
    private String[] imageFileName;// 得到文件的名称
........
........
........
 
public String execute() throws Exception {
       // 构建真实的存放路径
       StringrealPath = ServletActionContext.getServletContext().getRealPath(
              "/image");
       System.out.println(realPath);
       if (image != null) {
           for (int i = 0; i < image.length; i++) {
              Filesavefile = new File(new File(realPath), imageFileName[i]);
              if(!savefile.getParentFile().exists()) {
                  savefile.getParentFile().mkdirs();
              }
              FileUtils.copyFile(image[i], savefile);
           }
           ActionContext.getContext().put("message", "上传成功");
 
       }
       return "success";
    }

9.    编写自定义拦截器:

1)       继承自Interceptor接口来实现。

public class PermissionInterceptor implements Interceptor {
 
    public void destroy() {
    }
 
    public void init() {
    }
 
    public String intercept(ActionInvocation invocation) throws Exception {
       Object user = ActionContext.getContext().getSession().get("user");
       if(user!=null) return invocation.invoke(); //如果user不为null,代表用户已经登录,允许执行action中的方法
       ActionContext.getContext().put("message", "你没有权限执行该操作");
       return "success";
    }
 
}


2)       在xml中的配置为:

<interceptors>
           <interceptor name="permission"
              class="com.lcq.Interceptor.PermissionInterceptor" />
           <interceptor-stack name="permissionStack">
              <interceptor-ref name="defaultStack" />
              <interceptor-ref name="permission" />
           </interceptor-stack>
       </interceptors>
      
       <global-results>
           <result name="success">/WEB-INF/page/message.jsp</result>
       </global-results>
 
       <action name="userAction" class="com.lcq.action.UserAction"
           method="execute">
           <interceptor-ref name="permissionStack" />
       </action>


10. 对action的所有方法进行输入校验

1)       要进行验证的内容:

<body>
    <s:fielderror/>
    <form action="${pageContext.request.contextPath}//person/manage_save" method="post">
    用户名:<input type="text"name="username">用户名不能为空<br>
    手机号:<input type="text"name="mobile">不能为空,并且要符合手机号的格式1,3/5/8,后面是9个数字<br>
    <input type="submit" value="提 交">
    </form>
  </body>


2)       在action中继承ActionSupport重写validate()方法:

@Override
    public void validate() {//对action的所有方法进行校验
       if(this.username == null || "".equals(this.username.trim())){
           this.addFieldError("username", "用户名不能为空");
       }
       if(this.mobile == null || "".equals(this.mobile.trim())){
           this.addFieldError("mobile", "手机号不能为空");
       }else{
           if(!Pattern.compile("^1[358]\\d{9}{1}quot;).matcher(this.mobile).matches()){
              this.addFieldError("mobile", "手机号格式不对");
           }
       }
 
   
    }


3)       在validate方法中将错误信息放在错误集合中,转到input页面,所以在xml中的配置是:

<struts>
    <package name="person" namespace="/person" extends="struts-default">
       <action name="manage_*" class="com.lcq.action.PersonAction"
           method="{1}">
           <result name="input">/index.jsp</result>
           <result name="message">/WEB-INF/page/message.jsp</result>
       </action>
    </package>
</struts>


4)       如果只是对个别的方法进行校验则只要改正validate方法为validateXxxx()就行,其中Xxxx是要校验的方法的名称。

public void validateUpdate() {//对action的update()方法进行校验
       if(this.username == null || "".equals(this.username.trim())){
           this.addFieldError("username", "用户名不能为空");
       }
       if(this.mobile == null || "".equals(this.mobile.trim())){
           this.addFieldError("mobile", "手机号不能为空");
       }else{
           if(!Pattern.compile("^1[358]\\d{9}{1}quot;).matcher(this.mobile).matches()){
              this.addFieldError("mobile", "手机号格式不对");
           }
       }
 
   
    }


11. 基于xml的输入校验

1)       只要在要校验的action所在包下建立相应的action的xml验证文件即可,在xml中编写:

2)       如果只是对action中的指定方法进行校验则只要修改xml的文件名即可,修改为PersonAction-person-manage_update-validation.xml则该文件只对action中的update方法进行校验

<validators>
    <field name="username">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>用户名不能为空!</message>
        </field-validator>
    </field>
    <field name="mobile">
        <field-validator type="requiredstring">
            <message>手机号不能为空!</message>
        </field-validator>
        <field-validator type="regex">
            <param name="expression"><![CDATA[^1[358]\d{9}$]]></param>
            <message>手机号格式不正确!</message>
       </field-validator>
    </field>
</validators>


12. struts2对异常的处理机制,要编写自己的异常处理类,在struts.xml中进行配置。

13. OGNL表达式语言。

14. EL表达式:${username}可以访问值栈(action。。。)对象中的所有属性,是因为struts2对HttpServletRequest对象进行了封装,但是不能访问:request、application、session、parameters、attr等对象。如果要访问这些对象,要使用#语法进行访问,比如:#application.username或者#application[‘username’],特别注意在EL表达式中只能使用值栈中属性。

15. ognl表达式进行迭代和投影。并且能够使用集合。

16. 可以不用ognl表达式,直接用jstl和el结合来代替使用。

17. 利用token标签防止表单的重复提交问题

1)在jsp页面的表单中添加<s:token></s:token>

2)在对应的action中添加拦截器和不跳转对应的页面:

           <interceptor-ref name="defaultStack" />

           <interceptor-ref name="token" />

           <result name="invalid.token">/updatePerson.jsp</result>


你可能感兴趣的:(Struts2总结)