Stream result type是Struts2中比较有用的一个feature。特别是在动态生成图片和文档的情况下;例如动态验证码,各种报表图片生成等。鉴于网上使用struts2生成动态验证码,struts2+jfreechart的例子中很少使用到该feature,这里以生成动态验证码为例解释stream result的使用:
-
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>
-
可以看出使用Stream result type非常简单。在该例子中使用了一个小技巧将OutputStream转化为InputStrem
ByteArrayOutputStream output = new ByteArrayOutputStream(); //省略填充output的代码 ... InputStrem in = new ByteArrayInputStream(output.toByteArray());