Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。
Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开。
Struts2框架提供的功能支持:
MVC全名是Model View Controller,即是是模型-视图-控制器,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
MVC 分层有助于管理复杂的应用程序,可以在一个时间内专门关注一个方面。可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。
先了解一下,整个struts2执行的过程。
1、用户发送请求到服务器
2、FilterDispatcher 查看请求,会将请求转发给ActionMapper,ActionMapper负责识别当前的请求是否需要Struts2做出处理。
3、如果ActionMapper需要处理该请求,FilterDispatcher把请求的处理交给ActionProxy
4、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类
5、ActionProxy创建一个ActionInvocation实例,Action完整的调用过程都是由ActionInvocation对象负责
6、同样,配置的拦截器做任何后期处理,如果需要的话
7、然后execute方法返回结果(Result),将结果返回给用户
相关jar包可以在maven公库中找到。
我这次使用的是以下 的版本:
引入jar包后,我们可以看到以下几个核心jar包:
1、 struts2-core-2.1.8.1.jar Struts 2框架的核心类库
2、xwork-core-2.1.6.jar XWork类库,Struts 2在其上构建
3、ognl-2.7.3.jar (Object Graph Navigation Language), 通过其读写对象的属性
4、freemarker-2.3.15.jar : Struts 2的UI标签的模板使用FreeMarker编写
5、commons-logging-1.1.x.jar ASF出品的日志包,Struts 2框架使用这个日志
6、commons-fileupload-1.2.1.jar 文件上传组件,2.1.6版本后需要加入此文件
7、commons-io-1.3.2.jar 上传文件依赖的jar包
web.xml配置文件是一个J2EE的配置文件,决定如何处理元素的HTTP请求由servlet容器。这个文件为任何Web应用程序提供了一个切入点。 Struts2 应用程序的入口点,将是一个部署描述符(web.xml)中定义的过滤器。因此,我们将定义在web.xml中的FilterDispatcher是类的项。需要创建的文件夹的WebContent/ WEB-INF下web.xml文件。
在struts2中,struts框架是通过拦截器来启动的。
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<filter>
<filter-name>struts2Filterfilter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilterfilter-class>
filter>
<filter-mapping>
<filter-name>struts2Filterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
拦截器和过滤器的区别
1、拦截器是基于Java的反射机制的,而过滤器是基于函数回调
2、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
3、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
4、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
<struts>
<package name="action" extends="struts-default">
<action name="userAction" class="org.struts2.action.UserAction">
<result name="success" type="dispatcher">/success.jspresult>
action>
package>
struts>
Action动作是Struts2框架的核心。浏览器提交的请求将被映射到一个特定的动作,它提供了对请求处理逻辑。
Action类可以自己编写,一般需要编写execute方法,因为struts默认调用该方法。
package org.struts2.action;
public class UserAction{
//execute会被struts2调用处理请求
//返回succes就是对应我们之前在 struts.xml文件配置的 元素,将会转发到success.jsp页面
public String execute(){
System.out.println("成功处理请求..");
return "success";
}
}
Action接口中,定义了execute方法,预定义的一系列的字符串常量,用于返回一些预定的result。
//字符串常量:
SUCCESS="success"
NONE="none"
ERROR="error"
INPUT="input"
LOGIN="login"
package org.struts2.action;
import com.opensymphony.xwork2.Action;
public class UserAction inplements Action{
@Override
public String execute() throws Exception{
System.out.println("成功处理请求..");
return SUCCESS;
}
}
ActionSupport类本身实现了Action接口。还实现了其他几个接口,提供更多的功能。
package org.struts2.action;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
@Override
public String execute() throws Exception {
System.out.println("成功处理请求..");
return SUCCESS;
}
}
我们可以运行一下,直接请求 userAction ,则就会直接转发到 succes.jsp页面。
可以看到后天输出:
struts2提供了更加方便的方式来获取,浏览器提交的参数。会通过反射机制,自动向 Action 类 与提交参数同名的 成员变量 注入值。
页面表单提交参数:
<form action="userAction1">
<input type="text" name="userName"/>
<input type="password" name="password"/>
<input type="submit" value="登陆"/>
form>
Action类:
public class UserAction extends ActionSupport{
//struts2会自动帮我们将提交参数注入到同名的 Action类的成员变量中
//①在Action定义公共属性,属性名与参数名一致
public String userName;
//②在Action中定义私有属性,属性名与参数名一致。并提供setter方法。(推荐使用)
private String password;
public void setPassword(String password){
this.password = password;
}
@Override
public String execute() throws Exception {
System.out.println("用户名:"+userName+",密码:"+password);
return null;
}
}
页面表单提交参数:
<form action="userAction1">
<input type="text" name="user.userName"/>
<input type="password" name="user.password"/>
<input type="submit" value="登陆"/>
form>
Action类:
public class UserAction extends ActionSupport{
//struts2会自动帮我们将提交参数注入到同名的 Action类的成员变量中
private User user;
public void setPassword(User user){
this.user = user;
}
@Override
public String execute() throws Exception {
System.out.println("用户名:"+user.userName+",密码:"+user.password);
return null;
}
}
自定义类:
public class User {
private int userName;
private String password;
public User() {};
public int getUserName() {return userName;}
public void setUserName(int userName) {this.userName = userName;}
public String getPassword() {return password;}
public void setPassword(String password) {this.password = password;}
}
(1)List集合
页面表单提交参数:
<form action="userAction" method="post">
<input type="text" name="users[0].userName"/>
<input type="text" name="users[1].userName"/>
<input type="submit" value="确定"/>
form>
Action类:
public class UserAction extends ActionSupport{
//struts2会自动帮我们将提交参数注入到同名的 Action类的成员变量中
private List users;
public void setPassword(User users){
this.users = users;
}
@Override
public String execute() throws Exception {
System.out.println(users.size());
if(users.get(0)!=null) {
System.out.println("用户1:"+users.get(0).getUserName()+",用户2:"+users.get(1).getUserName());
}
return null;
}
}
(2)Map集合
页面表单提交参数:
<form action="userAction" method="post">
<input type="text" name="users.user1.userName"/>
<input type="text" name="users.user2.userName"/>
<input type="submit" value="确定"/>
form>
Action类:
public class UserAction extends ActionSupport{
private Map users;
public Map getUsers() {
return users;
}
public void setUsers(Map users) {
this.users = users;
}
@Override
public String execute() throws Exception {
System.out.println("用户1:"+users.get("user1").getUserName());
return null;
}
}
PS : 出现异常:
No result defined for action org.struts2.action.UserAction and result input
原因:
这个input结果是Struts2定义的当验证参数出错时产生的默认结果。这说明你传递给Action的参数值与Action中的属性可能存在不匹配。
解决方法:
1、仔细检查参数名称与Action中的属性名称是否相等
2、仔细检查参数值的类型与Action中的属性类型是否匹配
Struts2为Action中的属性提供了依赖注入功能,在struts2的配置文件中,我们可以很方便地为Action中的属性注入
值。
注意:属性必须提供setter方法。
配置文件中,在action元素中添加 param元素:
<action name="userAction" class="org.stuts2.action.UserAction" method="execute">
<param name="userName">leeparam>
action>
Action类:
public class UserAction extends ActionSupport{
private String userName;
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public String execute() throws Exception {
System.out.println(userName);
return null;
}
}
PS:以上在Action获取的提交参数,只要在Action中提供getter方法。在同一请求链上的JSP页面,可以同过EL表达式获取这些提交参数。
即是,通过setter方法自动封装用户提交的参数,通过getter方法可以直接在jsp页面用EL表达式获取参数(放到请求域中)
这种方法与servletAPI有耦合,不推荐使用。
public class UserAction1 extends ActionSupport {
@Override
public String execute() throws Exception {
HttpServletRequest res = ServletActionContext.getRequest();
HttpServletResponse resp = ServletActionContext.getResponse();
ServletContext context = ServletActionContext.getServletContext();
return null;
}
}
此种方式实现了Action 跟servletAPI的解耦,推荐使用此种方式。
public class UserAction1 extends ActionSupport {
@Override
public String execute() throws Exception {
//ActionContext是Struts封装的一个类,方便对数据的操作
ActionContext ctx = ActionContext.getContext();
//拿到Map,是struts对HttpServletRequest封装的对象(是一个 Map)
Map request1 = (Map) ctx.get("request");
//得到代表request的map对象
Map request = ctx.getContextMap();
//得到代表session的Map对象
Map session = ctx.getSession();
//得到代表servletContext的对象
Map application = ctx.getApplication();
//获取请求参数
HttpParameters params = ctx.getParameters();
return null;
}
}
实现了aware相关接口的action,struts在运行的时候,会分别把代表request、response、servletcontext的map对象注入进来。
如果业务方法很多,为了避免在每个业务方法获取范围对象,推荐使用此种方式。实际开发中,可以定义BaseAction实现此接口,其他Action全部继承BaseAction即可。
public class UserAction1 extends ActionSupport
implements ServletContextAware,ServletRequestAware,ServletResponseAware
{
@Override
public String execute() throws Exception {
return null;
}
private Map res;
private Map resp;
private Map context;
@Override
public void setServletResponse(HttpServletResponse resp) {
this.resp = (Map) resp;
}
@Override
public void setServletRequest(HttpServletRequest res) {
this.res = (Map) res;
}
@Override
public void setServletContext(ServletContext context) {
this.context = (Map) context;
}
}
Struts2默认访问 Action的execute方法。我们可以通过配置来实现访问Action的其他方法。
<action name="userActionLogin" class="org.struts2.action.UserAction" method="login">action>
<action name="userActionRegister" class="org.struts2.action.UserAction" method="register">action>
<action name="userAciton_*" class="org.struts2.action.UserAction2" method="{1}">
<allowed-methods>login,registerallowed-methods>
action>
每个动作方法都返回一个String类型的值,Struts会根据这个值,来决定应该执行什么结果。
例如,如果某个动作可能会返回了SUCCESS和ERROR,则它的动作声明必须包含两个result元素。
public class UserAction extends ActionSupport{
private String flag;
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
@Override
public String execute() throws Exception {
//这个Action类就设置两种返回值的可能
//因此在 action元素中也必须有 两个 result 元素 来对应不同的返回值。
if(flag=="true") {
return SUCCESS;
}else {
return ERROR;
}
}
}
<action name=“userAction" class=“org.struts2.action.UserAction“>
<result name=“success”>/success.jspresult>
<result name=“error”>/error.jspresult>
action>
1、结果名name
结果的名字,必须与动作返回的结果值匹配
可选,不写默认是success。
2、结果类型(result Type)
结果类型,不写默认是dispatcher。Struts支持的结果类型:
也可以配置全局的results
<package name="action" extends="struts-default" >
<global-results>
<result name="error">/error.jspresult>
<result name="notLogin">/login.jspresult>
global-results>
<action name="userAction" class="org.struts2.action.UserAction" >action>
package>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter是Struts2中的核心控制器,该Filter主要的任务是拦截用户/*的所有请求。如果请求的路径中带后缀为.action或没有带后缀,此时将请求交给Struts2框架处理。否则不做任何处理。例如:请求路径为/index.jsp直接访问页面
1、struts-default.xml
2、strtus-plugin.xml
3、struts.xml
4、struts.properties (用户自定义配置文件)
struts-default.xml文件是struts2框架默认加载的配置文件。它定义struts2一些核心的bean和拦截器。
<constant name="struts.i18n.encoding" value="UTF-8"/>
<constant name="struts.action.extension" value="do"/>
<constant name="struts.serve.static.browserCache" value="false"/>
<constant name="struts.configuration.xml.reload" value="true"/>
<constant name="struts.devMode" value="true" />
<constant name="struts.ui.theme" value="simple" />
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<constant name="struts.multipart.maxSize" value=“10701096"/>
struts.xml配置文件的元素介绍
拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。拦截器的概念是Servlet过滤器或JDK代理类一样的。拦截器允许横切功能分开实现的动作,以及框架。使用拦截器,可以实现如下
Struts2框架提供的许多功能都使用拦截实现的例子包括异常处理,文件上传,生命周期回调和验证等事实上作为Struts2的基础,其功能拦截,这可能有7或8拦截器分配给每个动作。
Struts 2已经为您提供丰富多样的,功能齐全的拦截器实现。大家可以至struts2的jar包内的struts-default.xml查看关于默认的拦截器与拦截器链的配置。
拦截器 | 名字 | 说明 |
---|---|---|
Alias Interceptor | alias | 在不同请求之间将请求参数在不同名字件转换,请求内容不变。 |
Chaining Interceptor | chain | 让前一个Action的属性可以被后一个Action访问,现在和chain类型的result()结合使用。 |
Checkbox Interceptor | checkbox | 添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。 |
Cookies Interceptor | cookies | 使用配置的name,value来是指cookies |
Conversion Error Interceptor | conversionError | 将错误从ActionContext中添加到Action的属性字段中。 |
Create Session Interceptor | createSession | 自动的创建HttpSession,用来为需要使用到HttpSession的拦截器服务。 |
Debugging Interceptor | debugging | 提供不同的调试用的页面来展现内部的数据状况。 |
Execute and Wait Interceptor | execAndWait | 在后台执行Action,同时将用户带到一个中间的等待页面。 |
Exception Interceptor | exception | 将异常定位到一个画面 |
File Upload Interceptor | fileUpload | 提供文件上传功能 |
I18n Interceptor | i18n | 记录用户选择的locale |
Logger Interceptor | logger | 输出Action的名字 |
Message Store Interceptor | store | 存储或者访问实现ValidationAware接口的Action类出现的消息,错误,字段错误等。 |
Model Driven Interceptor | model-driven | 如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。 |
Scoped Model Driven | scoped-model-driven | 如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model调用Action的setModel方法将其放入Action内部。 |
Parameters Interceptor | params | 将请求中的参数设置到Action中去。 |
Prepare Interceptor | prepare | 如果Acton实现了Preparable,则该拦截器调用Action类的prepare方法。 |
Scope Interceptor | scope | 将Action状态存入session和application的简单方法。 |
Servlet Config Interceptor | servletConfig | 提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。 |
Static Parameters Interceptor | staticParams | 从struts.xml文件中将中的中的内容设置到对应的Action中。 |
Roles Interceptor | roles | 确定用户是否具有JAAS指定的Role,否则不予执行。 |
Timer Interceptor | timer | 输出Action执行的时间 |
Token Interceptor | token | 通过Token来避免双击 |
Token Session Interceptor | tokenSession | 和Token Interceptor一样,不过双击的时候把请求的数据存储在Session中 |
Validation Interceptor | validation | 使用action-validation.xml文件中定义的内容校验提交的数据。 |
Workflow Interceptor | workflow | 调用Action的validate方法,一旦有错误返回,重新定位到INPUT画面 |
Parameter Filter Interceptor | N/A | 从参数列表中删除不必要的参数 |
Profiling Interceptor | profiling | 通过参数激活profile |
现在,我们尝试自定义一个 验证登陆的拦截器。
自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口,实现该接口需要实现,init()初始化拦截器,destroy() 销毁拦截器,intercept()处理拦截 方法。
package org.struts2.intercepter;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class LoginIntercepter implements Interceptor{
@Override
public void destroy() {
System.out.println("销毁拦截器");
}
@Override
public void init() {
System.out.println("初始化拦截器");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("进入拦截器..");
//可以通过下面的三个方法,可以获得相应的session域对象。用来进行登陆验证
//(其他的域对象也可以获得)
//ActionContext.getContext().getSession().get("user");
//invocation.getInvocationContext().getContext().get("session");
//ServletActionContext.getRequest().getSession()
//当完成验证时,需要调用 ActionInvocation 对象的 invoke()方法来 放行。
//其原理和过滤器一样
invocation.invoke();
//同样的,当执行完 被拦截Action后,会继续执行 intercept方法下 invocation.invoke();之后的代码
System.out.println("完成拦截器的调用");
return null;
}
}
实际行动将使用拦截器执行invocation.invoke()调用。所以,可以做一些前处理和一些处理后,根据需要。
<package name="package1" extends="struts-default">
<interceptors>
<interceptor name="loginInterceptor" class="org.struts2.intercepter.LoginIntercepter" />
<interceptor-stack name="myStack">
<interceptor-ref name="loginInterceptor" />
<interceptor-ref name="defaultStack" />
interceptor-stack>
interceptors>
<action name="loginAction" class="org.struts2.action.LoginAction" >
<interceptor-ref name="myStack"/>
action>
package>
Struts提供了一个更简单的方式来处理未捕获的异常,并将用户重定向到一个专门的错误页面。可以轻松地配置到不同的异常转向不同的错误页面。“exception”拦截器作为默认的栈的一部分,所以不必做任何额外的配置。
但这种支持不太灵活,建议还是自定义的统一异常处理拦截器,可以有更多功能的实现。
实现struts2提供的统一异常处理,只需要在配置文件配置即可。
<struts>
<package name="package1" extends="struts-default">
<global-exception-mapping>
<exception-mapping result="notFind" exception="ClassNotFoundException">exception-mapping>
global-exception-mapping>
<global-results>
<result name="notFind">/error.jspresult>
global-results>
<action name="loginAction" class="org.struts2.action.LoginAction" >
<exception-mapping result="mathException" exception="java.lang.ArithmeticExcption"/>
<result name="mathException">/mathError.jspresult>
action>
package>
struts>
struts2提供的功能支持主要有:
请求数据自动封装,我们已经在上面学习过了。现在主要讲解
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
(1)引入Gson的jar包
在maven公库中可以找到。Gson
(2)使用GSON
public class UserAction3 extends ActionSupport {
//自定义的json
public String execute() throws IOException {
List list = new ArrayList<>();
list.add("LEE");
list.add("WANG");
list.add("YANG");
//使用Json
Gson gson = new Gson();
String gsonStr = gson.toJson(list);
ServletActionContext.getResponse().getWriter().write(gsonStr);
return null;
}
}
struts.xml配置:
<package name="action1" extends="struts-default">
<action name="userAction3" class="org.struts2.action.UserAction3" >
action>
package>
实现步骤:
①导入jar包 struts2-json-plugin和 json-lib
②package的extends属性需要设置为”json-default”,
Result的type需要指定是json类型 ,
result的root属性文本 指定 Action中需要转换成json数据格式的 成员变量
<package name="action1" extends="json-default">
<action name="userAction3" class="org.struts2.action.UserAction3" >
<result name="success" type="json" >
<param name="root">userparam>
result>
action>
package>
表单的属性enctype要为 “multipart/form-data”,提交方式method 为 post。
<form method="post" action="upload" enctype="multipart/form-data" >
<input type="file" name="up" />
<input type="submit"/>
form>
package org.struts2.action;
import java.io.File;
import com.opensymphony.xwork2.ActionSupport;
public class FileUploadAction extends ActionSupport{
//都要提供setter方法
private File up;
//只要 属性名+FileName就能获得 上传文件的名字
private String upFileName;
//只要 属性名+ContentType就能获得 上传文件的类型
private String upContentType;
public void upload() {
System.out.println(up.length());
System.out.println(upFileName);
System.out.println(upContentType);
}
public File getUp() {return up;}
public void setUp(File up) {this.up = up;}
public String getUpFileName() {return upFileName;}
public void setUpFileName(String upFileName) {this.upFileName = upFileName;}
public String getUpContentType() {return upContentType;}
public void setUpContentType(String upContentType) {this.upContentType = upContentType;}
}
<action name="upload" class="org.struts2.action.FileUploadAction" method="upload">
action>
PS:遇到异常 java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
很明显地是没有找到相应的类,但是实际上该类存在的话。就可能是部署的问题,找到 web deployment assembly ,将相应的 存放jar包的lib部署上去。后面发现,在maven update时,有可能导致整个工程的 java buil path \ projact facts \deployment assembly 下的配置出现改变,要注意。
package org.struts2.action;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class DownloadAction {
//都必须提供 getter方法
//提供一个输出流,向浏览器输出文件
private FileInputStream input;
//定义文件名称,需要在响应头设置contentDisposition
private String fileName;
public FileInputStream getInput() {
return input;
}
public void setInput(FileInputStream input) {
this.input = input;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String download() throws FileNotFoundException {
//添加一个 文件输出流
input = new FileInputStream("C:\\Users\\lenovopc\\Desktop\\1.PNG");
//文件名称
fileName = "1.PNG";
//成功处理请求
return "success";
}
}
<struts>
<package name="action1" extends="struts-default">
<action name="donwload" class="org.struts2.action.DownloadAction" method="download">
<result name="success" type="stream">
<param name="contentType">image/pngparam>
<param name="inputName">inputparam>
<param name="contentDisposition">attachment;filename="${fileName}"param>
result>
action>
package>
struts>
使用Struts 注解,我们可以实现零配置。
Struts2注解是由Struts 2的约定插件的支持,所以需要引入jar包。
在Action类类名上配置,用于Action类的命名空间,只有value属性,用来指明包的命名空间。
@Namespace("/package1")
public class UserAction extends ActionSupport{
//...
}
用来为Action类指定父包,只有value属性,用来指定父包的名字。零配置的时候,所有的Action都是单独放置的,暂时没有包的概念。所以需要在每个Action类上指定自己的父包,如果不指定的话默认为struts-default。
@ParentPackage ("struts-default")
public class UserAction extends ActionSupport{
//...
}
@Action 可以为Action类指定引用名,即是指定URL中的映射名称,同时可以包含其他注解。
@Action 注解有以下属性:
@ParentPackage("struts-default")
@Namespace("/package")
@Action(value="action1",results= { //指定结果
@Result(name="success",location="/success.jsp"),
@Result(name="error",location="/error.jsp")
},interceptorRefs= { //指定拦截器
@InterceptorRef("defaultStack")
},exceptionMappings= { //声明错误处理
@ExceptionMapping(exception="java.lang.Exception",result="error")
})
public class UserAction extends ActionSupport{
//...
}
@Result 注解用于声明一个结果。有以下属性:
@ParentPackage("struts-default")
@Namespace("/package")
@Action(value="action1",results= {
@Result(name="success",type="stream",
params= {
"contentType","image/png","inputName","input","contentDisposition","attachment;filename=${fileName}"
}
)
}
)
public class UserAction extends ActionSupport{
private FileInputStream input;
private String fileName;
public FileInputStream getInput() {
return input;
}
public void setInput(FileInputStream input) {
this.input = input;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String execute() throws FileNotFoundException {
input = new FileInputStream("C:\\Users\\lenovopc\\Desktop\\1.PNG");
fileName="1.PNG";
return SUCCESS;
}
}
@Results 注解用来声明多个结果,它只有一个value属性,这个value属性又需要一个@Result 数组。
java注解规定在同一个语法单元上,同一种注解只能使用一个,因此,如果一个Action、可能有多个后继页面的时候,决不能再用一个Action类上使用U盾讴歌@Result 而是应该是使用@Results 包含多个@Result 。
@ParentPackage("struts-default")
@Namespace("/package")
@Action("action2")
@Results({
@Result(name="success",location="/success.jsp"), @Result(name="error",location="/error.jsp")
}
)
public class UserAction1 extends ActionSupport{
//..
}
@InterceptorRefs 注解用来声明多个拦截器引用,它只有一个value属性,而这个value属性有需要一个@ InterceptorRef 数组。
@ParentPackage("struts-default")
@Namespace("/package")
@Action("action2")
@InterceptorRefs({
@InterceptorRef("defaultStack")
})
public class UserAction1 extends ActionSupport{
//...
}
@ExceptionMapping 注解用来为这个Action声明错误处理,有以下属性:
@ParentPackage("struts-default")
@Namespace("/package")
@Action("action2")
@Results({
@Result(name="success",location="/success.jsp"),
@Result(name="error",location="error.jsp")
})
@InterceptorRefs({
@InterceptorRef("defaultStack")
})
@ExceptionMappings({
@ExceptionMapping(exception="java.lang.Exception",result="error")
})
public class UserAction1 extends ActionSupport{
//...
}
除了action元素,struts.xml配置文件中还有很多东西,比如全局结果
声明一个全局拦截器
等。到现在为止,注解还做不到。
因此,注解并不能完全地代替struts.xml,而是代替了其中Action部分的配置信息。一般是,注解和配置文件共存。