Struts2總結

fmms 12年前發布 | 65K 次閱讀 Struts2 Web框架

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>

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!