Stream result type是Struts2中比较有用的一个feature。特别是在动态生成图片和文档下载的情况下

1:图片验证码:

Action类,action主要要提供一个获取InputStrem的方法:

public class CheckCodeAction extends ActionSupport implements SessionAware {
private Logger log = LoggerFactory.getLogger(this.getClass());
private InputStream imageStream;
private Map session;

public String getCheckCodeImage(String str, int show, ByteArrayOutputStream output) {
Random random = new Random();
BufferedImage image = new BufferedImage(80, 30, BufferedImage.TYPE_3BYTE_BGR);
Font font = new Font("Arial", Font.PLAIN, 24);
int distance = 18;
Graphics d = image.getGraphics();
d.setColor(Color.WHITE);
d.fillRect(0, 0, image.getWidth(), image.getHeight());
d.setColor(new Color(random.nextInt(100) + 100, random.nextInt(100) + 100, random.nextInt(100) + 100));
for (int i = 0; i < 10; i++) {
d.drawLine(random.nextInt(image.getWidth()), random.nextInt(image.getHeight()), random.nextInt(image.getWidth()),
random.nextInt(image.getHeight()));
}
d.setColor(Color.BLACK);
d.setFont(font);
String checkCode = "";
char tmp;
int x = -distance;
for (int i = 0; i < show; i++) {
tmp = str.charAt(random.nextInt(str.length() - 1));
checkCode = checkCode + tmp;
x = x + distance;
d.setColor(new Color(random.nextInt(100) + 50, random.nextInt(100) + 50, random.nextInt(100) + 50));
d.drawString(tmp + "", x, random.nextInt(image.getHeight() - (font.getSize())) + (font.getSize()));
}
d.dispose();
try {
ImageIO.write(image, "jpg", output);
} catch (IOException e) {
log.warn("生成验证码错误.", e);
}
return checkCode;
}

public String execute() throws Exception {
ByteArrayOutputStream output = new ByteArrayOutputStream();
String checkCode = getCheckCodeImage("ABCDEFGHJKLMNPQRSTUVWXYZ123456789", 4, output);
this.session.put(Constants.CHECK_CODE_KEY, checkCode);
//这里将output stream转化为 inputstream
this.imageStream = new ByteArrayInputStream(output.toByteArray());
output.close();
return SUCCESS;
}

public InputStream getImageStream() {
return imageStream;
}

public void setSession(Map session) {
this.session = session;
}

struts配置文件:

<action name="checkCode" class="CheckCodeAction">
<result name="success" type="stream">
<param name="contentType">image/jpeg</param>
<!-- 指定提供InputStream的filed name -->
<param name="inputName">imageStream</param>
<param name="bufferSize">1024</param>
</result>
<interceptor-ref name="defaultStack"/>
</action>

2:文件下载:

我这里的应用是POI在内存中生成excel文件供客户端下载。struts.xml中的配置如下:

<action name="jxcQuery_*" class="com.chengzhong.action.JxcChaXunAction" method="{1}">
<result name="success">jxcchaxun.jsp</result>
<!--进销存信息导出为excel -->
<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 {
//中文文件名需要转码为 ISO8859-1,否则乱码
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-TypeContent-disposition头。

struts2 中 result type="stream"的更多相关文章

  1. Struts2 中result type属性说明

    Struts2 中result type属性说明 首先看一下在struts-default.xml中对于result-type的定义: <result-types><result-t ...

  2. struts2文件下载 <result type="stream">

    <!--struts.xml配置--> <action name="download" class="com.unmi.action.DownloadA ...

  3. Struts2 中 result type=”json” 的参数解释

    转自:http://wangquanhpu.iteye.com/blog/1461750 1, ignoreHierarchy 参数:表示是否忽略等级,也就是继承关系,比如:TestAction 继承 ...

  4. struts2 action result type类型

    struts2 action result type类型 1.chain:用来处理Action链,被跳转的action中仍能获取上个页面的值,如request信息. com.opensymphony. ...

  5. struts2.xml 中result type属性说明

    chain           用来处理Action链,被跳转的action中仍能获取上个页面的值,如request信息.           com.opensymphony.xwork2.Acti ...

  6. Struts2中 Result类型配置详解

    一个result代表了一个可能的输出.当Action类的方法执行完成时,它返回一个字符串类型的结果码,框架根据这个结果码选择对应的result,向用户输出.在com.opensymphony.xwor ...

  7. Struts2 语法--result type

    result type: dispatcher,redirect:只能跳转到jsp,html之类的页面,dispatcher属于服务器跳转, redirect属于客户端跳转 chain: 等同于for ...

  8. 04. struts2中Result配置的各种视图转发类型

    概述 <action name="helloworld" class="com.liuyong666.action.HelloWorldAction"&g ...

  9. Struts2.xml中result type属性说明

    在struts2配置XML里,result中type属性有以下几种: 1.dispatcher:服务器跳转到前台,后面跟着可以是JSP.htm等等前台页面,默认是这种. 2.redirect:客户端跳 ...

随机推荐

  1. 对于单片机工程.h头文件的管理

    最近工程管理过于混乱,学习了一些工程头文件管理的方法,现在做一个记录,也分享给大家. 目前有两种管理文件的方式: 1.每一个功能模块对应一个文件夹,里面包含一个.c和一个.h文件如下图所示 这样做的好 ...

  2. Poj 2337 Catenyms(有向图DFS求欧拉通路)

    题意: 给定n个单词, 问是否存在一条欧拉通路(如acm,matal,lack), 如果存在, 输出字典序最小的一条. 分析: 这题可以看作http://www.cnblogs.com/Jadon97 ...

  3. .NET Core 文件的上传与下载

    1.前言 文件导入导出是简单且常用的功能,以下示例实现了文件上传与下载的几种方法,如有不妥的地方,欢迎指正.小白一枚,在往目标前进. 2.1.文件上传    --    纯文件 <form ac ...

  4. Laya 类列表加载优化

    Laya 类列表加载优化 @author ixenos 类列表:在一个页面展示的大量的零散单元的集合(聊天面板.背包) 一.按展示优化1.展示内容少,即使大量数据,但用户只看到少量信息的时候,考虑按需 ...

  5. BZOJ 2561: 最小生成树【最小割/最大流】

    Description 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v), ...

  6. eclipse pom.xml 报错org.apache.maven.plugin.war.WarMojo的解决办法

    如题,maven项目eclipse提示pom.ml有错,提示信息就是org.apache.maven.plugin.war.WarMojo. 然后执行 maven install 出现如下错误提示 [ ...

  7. Circling Round Treasures(codeforces 375c)

    题意:要求在一张网格图上走出一条闭合路径,不得将炸弹包围进去,使围出的总价值减去路径长度最大. /* 类似于poj3182的做法,只不过出现了多个点,那么就用状态压缩的方法记录一个集合即可. */ # ...

  8. C++,C程序设计入门——《高质量程序设计第4章》

    1. 连接规范 1. extern “C” 2. 一部分采用C的连接规范 #ifdef __cplusplus extern "C" { #endif #ifdef __cplus ...

  9. Es首页

    https://www.elastic.co/guide/en/elasticsearch/reference/index.html

  10. Educational Codeforces Round 50 (Rated for Div. 2)F. Relatively Prime Powers

    实际上就是求在[2,n]中,x != a^b的个数,那么实际上就是要求x=a^b的个数,然后用总数减掉就好了. 直接开方求和显然会有重复的数.容斥搞一下,但实际上是要用到莫比乌斯函数的,另外要注意减掉 ...