[b]一、Struts2概述[/b]
Struts2 是Apache软件基金会(ASF)赞助的一个开源项目,使用Struts2的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。如果我们想混合使用Servlets和JSP的优点来建立可扩展的应用,Struts2是一个不错的选择。
[b]二、Struts2工作原理[/b]
[img]http://dl2.iteye.com/upload/attachment/0094/9553/3185d01f-1763-3b9f-b72d-5266492c524b.jpg[/img]
如图,Struts2工作原理大概分为以下几个步骤:
1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求。
2.这个请求经过一系列的过滤器(Filter)(ActionContextCleanUp,SiteMesh,etc等)。
3.接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求调用那个Action。
4.FilterDispatcher将控制权委派给ActionProxy,ActionProxy通过Configuration Manager读取框架的配置文件,然后创建一个ActionInvocation实例。
5.ActionInvocation调用Action,Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。
[b]三、Struts2相对于Struts1的改进[/b]
[b]1.在Action的实现方面[/b]
Struts1要求必须统一扩展自Action类,而Struts2中可以是一个普通的POJO。
[b]2.线程模型方面[/b]
Struts1的Action是单实例的,一个Action的实例处理所有的请求。Struts2的Action是一个请求对应一个实例(每次请求时都新new出一个对象),没有线程安全方面的问题。
[b]3.Servlet依赖方面[/b]
Struts1的Action依赖于Servlet API,比如Action的execute方法的参数就包括request和response对象。这使程序难于测试。Struts2中的Action不再依赖于Servlet API,有利于测试,并且实现TDD。
[b]4.封装请求参数[/b]
Struts1中强制使用ActionForm对象封装请求的参数。Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。
[b]5.表达式语言方面[/b]
Struts1中整合了EL,但是EL对集合和索引的支持不强,Struts2整合了OGNL(Object Graph NavigationLanguage)。绑定值到视图技术
Struts1使用标准的JSP,Struts2使用“ValueStack”技术。
[b]6.类型转换[/b]
Struts1中的ActionForm基本使用String类型的属性。Struts2中使用OGNL进行转换,可以更方便的使用。Struts1中支持覆盖validate方法或者使用Validator框架。Struts2支持重写validate方法或者使用XWork的验证框架。
[b]7.Action执行控制的对比[/b]
Struts1支持每一个模块对应一个请求处理,但是模块中的所有Action必须共享相同的生命周期。Struts2支持通过拦截器堆栈为每一个Action创建不同的生命周期。
[b]四、Struts2开发示例[/b]
[b]1. Struts2的下载[/b]
官方下载地址:http://struts.apache.org/download.cgi
Struts2完整版结构如下:apps(应用示例),docs(帮助文档,API),lib(核心类库),src(全部源码)
[b]2. 导入struts2核心类库到项目[/b]
基本包包括:antlr-2.7.2.jar,commons-fileupload-1.3.jar,commons-io-2.0.1.jar,commons-logging-1.1.3.jar,commons-lang3-3.1.jar,freemarker-2.3.19.jar,javassist-3.11.0.GA.jar,ognl-3.0.6.jar,struts2-core-2.3.15.3.jar,
xwork-core-2.3.15.3.jar,如需使用Struts2的更多特性,则需导入其它jar包
[b]3. 在web.xml中配置Struts2的核心Filter[/b]
<!-- 定义Struts2的核心Filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- 让Struts2的核心Filter拦截所有请求 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[b]4. 创建登陆页面login.jsp,测试Struts2[/b]
<script type="text/javascript">
function regist(){
//获取页面的第一个表单
targetForm = document.forms[0];
//动态修改表单的action属性
targetForm.action = "regist";
}
</script>
<body bgcolor="pink">
<center>
用户登陆<br><hr>
<form action="login">
账 号:<input type="text" name="username"><br>
密 码:<input type="text" name="password"><br>
<input type="submit" value="登陆">
<input type="submit" value="注册" οnclick="regist();">
</form>
</center>
</body>
[b]5. 为Struts2添加配置文件struts.xml[/b]
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<!-- 指定Struts 2配置文件的根元素 -->
<struts>
<!-- 指定全局国际化资源文件 -->
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 指定国际化编码所使用的字符集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<!-- 所有的Action定义都应该放在package下 -->
<package name="userManager" extends="struts-default">
<!-- 不配置method属性,交给默认的execute()方法处理 -->
<action name="login" class="test.action.LoginAction">
<!-- 定义三个逻辑视图和物理资源之间的映射 -->
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
<!-- 配置method属性,交给regist()方法处理 -->
<action name="regist" class="test.action.LoginAction" method="regist">
<result name="success">/welcome.jsp</result>
</action>
</package>
<!-- 导入其它完整的配置文件 -->
<include file="struts-xxx.xml"></include>
</struts>
[b]6. 编写Action处理类BaseAction.java,LoginAction.java[/b]
/// 1.BaseAction
/ 2. LoginAction
[b]7. 其它跳转页面welcome.jsp[/b]
<body>
登陆成功!<%=request.getAttribute("username")%><br>
<a href="login.jsp">退出</a><hr>
</body>
[b]五、Struts2的文件上传和下载[/b]
[b]Struts2的文件上传:[/b]
[b]1. 测试文件上传页面upload.jsp[/b]
此处使用Struts2标签来生成上传文件的表单,为了让浏览器采用二进制数据的方式把数据发送到服务器,我们必须把表单的method设置为POST,将enctype设置为multipart/form-data。jsp代码如下:
<body>
<s:form action="uploadPro" method="post" enctype="multipart/form-data">
<s:file name="upload" label="选择文件"/><br />
<s:submit value="上传"/>
</s:form>
</body>
[b]2. 实现文件上传的Action(UploadAction.java)[/b]
Action实现类其实非常简单,只需要定义三个属性接收文件参数即可,一是类型为File的xxx封装文件内容,二是String类型的xxxFileName封装文件名,三是String类型的xxxContentType封装文件类型。代码如下:
[b]3. 配置文件上传的Action(struts.xml)[/b]
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 设置该应用使用的解码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置处理文件上传的Action -->
<action name="uploadPro" class="test.UploadAction">
<!-- 配置Struts 2默认的视图页面 -->
<result>/upload.jsp</result>
</action>
</package>
</struts>
4. 实现文件过滤
方法一:直接在Action中判断文件的类型是否为允许类型
方法二:拦截器实现文件过滤,如下:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 设置该应用使用的解码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置处理文件上传的Action -->
<action name="uploadPro" class="org.crazyit.app.action.UploadAction">
<!-- 配置fileUpload的拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 配置允许上传的文件类型 -->
<param name="allowedTypes">image/png,image/gif,image/jpeg</param>
<!-- 配置允许上传的文件大小 -->
<param name="maximumSize">2000</param>
</interceptor-ref>
<!-- 配置系统默认的拦截器 -->
<interceptor-ref name="defaultStack"/>
<!-- 配置Struts 2默认的视图页面 -->
<result>/WEB-INF/content/succ.jsp</result>
</action>
</package>
</struts>
[b]Struts2的文件下载:[/b]
[b]1. 测试文件下载jsp页面[/b]
<body>
<ul><li>下载:<a href="download.action">下载文件</a></li></ul>
</body>
[b]2. 实现文件下载的Action(FileDownloadAction.java)[/b]
[b]3. 配置文件下载的Action(struts.xml)[/b]
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<action name="download" class="test.FileDownloadAction">
<param name="inputPath">\images\aaa.jpg</param>
<!-- 配置结果类型为stream的结果 -->
<result name="success" type="stream">
<!-- 指定下载文件的文件类型 -->
<param name="contentType">image/jpg</param>
<!-- 指定由getTargetFile()方法返回被下载文件的InputStream -->
<param name="inputName">targetFile</param>
<param name="contentDisposition">filename="hap.jpg"</param>
<!-- 指定下载文件的缓冲大小 -->
<param name="bufferSize">4096</param>
</result>
</action>
</package>
</struts>
[b]六、Struts2返回JSON数据示例[/b]
[b]1. 导包[/b]
除导入Struts2基本包以外还要导入struts2-json-plugin-2.3.15.3.jar
[b]2. 实现Action(JSONExample.java)[/b]
[b]3. 配置Action(struts.xml)[/b]
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.i18n.encoding" value="UTF-8"/>
<package name="example" extends="json-default">
<action name="JSONExample" class="test.JSONExample">
<!-- 配置类型的json的Result -->
<result type="json">
<!-- 为该Result指定参数 -->
<param name="noCache">true</param>
<param name="contentType">text/html</param>
<!-- 设置只返回Action的map属性 -->
<!-- param name="root">map</param -->
</result>
</action>
</package>
</struts>
[b]4. 测试返回结果[/b]
浏览器输入: http://localhost:8080/TestStrutsJSON/example/JSONExample(项目路径+Action配置文件包名+Action名)测试得到的JSON数据。
Struts2 是Apache软件基金会(ASF)赞助的一个开源项目,使用Struts2的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。如果我们想混合使用Servlets和JSP的优点来建立可扩展的应用,Struts2是一个不错的选择。
[b]二、Struts2工作原理[/b]
[img]http://dl2.iteye.com/upload/attachment/0094/9553/3185d01f-1763-3b9f-b72d-5266492c524b.jpg[/img]
如图,Struts2工作原理大概分为以下几个步骤:
1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求。
2.这个请求经过一系列的过滤器(Filter)(ActionContextCleanUp,SiteMesh,etc等)。
3.接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求调用那个Action。
4.FilterDispatcher将控制权委派给ActionProxy,ActionProxy通过Configuration Manager读取框架的配置文件,然后创建一个ActionInvocation实例。
5.ActionInvocation调用Action,Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。
[b]三、Struts2相对于Struts1的改进[/b]
[b]1.在Action的实现方面[/b]
Struts1要求必须统一扩展自Action类,而Struts2中可以是一个普通的POJO。
[b]2.线程模型方面[/b]
Struts1的Action是单实例的,一个Action的实例处理所有的请求。Struts2的Action是一个请求对应一个实例(每次请求时都新new出一个对象),没有线程安全方面的问题。
[b]3.Servlet依赖方面[/b]
Struts1的Action依赖于Servlet API,比如Action的execute方法的参数就包括request和response对象。这使程序难于测试。Struts2中的Action不再依赖于Servlet API,有利于测试,并且实现TDD。
[b]4.封装请求参数[/b]
Struts1中强制使用ActionForm对象封装请求的参数。Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。
[b]5.表达式语言方面[/b]
Struts1中整合了EL,但是EL对集合和索引的支持不强,Struts2整合了OGNL(Object Graph NavigationLanguage)。绑定值到视图技术
Struts1使用标准的JSP,Struts2使用“ValueStack”技术。
[b]6.类型转换[/b]
Struts1中的ActionForm基本使用String类型的属性。Struts2中使用OGNL进行转换,可以更方便的使用。Struts1中支持覆盖validate方法或者使用Validator框架。Struts2支持重写validate方法或者使用XWork的验证框架。
[b]7.Action执行控制的对比[/b]
Struts1支持每一个模块对应一个请求处理,但是模块中的所有Action必须共享相同的生命周期。Struts2支持通过拦截器堆栈为每一个Action创建不同的生命周期。
[b]四、Struts2开发示例[/b]
[b]1. Struts2的下载[/b]
官方下载地址:http://struts.apache.org/download.cgi
Struts2完整版结构如下:apps(应用示例),docs(帮助文档,API),lib(核心类库),src(全部源码)
[b]2. 导入struts2核心类库到项目[/b]
基本包包括:antlr-2.7.2.jar,commons-fileupload-1.3.jar,commons-io-2.0.1.jar,commons-logging-1.1.3.jar,commons-lang3-3.1.jar,freemarker-2.3.19.jar,javassist-3.11.0.GA.jar,ognl-3.0.6.jar,struts2-core-2.3.15.3.jar,
xwork-core-2.3.15.3.jar,如需使用Struts2的更多特性,则需导入其它jar包
[b]3. 在web.xml中配置Struts2的核心Filter[/b]
<!-- 定义Struts2的核心Filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- 让Struts2的核心Filter拦截所有请求 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[b]4. 创建登陆页面login.jsp,测试Struts2[/b]
<script type="text/javascript">
function regist(){
//获取页面的第一个表单
targetForm = document.forms[0];
//动态修改表单的action属性
targetForm.action = "regist";
}
</script>
<body bgcolor="pink">
<center>
用户登陆<br><hr>
<form action="login">
账 号:<input type="text" name="username"><br>
密 码:<input type="text" name="password"><br>
<input type="submit" value="登陆">
<input type="submit" value="注册" οnclick="regist();">
</form>
</center>
</body>
[b]5. 为Struts2添加配置文件struts.xml[/b]
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<!-- 指定Struts 2配置文件的根元素 -->
<struts>
<!-- 指定全局国际化资源文件 -->
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 指定国际化编码所使用的字符集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<!-- 所有的Action定义都应该放在package下 -->
<package name="userManager" extends="struts-default">
<!-- 不配置method属性,交给默认的execute()方法处理 -->
<action name="login" class="test.action.LoginAction">
<!-- 定义三个逻辑视图和物理资源之间的映射 -->
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
<!-- 配置method属性,交给regist()方法处理 -->
<action name="regist" class="test.action.LoginAction" method="regist">
<result name="success">/welcome.jsp</result>
</action>
</package>
<!-- 导入其它完整的配置文件 -->
<include file="struts-xxx.xml"></include>
</struts>
[b]6. 编写Action处理类BaseAction.java,LoginAction.java[/b]
/// 1.BaseAction
package test.action;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class BaseAction extends ActionSupport {
private transient HttpServletRequest request = null;
private transient HttpServletResponse response = null;
private transient ServletContext servletContext = null;
private transient HttpSession session = null;
public void setRequest(HttpServletRequest request) {
this.request = request;
}
public void setResponse(HttpServletResponse response) {
this.response = response;
}
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
public void setSession(HttpSession session) {
this.session = session;
}
public HttpServletRequest getRequest(){
if(request != null){
return request;
}
return ServletActionContext.getRequest();
}
public HttpServletResponse getResponse(){
if(response != null){
return response;
}
return ServletActionContext.getResponse();
}
public ServletContext getServletContext(){
if(servletContext != null){
return servletContext;
}
return ServletActionContext.getServletContext();
}
public HttpSession getSession(){
if(session != null){
return session;
}
return getRequest().getSession();
}
}
/ 2. LoginAction
package test.action;
public class LoginAction extends BaseAction{
//定义封装请求参数的username和password属性
private String username;
private String password;
public String getUsername(){
return username;
}
public void setUsername(String username){
this.username = username;
}
public String getPassword(){
return password;
}
public void setPassword(String password){
this.password = password;
}
//注册Action
public String regist() throws Exception {
System.out.println(this.getRequest().getAttribute("username"));
this.getRequest().setAttribute("username", "regist");
return SUCCESS;
}
//默认的登陆Action
public String execute() throws Exception {
// 1. 通过request对象得到表单的值
System.out.println(this.getRequest().getParameter("username"));
// 2. 直接通过getter和setter得到表单的值
if (getUsername().equals("a")&& getPassword().equals("a")){
// 3. 设置、得到session的值
this.getSession().setAttribute("username", "ok");
System.out.println(this.getSession().getAttribute("username"));
// 4. 设置响应的字符串
this.getResponse().setCharacterEncoding("UTF-8");
this.getResponse().getWriter().print("ccccc");
return SUCCESS;
} else {
return ERROR;
}
}
}
[b]7. 其它跳转页面welcome.jsp[/b]
<body>
登陆成功!<%=request.getAttribute("username")%><br>
<a href="login.jsp">退出</a><hr>
</body>
[b]五、Struts2的文件上传和下载[/b]
[b]Struts2的文件上传:[/b]
[b]1. 测试文件上传页面upload.jsp[/b]
此处使用Struts2标签来生成上传文件的表单,为了让浏览器采用二进制数据的方式把数据发送到服务器,我们必须把表单的method设置为POST,将enctype设置为multipart/form-data。jsp代码如下:
<body>
<s:form action="uploadPro" method="post" enctype="multipart/form-data">
<s:file name="upload" label="选择文件"/><br />
<s:submit value="上传"/>
</s:form>
</body>
[b]2. 实现文件上传的Action(UploadAction.java)[/b]
Action实现类其实非常简单,只需要定义三个属性接收文件参数即可,一是类型为File的xxx封装文件内容,二是String类型的xxxFileName封装文件名,三是String类型的xxxContentType封装文件类型。代码如下:
package test;
import com.opensymphony.xwork2.ActionSupport;
import java.io.*;
public class UploadAction extends ActionSupport{
//封装上传文件域
private File upload;
//封装上传文件类型
private String uploadContentType;
//封装上传文件名
private String uploadFileName;
public void setUpload(File upload) {
this.upload = upload;
}
public File getUpload(){
return (this.upload);
}
public void setUploadContentType(String uploadContentType){
this.uploadContentType = uploadContentType;
}
public String getUploadContentType(){
return (this.uploadContentType);
}
public void setUploadFileName(String uploadFileName){
this.uploadFileName = uploadFileName;
}
public String getUploadFileName(){
return (this.uploadFileName);
}
@Override
public String execute() throws Exception{
//将文件写入服务器,没有此文件时新建
File file = new File("h:\\AAA\\"+getUploadFileName());
FileOutputStream fos = new FileOutputStream(file);
FileInputStream fis = new FileInputStream(getUpload());
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0){
fos.write(buffer , 0 , len);
}
fos.close();
return SUCCESS;
}
}
[b]3. 配置文件上传的Action(struts.xml)[/b]
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 设置该应用使用的解码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置处理文件上传的Action -->
<action name="uploadPro" class="test.UploadAction">
<!-- 配置Struts 2默认的视图页面 -->
<result>/upload.jsp</result>
</action>
</package>
</struts>
4. 实现文件过滤
方法一:直接在Action中判断文件的类型是否为允许类型
方法二:拦截器实现文件过滤,如下:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<!-- 设置该应用使用的解码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置处理文件上传的Action -->
<action name="uploadPro" class="org.crazyit.app.action.UploadAction">
<!-- 配置fileUpload的拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 配置允许上传的文件类型 -->
<param name="allowedTypes">image/png,image/gif,image/jpeg</param>
<!-- 配置允许上传的文件大小 -->
<param name="maximumSize">2000</param>
</interceptor-ref>
<!-- 配置系统默认的拦截器 -->
<interceptor-ref name="defaultStack"/>
<!-- 配置Struts 2默认的视图页面 -->
<result>/WEB-INF/content/succ.jsp</result>
</action>
</package>
</struts>
[b]Struts2的文件下载:[/b]
[b]1. 测试文件下载jsp页面[/b]
<body>
<ul><li>下载:<a href="download.action">下载文件</a></li></ul>
</body>
[b]2. 实现文件下载的Action(FileDownloadAction.java)[/b]
package test;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.*;
public class FileDownloadAction extends ActionSupport {
//该属性可以在配置文件中动态指定该属性值
private String inputPath;
//依赖注入该属性值的setter方法
public void setInputPath(String value){
inputPath = value;
}
/*
* 定义一个返回InputStream的方法,该方法将作为被下载文件的入口,
* 且需要配置stream类型结果时指定inputName参数,inputName参数的值就是方法去掉get前缀、首字母小写的字符串
*/
public InputStream getTargetFile() throws Exception {
//ServletContext提供getResourceAsStream()方法返回指定文件对应的输入流
return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
}
}
[b]3. 配置文件下载的Action(struts.xml)[/b]
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="mess"/>
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<action name="download" class="test.FileDownloadAction">
<param name="inputPath">\images\aaa.jpg</param>
<!-- 配置结果类型为stream的结果 -->
<result name="success" type="stream">
<!-- 指定下载文件的文件类型 -->
<param name="contentType">image/jpg</param>
<!-- 指定由getTargetFile()方法返回被下载文件的InputStream -->
<param name="inputName">targetFile</param>
<param name="contentDisposition">filename="hap.jpg"</param>
<!-- 指定下载文件的缓冲大小 -->
<param name="bufferSize">4096</param>
</result>
</action>
</package>
</struts>
[b]六、Struts2返回JSON数据示例[/b]
[b]1. 导包[/b]
除导入Struts2基本包以外还要导入struts2-json-plugin-2.3.15.3.jar
[b]2. 实现Action(JSONExample.java)[/b]
package test;
import java.util.HashMap;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import org.apache.struts2.json.annotations.JSON;
public class JSONExample{
//模拟处理结果的属性
private int[] ints = {10, 20};
private Map<String , String> map = new HashMap<String , String>();
private String customName = "顾客";
//封装请求参数的三个属性
private String field1;
//'transient'修饰的属性不会被序列化
private transient String field2;
//没有setter和getter方法的字段不会被序列化
private String field3;
public String execute(){
field2 = "333";
map.put("name", "疯狂Java讲义");
return Action.SUCCESS;
}
//使用注释语法来改变该属性序列化后的属性名
@JSON(name="newName")
public Map getMap(){
return this.map;
}
//customName属性的setter和getter方法
public void setCustomName(String customName){
this.customName = customName;
}
public String getCustomName(){
return this.customName;
}
//field1属性的setter和getter方法
public void setField1(String field1){
this.field1 = field1;
}
public String getField1(){
return this.field1;
}
//field2属性的setter和getter方法
public void setField2(String field2){
this.field2 = field2;
}
public String getField2(){
return this.field2;
}
//field3属性的setter和getter方法
public void setField3(String field3){
this.field3 = field3;
}
public String getField3(){
return this.field3;
}
}
[b]3. 配置Action(struts.xml)[/b]
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.i18n.encoding" value="UTF-8"/>
<package name="example" extends="json-default">
<action name="JSONExample" class="test.JSONExample">
<!-- 配置类型的json的Result -->
<result type="json">
<!-- 为该Result指定参数 -->
<param name="noCache">true</param>
<param name="contentType">text/html</param>
<!-- 设置只返回Action的map属性 -->
<!-- param name="root">map</param -->
</result>
</action>
</package>
</struts>
[b]4. 测试返回结果[/b]
浏览器输入: http://localhost:8080/TestStrutsJSON/example/JSONExample(项目路径+Action配置文件包名+Action名)测试得到的JSON数据。