1,struts2配置文件详解
【总是提示含有非法url,郁闷,竟然不能写】
2,针对配置文件中的 type="stream"分析
原文链接
struts2中 result="stream",可以实现文件的下载功能。
这里有两篇比较清楚和基础的文章:
我这里的应用是POI在内存中生成excel文件供客户端下载。struts.xml中的配置如下
-
- <action name="jxcQuery_*" class="com.chengzhong.action.JxcChaXunAction" method="{1}">
- <result name="success">jxcchaxun.jsp</result>
-
- <result name="toexcelOK" type="stream">
- <param name="contentType">application/vnd.ms-excel</param>
- <param name="contentDisposition">attachment;filename="${fileName}"</param>
- <param name="inputName">excelIS</param>
- </result>
- <result name="error">../404.htm</result>
- </action>
1.type="stream" 把一般内容输出到流
2.参数contentType的地方指定为application/vnd.ms-excel
3.设置为 attachment 将会告诉浏览器下载该文件,filename 指定下载文件保有存时的文件名,若未指定将会是以浏览的页面名作为文件名,如以 download.action 作为文件名。这里使用的是动态文件名,${fileName}。它将通过 Action 的 getFileName() 获得文件名。也就是说Action里面要有一个getFileName ()的方法。
比如下面这个:
- public String getFileName() {
- String fileName = "进销存信息统计表.xls"
- try {
-
- return new String(fileName.getBytes(), "ISO8859-1");
- } catch (UnsupportedEncodingException e) {
- return "jxc.xls";
- }
- }
或者Action 里面有一个fileName的属性,提供它的set 和get 方法。在程序合适的位置给fileName赋值。这两者本质上应该是一样的。
我刚开始没有用注释处的方法转码,用中文做文件名的时候,它就象前面说的用浏览的页面名作为文件名了。
4.<param name="inputName">excelIS</param>
参数inputName指定输入流的名称。和前面的文件名一样,Action里或者提供一个getExcelIS()的方法,或者提供excelIS属性。
5.对流的操作:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
/************************************************************/
DataImportAndExportTool.InfoToExcel(Info, sheetName).write(baos);
byte[] ba = baos.toByteArray();
baos.close();
excelIS = new ByteArrayInputStream(ba);
/*******************************************************************/
//DataImportAndExportTool.InfoToExcel(Info, sheetName).write(fOut); //这样excel表保存在了服务器上
} catch (Exception e) {
e.printStackTrace();
}
return "toexcelOK";、
DataImportAndExportTool.InfoToExcel(Info, sheetName)是我生成excel的方法,info是一个list,sheetName 是工作薄名,这句执行后生成了一个workbook。
ByteArrayOutputStream类是在创建它的实例时,程序内部创建一个byte型别数组的缓冲区,然后利用ByteArrayOutputStream和ByteArrayInputStream的实例向数组中写入或读出byte型数据。在网络传输中我们往往要传输很多变量,我们可以利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去。
ByteArrayOutputStream用途很多。其中缓冲是一个。对象的深浅复制也会用到
注意:以下是一些参数说明
contentType
内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片
inputName
下载文件的来源流,对应着action类中某个类型为Inputstream的属性名,例如取值为inputStream的属性需要编写getInputStream()方法
contentDisposition
文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件。取值为:
attachment;filename="struts2.txt",表示文件下载的时候保存的名字应为struts2.txt。如果直接写filename="struts2.txt",那么默认情况是代表inline,浏览器会尝试自动打开它,等价于这样的写法:inline; filename="struts2.txt"
bufferSize
下载缓冲区的大小
。在这里面,contentType属性和contentDisposition分别对应着HTTP响应中的头Content-Type和Content-disposition头。
3,针对 type="chain dispatcher、redirect(redirect-action)"的分析
原文链接
dispatcher 为默认跳转类型,用于返回一个视图资源(如:jsp)
Xml代码 :
<result name="success">/main.jsp</result>
<result name="success">/main.jsp</result>
以上写法使用了两个默认,其完整的写法为:
<result name="success" type="dispatcher">
<param name="location">/maini.jsp</param>
</result>
用于页面转发,页面跳转过程一直是同一个线程,Action中的数据一直保存在。
location只能是页面,不能是另一个action(可用type="chain"解决)。
redirect 类型用于重定向到一个页面,另一个action或一个网址。
Xml代码:
<result name="success" type="redirect">aaa.jsp</result>
<result name="success" type="redirect">bbb.action</result>
<result name="success" type="redirect">www.baidu.com</result>
缺点:redirect把一个http返回码(SUCCESS)以及返回的页面位置一起重新发给web服务器,容纳后由web服务器产生一个新的HTTP请求,就会产生一个新的线程,保存在原来Action执行的线程中的数据就无法访问。
所以,result需要包含Action的数据,那么redirect不是一个可行的办法。因为新的HTTP请求时在Servlet容器的新的线程中处理的,ActionContext中的所有状态都不会存在。
处理方法:
(方法一):
<result name="topic" type="redirect">/topicAction!findTopics.do?topicId=${topicId}</result> //用这种方式可以传递action中的参数到页面
(方法二):
<result name="topic" type="redirect-action">
<param name="actionName">findTopics</param>
<param name="topicId">${topicId}</param>
</result>
redirect-action 结果类型使用ActionMapperFactory提供的ActionMapper来重定向请求到另外一个action
Xml代码:
<result name="err" type="redirect-action">
<param name="actionName">重定向的Action名</param>
<param name="namespace">重定向Action所在的名字空间</param>
</result>
redirect和redirect-action两种结果类型在使用上其实并没有什么区别,只是写法不同而已。
chain 用于把相关的几个action连接起来,共同完成一个功能。
Xml代码:
<action name="step1" class="test.Step1Action">
<result name="success" type="chain">step2.action</result>
</action>
<action name="step2" class="test.Step2Action">
<result name="success">finish.jsp</result>
</action>
处于chain中的action属于同一个http请求,共享一个ActionContext
plaintextj 结果类型用于直接在页面上显示源代码
Xml代码:
<result name="err" type="plaintext">
<param name="location">具体的位置</param>
<param name="charSet">字符规范(如GBK)</param>
</result>
=============
提交服务器处理业务后结果返回页面的处理,Struts2提供了对不同种类返回结果的支持,常见的有JSP,FreeMarker,Velocity等。
struts.xml配置文件中result的语法:<result name="" type="">xxxxx</result>
Struts2支持的不同类型的返回结果为:
Chain Result-->type="chain"
用来处理Action链
Dispatcher Result -->type="dispatcher"
用来转向页面,通常处理JSP
FreeMarker Result -->type="freemarker"
处理FreeMarker模板
HttpHeader Result -->type="httpheader"
用来控制特殊的Http行为
Redirect Result -->type="redirect"
重定向到一个URL
Redirect Action Result -->type="redirectAction"
重定向到一个Action
Stream Result -->type="stream"
向浏览器发送InputSream对象,通常用来处理文件下载
Velocity Result -->type="velocity"
处理Velocity模板
XLST Result -->type="xslt"
处理XML/XLST模板
PlainText Result -->type="plainText"
显示原始文件内容,例如文件源代码
另外第三方的result类型还包括JasperReports Plugin,专门用来处理JasperReport类型的报表输出。