[原]Struts2-深入探索

xiaoxiao2022-06-14  27

[标题]:[原]Struts2-深入探索 [时间]:2009-8-26 [摘要]:Struts2中一些零碎的知识点:struts.xml详解、模型驱动、Preparable接口、防止表单重复提交、ActionContext、动态方法调用、异常 [关键字]:浪曦视频,Struts2应用开发系列,WebWork,Apache,深入探索 [环境]:struts-2.1.6、JDK6、MyEclipse7、Tomcat6 [作者]:Winty (wintys@gmail.com) http://www.blogjava.net/wintys [正文]: 1、struts.xml详解 a. struts.properties     在struts.xml中可以定义constant覆盖struts-core.jar/org/apache/struts2/default.properties中的设置。     例:<constant name="struts.custom.i18n.resources" value="message"/>     也可以直接新建struts.properties (与struts.xml在同一目录),在struts.properties中配置。推荐在struts.properties中进行配置。     例:struts.custom.i18n.resources = message b. abstract package     struts-core.jar/struts-default.xml,中有如下定义。     <package name="struts-default" abstract="true" >         ......     </package>     其中abstract="true"中,表示在此package中不能定义Action(与Java abstract类相似),仅供继承。 c. namespace     strut.xml中:     <package name="MyStruts" extends="struts-default" namespace ="/ mystruts">     ......     </package>     默认命名空间为namespace="",命名空间要以"/"开头。     JSP访问:<s:form action="miscellaneous" namespace="/mystruts" >。     不能写成<s:form action="/mystruts/miscellaneous"> ,否则会发生错误:"No configuration found for the specified action: '/mystruts/miscellaneous' in namespace: '/miscellaneous'. Form action defaulting to 'action' attribute's literal value."[2]。 d. 模块化配置     ......     <struts>         <include file="struts1.xml" />         <package ...>             ......         </package>     </struts>     include中struts1.xml的编写与struts.xml是类似的。 2、属性驱动与模型驱动 属性驱动:直接在Action中写表单属性。 /StrutsHelloWorld/src/wintys/struts2/miscellaneous/MiscellaneousAction.java:

package wintys.struts2.miscellaneous; import com.opensymphony.xwork2.ActionSupport; /**  *  * @author Winty (wintys@gmail.com)  * @version 2009-8-24  * @see http://wintys.blogjava.net  */ @SuppressWarnings("serial") public class MiscellaneousAction extends ActionSupport {     private String name;     private String password;     public String getName() {         return name;     }     public void setName(String name) {         this.name = name;     }     public String getPassword() {         return password;     }     public void setPassword(String password) {         this.password = password;     }          @Override     public String execute() throws Exception {         return SUCCESS;     } }

模型驱动:将属性放到JavaBean中,Action需要实现com.opensymphony.xwork2.ModelDriven接口。ModelDrivenInterceptor 必须在之前StaticParametersInterceptor and ParametersInterceptor。这个顺序已在defaultStack Interceptor中定义。 /StrutsHelloWorld/src/wintys/struts2/miscellaneous/User.java:

package wintys.struts2.miscellaneous; /**  * 模型驱动Action中的模型  * @author Winty (wintys@gmail.com)  * @version 2009-8-25  * @see http://wintys.blogjava.net  */ public class User {     private String name;     private String password;     public String getName() {         return name;     }     public void setName(String name) {         this.name = name;     }     public String getPassword() {         return password;     }     public void setPassword(String password) {         this.password = password;     } }

/StrutsHelloWorld/src/wintys/struts2/miscellaneous/MiscellaneousModelDrivenAction.java:

package wintys.struts2.miscellaneous; import com.opensymphony.xwork2.ModelDriven; @SuppressWarnings("serial") public class MiscellaneousModelDrivenAction extends ActionSupport implements         ModelDriven<User>{          private User user = new User();          @Override     public User getModel() {         return user;     }          @Override     public String execute() throws Exception {         return SUCCESS;     } }

3、Preparable接口     Action还可以实现com.opensymphony.xwork2.Preparable接口,用于准备Action自己。Preparable中的prepare方法在Action执行其它方法前执行。 4、使用simple 主题时,如何单独格式化Struts错误提示信息     单独显示name字段的fielderror:

<s:fielderror>      <s:param>name</s:param> </s:fielderror>

5、Struts防止表单重复提交     JSP页面中加入token和actionerror: <s:actionerror /> <s:form .../>     <s:token /> </s:form>     token产生的actionerror的i18n key为:struts.message.invalid.token。     在struts.xml中的Action配置中加入token interceptor,和invalid.token result:

        <action name="miscellaneous" class="wintys.struts2.miscellaneous.MiscellaneousModelDrivenAction">             <result name="success">/miscellaneous/output.jsp</result>             <result name="input">/miscellaneous/input.jsp</result>             <result name=" invalid.token " >/miscellaneous/input.jsp</result>             <interceptor-ref name=" token " />             <interceptor-ref name="defaultStack" />         </action>

    生成的JSP页面如下:     <input type="hidden" name="struts.token.name" value="struts.token " />     <input type="hidden" name="struts.token " value="ORU0RZIP8JWQ7BDZG4P1NJSEKITGG6X5" />     struts.token.name指<s:token />中的name,默认为struts.token。也可以自己指定<s:token name="mytoken" />。则生成如下token:     <input type="hidden" name="struts.token.name" value="mytoken" />     <input type="hidden" name="mytoken" value="GFD13EW206G2DY9AB3SRIAVXXT1S915C" /> 6、通过Struts获取Servlet API     一般Java Web程序不能离开容器进行测试。容器内测试常用框架:Cactus(jakarta.apache.org/cactus/index.html) 、Mock。     通过Struts获取Servlet API,使程序可脱离容器测试。Struts中可通过如下方法获取Servlet API:ActionContext 、ServletActionContext、ServletXXXAware。首选ActionContext,其次选择ServletActionContext,再次ServletXXXAware。 a. ActionContext     com.opensymphony.xwork2.ActionContext.getActionContext()获取ActionContext实例。     ActionContext的get()和put()方法与HttpServletRequest的对应关系:     ActionContext.get() <=> HttpServletRequest.getAttribute()     ActionContext.put() <=> HttpServletRequest.setAttribute()     例:

        ActionContext context = ActionContext.getContext();         context.put("info", "this is ActionContext value");

         但是ActionContext无法获取Servlet HttpResponse对象。 b. ServletActionContext     org.apache.struts2.ServletActionContext是com.opensymphony.xwork2.ActionContext的子类。     使用静态方法直接获取Servlet对象:     Request: ServletActionContext.getRequest();     Response: ServletActionContext.getResponse();     Session: ServletActionContext.getRequest().getSession();     例:

        Cookie cookie = new Cookie("mycookie" , "10000");         HttpServletResponse response = ServletActionContext.getResponse() ;         response.addCookie(cookie);

c. ServletXXXAware接口     org.apache.struts2.util.ServletContextAware接口     org.apache.struts2.interceptor.ServletRequestAware接口     org.apache.struts2.interceptor.ServletResponseAware接口     org.apache.struts2.interceptor.SessionAware接口     实现ServletXXXAware接口的Action会被Struts自动注入相应的Servlet对象。     例:

package wintys.struts2.miscellaneous; import org.apache.struts2.interceptor.ServletRequestAware; import com.opensymphony.xwork2.ActionSupport; @SuppressWarnings("serial") public class MiscellaneousModelDrivenAction extends ActionSupport implements          ServletRequestAware {     private HttpServletRequest request;     ......     @Override     public String execute() throws Exception {         //实现ServletRequestAware接口,Struts自动注入的request         Cookie[] cookies = this.request.getCookies();         for(Cookie ck : cookies){             System.out.print("cookie:" + ck.getName());             System.out.println(" = " + ck.getValue());         }         return SUCCESS;     }     ......     @Override     public void setServletRequest (HttpServletRequest request) {         this.request = request;     } }

7、动态方法调用 a. Action配置中,由method指定动态调用方法的名称。 <action name="myaction" class="com.tests.MyAction" method="myexecute "> ...... </action> b.在JSP页面中,调用Action时加感叹号指定动态调用方法的名称。 <s:form action="myaction!myexecute " /> c.通配符 <action name="*action " class="com.tests.MyAction" method="{1} "> 则请求中helloaction对应到action中的hello()方法,以此类推。 8、异常     发生异常时,可转到指定的result。由exception-mapping配置

<action name="miscellaneous" class="wintys.struts2.miscellaneous.MiscellaneousModelDrivenAction">     <result name="success">/miscellaneous/output.jsp</result>     <result name="input">/miscellaneous/input.jsp</result>     < exception-mapping   exception="wintys.struts2.miscellaneous.NameInvalidException" result="nameInvalid" />     <result name="nameInvalid">/miscellaneous/nameInvalidException.jsp</result> </action>

    也可以配置全局exception mapping

<global-exception-mapping>     <exception-mapping result="nameInvalid" /> </global-exception-mapping>

    nameInvalidException.jsp:

<s:property value="exception"/> <s:property value="exceptionStack" />

NameInvalidException.java:

package wintys.struts2.miscellaneous; @SuppressWarnings("serial") public class NameInvalidException extends Exception {     public NameInvalidException(String message) {         super(message);     } }

9、详细代码 /StrutsHelloWorld/WebRoot/miscellaneous/input.jsp:

<%@ page language="java"  contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html>   <head>     <title>Input</title>   </head>   <body>      <s:actionerror/>           <s:form action="miscellaneous" method="post" theme="simple" namespace="/mystruts">         <s:token name="mytoken"/>                  用户名:<s:textfield name="name" />         <s:fielderror >             <s:param>name</s:param>         </s:fielderror>         <br />                           密码:<s:textfield name="password"/>         <s:fielderror >             <s:param>password</s:param>         </s:fielderror>         <br />                  <s:submit name="提  交" />     </s:form>          <hr />     动态方法调用方法二:    miscellaneous!myexecute     <s:form action="miscellaneous!myexecute" namespace="/mystruts">         <s:token name="mytoken"/>         <s:hidden name="name" value="test" />         <s:hidden name="password" value="test" />         <s:submit name="提交执行myexecute() " />     </s:form>   </body> </html>

/StrutsHelloWorld/WebRoot/miscellaneous/output.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html>   <head>     <title>Output</title>   </head>   <body>       提交结果:<br/>     用户名:<s:property value="name"/> <br />     密码:<s:property value="password"/> <br />     <hr />     ${request.info}     ${cookie.mycookie.value }   </body> </html>

/StrutsHelloWorld/src/wintys/struts2/miscellaneous/MiscellaneousModelDrivenAction.java:

package wintys.struts2.miscellaneous; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.apache.struts2.interceptor.ServletRequestAware; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; /**  * Struts2深入探索  * @author Winty (wintys@gmail.com)  * @version 2009-8-26  * @see http://wintys.blogjava.net  */ @SuppressWarnings("serial") public class MiscellaneousModelDrivenAction extends ActionSupport implements         ModelDriven<User> , ServletRequestAware {          private User user = new User();     private HttpServletRequest request;          @Override     public User getModel() {         return user;     }          @Override     public String execute() throws Exception {         System.out.println("this is model driven action");                  if(user.getName().equals("admin")){             throw new NameInvalidException("name 'admin' is invalid");         }                  //ActionContext.put相当于HttpServletRequest.setAttribute()         ActionContext context = ActionContext.getContext();         context.put("info", "this is ActionContext value");                  //ServletActionContext.getResponse得到Response对象         Cookie cookie = new Cookie("mycookie" , "10000");         HttpServletResponse response = ServletActionContext.getResponse();         response.addCookie(cookie);                  //实现ServletRequestAware接口,Struts自动注入的request         Cookie[] cookies = this.request.getCookies();         for(Cookie ck : cookies){             System.out.print("cookie:" + ck.getName());             System.out.println(" = " + ck.getValue());         }         return SUCCESS;     }          public String myexecute()throws Exception{         System.out.println("myexecute()");                  return SUCCESS;     }          @Override     public void validate() {         if(user.getName() == null || user.getName().equals("")){             this.addFieldError("name", "invalid name");         }     }     @Override     public void setServletRequest(HttpServletRequest request) {         this.request = request;     } }

/src/struts.xml:

<?xml version="1.0" 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="MyStruts" extends="struts-default" namespace="/mystruts">         <!-- Struts2深入探索 -->         <action name="miscellaneous" class="wintys.struts2.miscellaneous.MiscellaneousModelDrivenAction">             <result name="success">/miscellaneous/output.jsp</result>             <result name="input">/miscellaneous/input.jsp</result>             <exception-mapping  exception="wintys.struts2.miscellaneous.NameInvalidException" result="nameInvalid" />             <result name="nameInvalid">/miscellaneous/nameInvalidException.jsp</result>             <result name="invalid.token" >/miscellaneous/input.jsp</result>             <interceptor-ref name="token" />             <interceptor-ref name="defaultStack" />         </action>     </package> </struts>

[参考资料]:     [1]《浪曦视频之Struts2应用开发系列》     [2] No configuration found for the specified action : http://javasunnyboy.iteye.com/blog/254753 [附件]:     源代码 : struts_miscellaneous.zip

相关资源:Java 面经手册·小傅哥(公众号:bugstack虫洞栈).pdf
转载请注明原文地址: https://www.6miu.com/read-4936729.html

最新回复(0)