首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Struts2中施用Stream Result Type

2012-10-24 
Struts2中使用Stream Result TypeStream result type是Struts2中比较有用的一个feature。特别是在动态生成

Struts2中使用Stream Result Type

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" 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的代码...   InputStremin = new ByteArrayInputStream(output.toByteArray());?

public SafeImageAction() {
}

public String execute() throws IOException {
response.setContentType("image/jpeg");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0L);
output = new ByteArrayOutputStream();
// HttpSession session = request.getSession();
int width = 60;
int height = 20;
// image = new BufferedImage(width, height, 1);
image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
g.setFont(new Font("Arial", 0, 19));
g.setColor(getRandColor(160, 200));
for (int i = 0; i < 155; i++) {
int x = random.nextInt(width + 100);
int y = random.nextInt(height + 100);
int xl = random.nextInt(10);
int yl = random.nextInt(12);
g.drawOval(x, y, x + xl, y + yl);
}

String sRand = "";
for (int i = 0; i < 4; i++) {
String rand = getRandChar(random.nextInt(36));
sRand = (new StringBuilder()).append(sRand).append(rand).toString();
g.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
g.drawString(rand, 13 * i + 6, 16);
}

// session().setAttribute("rand", sRand);
// session.put("rand", sRand);
g.dispose();
try {
ImageIO.write(image, "jpg", output);
} catch (IOException e) {
System.out.println("生成验证码有误: " + e);
}
imageOut = response.getOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(imageOut);
encoder.encode(image);
this.imageStream = new ByteArrayInputStream(output.toByteArray());
output.close();
return SUCCESS;
}

public void setServletResponse(HttpServletResponse response) {
this.response = response;
}

public void setServletRequest(HttpServletRequest request) {
this.request = request;
}

private Color getRandColor(int fc, int bc) {
Random random = new Random();
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}

private String getRandChar(int randNumber) {
return CHARARRAY[randNumber];
}

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

public BufferedImage getImage() {
return image;
}

public void setImage(BufferedImage image) {
this.image = image;
}

public javax.servlet.ServletOutputStream getImageOut() {
return imageOut;
}

public void setImageOut(javax.servlet.ServletOutputStream imageOut) {
this.imageOut = imageOut;
}

}
----------------------------------------- 9 楼 ray_linn 2008-07-03   Stream result type? 可有可无,把Respose的header设置成image/xxx就可以了。 10 楼 kjj 2008-12-31   ray_linn 写道Stream result type? 可有可无,把Respose的header设置成image/xxx就可以了。

用struts2 为什么,她的目的就是让你们忘掉servlet ,造一个脱离servlet 的瓶子,你又给拉回去了,还不如直接用servlet 算了,不伦不类滴 11 楼 epanthere 2009-01-09   kjj 写道ray_linn 写道Stream result type? 可有可无,把Respose的header设置成image/xxx就可以了。

用struts2 为什么,她的目的就是让你们忘掉servlet ,造一个脱离servlet 的瓶子,你又给拉回去了,还不如直接用servlet 算了,不伦不类滴
ls的正解  和servlet的交互struts2都给你封装好了  干嘛没事找事 12 楼 wenquan4004 2009-04-02   哎呀!我找了好几天的有关struts2读取数据库显示图片的例子都是些老版本(servlet)
谁知今天我才看到一片关于使用result处理的图片的文章,还是英文,费老劲才看懂,原来是用了StreamResult,想看看网上有没有和这个相关的文章学习下,还就找到了,看了哥哥的文章我是如梦初醒啊!学了java也很长时间了虽说会抄写代码,但是达到哥哥这种地步还是望尘莫及啊!谢谢! 13 楼 wzlcm 2011-07-26   kjj 写道ray_linn 写道Stream result type? 可有可无,把Respose的header设置成image/xxx就可以了。

用struts2 为什么,她的目的就是让你们忘掉servlet ,造一个脱离servlet 的瓶子,你又给拉回去了,还不如直接用servlet 算了,不伦不类滴
不大同意楼上,用header也并非没有好处,例如:我想在线看(一般浏览器都支持)doc,excel,jpg等,我就没必要用几个不同的result,我可以直接在后台判断文件类型,然后直接让返回相应的ContentType,这样岂不更方便?
使用框架,当然怎么是简单方便怎么样,而不要被所谓“思想”给局限了!

热点排行