Struts2注解详解
使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了。
要使用注解方式,我们必须添加一个额外包:struts2-convention-plugin-2.x.x.jar。
虽说是零配置的,但struts.xml还是少不了的,配置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
".1.7.dtd">
<struts>
<!-- 请求参数的编码方式-->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开-->
<constant name="struts.action.extension" value="action,do,htm"/>
<!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开 -->
<constant name="struts.configuration.xml.reload" value="true"/>
<!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开 -->
<constant name="struts.devMode" value="false"/>
<!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭 -->
<constant name="struts.serve.static.browserCache" value="false" />
<!-- 指定由spring负责action对象的创建-->
<constant name="struts.objectFactory" value="spring" />
<!-- 是否开启动态方法调用-->
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
</struts>
action类的注解:
package com.tjcyjd.web.action;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ExceptionMapping;
import org.apache.struts2.convention.annotation.ExceptionMappings;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import com.opensymphony.xwork2.ActionSupport;
/**
* Struts2基于注解的Action配置
*
*/
@ParentPackage("struts-default")
@Namespace("/annotation_test")
@Results( { @Result(name = "success", location = "/main.jsp"),
@Result(name = "error", location = "/error.jsp") })
@ExceptionMappings( { @ExceptionMapping(exception = "java.lange.RuntimeException", result = "error") })
public class LoginAction extends ActionSupport {
private static final long serialVersionUID = 2730268055700929183L;
private String loginName;
private String password;
@Action("login") //或者写成 @Action(value = "login")
public String login() throws Exception {
if ("yjd".equals(loginName) && "yjd".equals(password)) {
return SUCCESS;
} else {
return ERROR;
}
}
@Action(value = "add", results = { @Result(name = "success", location = "/index.jsp") })
public String add() throws Exception {
return SUCCESS;
} <br>
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password= password;
}
}
最后在web.xml中配置一下
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.ssh</param-value> <!-- 填写action所在包完整包名 -->
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
总结常用的注解如下:
Namespace:指定命名空间
ParentPackage:指定父包
Result:提供了Action结果的映射(一个结果的映射)
Results:“Result”注解列表
ResultPath:指定结果页面的基路径
Action:指定Action的访问URL
Actions:“Action”注解列表
ExceptionMapping:指定异常映射(映射一个声明异常)
ExceptionMappings:一级声明异常的数组
InterceptorRef:拦截器引用
InterceptorRefs:拦截器引用组
重点解析:
@ParentPackage,这个注解对应了xml文件中的package节点,它只有一个属性叫value,其实就是package的name属性;
@Namespace,命名空间,也就是xml文件中<package>的
namespace
属性;
@Action,这个注解对应<action>节点。这个注解可以应用于action类上,也可以应用于方法上。这个注解中有几个属性:
value(),表示action的URL,也就是<action>节点中的name属性;
results(),表示action的多个result;这个属性是一个数组属性,因此可以定义多个Result;
interceptorRefs(),表示action的多个拦截器。这个属性也是一个数组属性,因此可以定义多个拦截器;
params
(),这是一个String类型的数组,它按照name/value的形式组织,是传给action的参数;
exceptionMappings(),这是异常属性,它是一个ExceptionMapping的数组属性,表示action的异常,在使用时必须引用相应的拦截器;
@Result,这个注解对应了<result>节点。这个注解只能应用于action类上。这个注解中也有几个属性:
name(),表示action方法的返回值,也就是<result>节点的name属性,默认情况下是【success】;
location(),表示view层文件的位置,可以是相对路径,也可以是绝对路径;
type(),是action的类型,比如redirect;
params
(),是一个String数组。也是以name/value形式传送给result的参数;
使用struts2注解需要注意的几个问题:
1.在使用struts2注解的时候如何跳转从一个action跳转到另一个action
@Result(name = "insertProfessionalCourse", params={"actionName","cultivateTeachtask","namespace","/cultivate","method","beforeInsertProfessionalCourse"}, type = "chain")
2.如果没有配置@Namespace注解,那么他是如何映射的呢
以前在用struts2的注解配置时总是要在web.xml中配置一个初始化参数(actionPackages),最近发现不灵了,仔细研究了下发现即使不用在web.xml中配置也能成功,但时灵时不灵的,很是纠结。原来在新版本中的注解配置是要依赖一个struts2-convention-plugin-2.1.8.1.jar的包,而这个包会默认依次检索包名里含有struts,struts2,action,actions的包,然后它会对实现了Action接口以及类名以Action结尾的这些类,作为Action来进行处理。
映射规则对于以Action结尾的的类,去掉Action,取剩下的部分,将所有的字母转换为小写,如果有驼峰式的写法,则用"-"连接符来连接不同的单词,这是此插件的默认方式。最终转换之后的就是请求地址。
例:
com.han.action.OrderAction
这个类按照上面的规则,那么它的请求地址就应该是去年后面的Action,前面的Order全部转换成小写,那么最后的请求地址就是 /order.action
默认命名空间
我们平时一般还有命名空间的问题,在这里面是如果你的包名里面在struts,sturts2,action,action2的后面还有其它的话,那么后面的部分就默认为命名空间
例:
com.han.action.other.OrderAction
按上面所说的那么这个最终的请求地址就为:/other/order.action 默认的命名空间为: other
类名使用驼峰命名法的解析规则
它的默认解析规则为用"-"连接符来连接不同的单词
例:
com.han.action.UserOrderAction
这个请求地址就为:/user-order.action
例:
com.han.struts.action.OrderAction 请求地址为: /action/order.action
com.han.action.struts.OrderAction 请求地址为: /order.action
自定义关键字
那么如果我们不想按照它默认的这几种关键字来检索呢?有办法,那就是通过struts.xml的常量配置来修改它检索的关键字:
<constant name="struts.convention.package.locators" value="han" />
这样就让它默认的检索为包名里是否含有han来判定action了