完整版见https://jadyer.github.io/
这是一个Struts2.0.11应用,相关用法参见代码的注释部分
首先是web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> <init-param> <!-- 这里actionPackage是固定格式。然后再指定使用注解的Action所在的包 --> <param-name>actionPackages</param-name> <param-value>com.jadyer.action</param-value> </init-param> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>annotationTest.jsp</welcome-file> </welcome-file-list> </web-app>
然后是输入用户名和密码的添加用户页面annotationTest.jsp
<%@ page language="java" pageEncoding="UTF-8"%> <h2>使用Struts2的注解配置Action</h2> <h3><font color="red">提示:</font>程序设定的用户名和密码分别为<font color="blue"><strong>admin</strong></font>和<font color="blue"><strong>jadyer</strong></font></h3> <h3><font color="red">注意:</font>用户名或密码不正确时将停留在该页面不动</h3> <form action="<%=request.getContextPath()%>/annotation/user.action" method="POST"> 姓名:<input type="text" name="username"><br/> 密码:<input type="text" name="password"><br/> <input type="submit" value="添加用户"> </form>
接着是显示用户添加结果的userSuc.jsp页面
<%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <h2>添加用户<font color="blue"><s:property value="username"/></font>成功</h2>
最后是用到的UserAction.java
package com.jadyer.action; import org.apache.struts2.config.Namespace; import org.apache.struts2.config.Result; import org.apache.struts2.config.Results; import com.opensymphony.xwork2.ActionSupport; /********************【Zero Configuration】*********************************************************************************/ //官方文档中Zero Configuration叫做零配置,翻译到中国叫做注解配置。好处是不用写struts.xml,而将配置信息写在Action中 //Spring中也有两种配置方式,一种是在配置文件里面配,还有一种就是通过注解来配 //所以现在如果强迫自己弄明白了这里的注解的话,将来在学习Spring的时候,就能够变得简单一些 //而且注解这东西,将来用的会越来越广,因为它有很多的好处。Struts2.0.11版本中的注解的功能暂时还不是特别强大 //据官方网站上说:在Struts2.2版出来后,注解的功能会非常非常的强大,完全可以抛离struts.xml来写程序,程序员开发时就更方便了 //每个人都可以配置好自己的程序,不用集中在struts.xml中配置了,但统一性就会有所缺失,万一某人不按套路胡写一通,维护时很麻烦 /********************【浅析Action的四大注解】*********************************************************************************/ //Struts2的所有注解中与Action相关的注解:ParentPackage、Namespace、Result、Results //在org.apache.struts2.config包中有四个它们的同名类,就是四大注解相关的 //这四大注解都是类级别的,也就是说它们需要写在类的前面,接下来一一解释 //【@ParentPackage(value="struts-default")】相当于【<package extends="struts-default"/>】 //而ParentPackage注解的缺省设置就是继承struts-default包,所以它可以不写 //【@Namespace(value="")】相当于【<package namespace=""/>】或者是没有在包中定义命名空间 //而Namespace注解的缺省设置就是位于默认的命名空间中,所以它同样可以不写 //【@Result(name="success",value="/userSuc.jsp")】相当于【<result name="success">/userSuc.jsp</result>】 //而Result注解的name属性缺省设置就是success,但为了便于分析,仍建议显式的指明name属性 //在Action中配置好注解之后,还需要在【web.xml】中声明哪些类使用了注解,代码如下所示 //<filter> // <filter-name>struts2</filter-name> // <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> // <init-param> // <!-- 这里actionPackage是固定格式。然后再指定使用注解的Action所在的包 --> // <param-name>actionPackages</param-name> // <param-value>com.jadyer.action</param-value> // </init-param> //</filter> //此时Action在命名时一定要以Action结尾,注解在解释的时候,会先把名字中后面的Action去掉 //然后取Action名字中前面的字段作为访问的名字,比如说UserAction的调用,例如如下 //访问时访问【<a href="user.action" mce_href="user.action">添加用户</a>】即可,而且user首字母需要小写方能匹配成功 //如果Action的返回结果有多个,测试就需要用到【@Results】注解,具体用法见下方 //注意:当配置result的转发模式的时候,若写成type="redirect"会报告Type mismatch: cannot convert from String to Class的错误 //注意:这是因为在注解中是允许出现继承过来的东西的,所以此时就需要把redirect对应的类写在type值中 //注意:例如type=org.apache.struts2.dispatcher.ServletRedirectResult.class //注意:然后Strtus2就会利用反射机制自动把这个类装载进来。此时不能添加双引号,因为它代表的是完整类,不是字符串 /************************************************************************************************************************/ //@ParentPackage(value="struts-default") //@Namespace(value="") //@Result(value="/userSuc.jsp") //@Result(name="success", value="/userSuc.jsp") @Namespace(value="/annotation") @Results({ @Result(name="success", value="/userSuc.jsp"), @Result(name="input", value="/annotationTest.jsp", type=org.apache.struts2.dispatcher.ServletRedirectResult.class) }) public class UserAction extends ActionSupport { private static final long serialVersionUID = -5137568969521746637L; private String username; private String password; /* 两个属性对应的setter和getter略 */ @Override public String execute() throws Exception { System.out.println("UserAction.execute() is invoked"); if(username.trim().equalsIgnoreCase("admin") && password.equals("jadyer")){ return SUCCESS; }else{ return INPUT; } } } // @Before // public void doBefore(){ // System.out.println("注解配置的方法在execute()执行之前调用了"); // } // // @After // public void doAfter(){ // System.out.println("注解配置的方法在execute()执行之后调用了"); // } // // @BeforeResult // public void doBeforeResult(){ // System.out.println("注解配置的方法在Result返回之前调用了"); // } /********************【浅析Interceptor的三大注解】***************************************************************************/ //在com.opensymphony.xwork2.interceptor.annotations包中定义了可用的配置拦截器的注解 //其中Before和After注解分别是在execute()执行之前和之后调用的,而BeforeResult注解是在结果集返回之前调用的 //Action的四大注解都是类级别的,而Interceptor的注解都是属于方法级别的,也就是说它们都需要写在类里面的方法之前 //想在拦截器里面使用注解的话,就必须配置xwork2.interceptor.annotations包的AnnotationWorkflowInterceptor类 //AnnotationWorkflowInterceptor类是调用这三个注解的前提,必须得把这个类配置在struts.xml中,配置方式如下 //<interceptors> // <interceptor name="annoInterceptor" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor"/> //</interceptors> //然后在需要使用注解配置的拦截器的<action/>中增加<interceptor-ref name="annoInterceptor"/>即可 //注意,这个时候不要忘记再引用一下默认的defaultStack拦截器 //那么当发送这个Action请求的时候,执行的就是:@Before----execute()----@BeforeResult----@After顺序 //这样看来,使用注解来配置拦截器的话,真的是非常非常简单。但是注解也有一个缺点:不能复用 //另外,我们同样也可以通过注解配置拦截器的方式,来实现权限验证。举例如下 //@Before //public String doBefore(){ // if(session.get("user")==null){ // //如果没有session,则表示用户还没有登录,那么返回登录的结果集 // return LOGIN; // }else{ // //若有session,则表示用户已经登录,可以去执行下一步 // //此处返回null,那么程序就会继续执行execute()方法 // return null; // } //}//这样就轻松实现了对用户的访问权限的验证了。所以说使用注解来配置Interceptor,有时候还是很方便的 /************************************************************************************************************************/