`

Struts2中使用Stream Result Type

    博客分类:
  • java
阅读更多

Stream result type是Struts2中比较有用的一个feature。特别是在动态生成图片和文档的情况下;例如动态验证码,各种报表图片生成等。鉴于网上使用struts2生成动态验证码,struts2+jfreechart的例子中很少使用到该feature,这里以生成动态验证码为例解释stream result的使用:

  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;
        }
     
  2. 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>
     
  3. 可以看出使用Stream result type非常简单。在该例子中使用了一个小技巧将OutputStream转化为InputStrem
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    //省略填充output的代码
    ...   
    InputStrem
    in = new ByteArrayInputStream(output.toByteArray()); 
分享到:
评论
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,这样岂不更方便?
使用框架,当然怎么是简单方便怎么样,而不要被所谓“思想”给局限了!
12 楼 wenquan4004 2009-04-02  
哎呀!我找了好几天的有关struts2读取数据库显示图片的例子都是些老版本(servlet)
谁知今天我才看到一片关于使用result处理的图片的文章,还是英文,费老劲才看懂,原来是用了StreamResult,想看看网上有没有和这个相关的文章学习下,还就找到了,看了哥哥的文章我是如梦初醒啊!学了java也很长时间了虽说会抄写代码,但是达到哥哥这种地步还是望尘莫及啊!谢谢!
11 楼 epanthere 2009-01-09  
kjj 写道
ray_linn 写道
Stream result type? 可有可无,把Respose的header设置成image/xxx就可以了。


用struts2 为什么,她的目的就是让你们忘掉servlet ,造一个脱离servlet 的瓶子,你又给拉回去了,还不如直接用servlet 算了,不伦不类滴

ls的正解  和servlet的交互struts2都给你封装好了  干嘛没事找事
10 楼 kjj 2008-12-31  
ray_linn 写道
Stream result type? 可有可无,把Respose的header设置成image/xxx就可以了。


用struts2 为什么,她的目的就是让你们忘掉servlet ,造一个脱离servlet 的瓶子,你又给拉回去了,还不如直接用servlet 算了,不伦不类滴
9 楼 ray_linn 2008-07-03  
Stream result type? 可有可无,把Respose的header设置成image/xxx就可以了。
8 楼 Acaleph 2008-07-03  
我的程序,虽然结果出来了,但后台总是抛错:
-------------------------------------------------------------------------------
java.lang.IllegalStateException: STREAM
        at org.mortbay.jetty.Response.getWriter(Response.java:585)
        at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:17
1)
        at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.jav
a:164)
        at org.apache.jasper.runtime.JspWriterImpl.flush(JspWriterImpl.java:219)

        at org.apache.struts2.components.ActionComponent.end(ActionComponent.jav
a:150)
        at org.apache.struts2.views.jsp.ComponentTagSupport.doEndTag(ComponentTa
gSupport.java:43)
        at org.apache.jsp.Servlet_jsp._jspx_meth_s_action_0(org.apache.jsp.Servl
et_jsp:150)
        at org.apache.jsp.Servlet_jsp._jspService(org.apache.jsp.Servlet_jsp:85)

        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:93)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper
.java:373)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:4
70)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:364)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487
)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:3
62)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.jav
a:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:1
81)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:7
26)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)

        at org.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
        at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(Servl
etDispatcherResult.java:141)
        at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResul
tSupport.java:178)
        at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(Default
ActionInvocation.java:348)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:253)
        at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doInte
rcept(DefaultWorkflowInterceptor.java:221)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept
(MethodFilterInterceptor.java:86)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(V
alidationInterceptor.java:150)
        at org.apache.struts2.interceptor.validation.AnnotationValidationInterce
ptor.doIntercept(AnnotationValidationInterceptor.java:48)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept
(MethodFilterInterceptor.java:86)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.interc
ept(ConversionErrorInterceptor.java:123)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept
(ParametersInterceptor.java:167)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept
(MethodFilterInterceptor.java:86)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.inter
cept(StaticParametersInterceptor.java:105)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(Checkbox
Interceptor.java:83)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUp
loadInterceptor.java:207)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(
ModelDrivenInterceptor.java:74)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.inte
rcept(ScopedModelDrivenInterceptor.java:127)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at org.apache.struts2.interceptor.ProfilingActivationInterceptor.interce
pt(ProfilingActivationInterceptor.java:107)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.interce
pt(DebuggingInterceptor.java:206)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(Cha
iningInterceptor.java:115)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInt
erceptor.java:143)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(Pr
epareInterceptor.java:121)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept
(MethodFilterInterceptor.java:86)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(Ser
vletConfigInterceptor.java:170)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasI
nterceptor.java:123)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.inter
cept(ExceptionMappingInterceptor.java:176)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:224)
        at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(Default
ActionInvocation.java:223)
        at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTim
erStack.java:455)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:221)
        at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.j
ava:50)
        at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.jav
a:504)
        at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatc
her.java:419)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(Servlet
Handler.java:1084)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterIntern
al(CharacterEncodingFilter.java:96)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR
equestFilter.java:75)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(Servlet
Handler.java:1084)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:3
60)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.jav
a:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:1
81)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:7
26)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)

        at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHand
lerCollection.java:206)
        at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.
java:114)
        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:1
52)
        at org.mortbay.jetty.Server.handle(Server.java:324)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:50
5)
        at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpCo
nnection.java:828)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.ja
va:395)
        at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool
.java:450)
----------------------------------------------------------------------------
程序代码
----------------------------------------------------------------------------
package com.easybea.system.action;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.config.Result;
import org.apache.struts2.config.Results;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

@Results(@Result(name = "success", value = "/Servlet.jsp"))
public class SafeImageAction extends ActionSupport implements SessionAware,
ServletRequestAware, ServletResponseAware {

private Map session;
private HttpServletRequest request;
private HttpServletResponse response;
private BufferedImage image;
private ByteArrayOutputStream output;
private InputStream imageStream;
javax.servlet.ServletOutputStream imageOut;
private static final long serialVersionUID = 1L;
private static final String CHARARRAY[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i",
"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z" };

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;
}

}
-----------------------------------------------------------------------------
7 楼 aninfeel 2008-05-06  
其实设置一下header再输出流就行了,没有stream result type也一样
6 楼 newchengse 2008-05-06  
谢谢楼上的热心回复。不过,我在李刚的《Struts2权威指南》中发现他给出了如下提示:
  即使在Action中书写代码:response.getWriter().println("HHHH");
没有任何实际意义,虽然上述代码在标准Servlet中会生成对客户端的输出。因此,我们在struts2的Action类中获得了HttpServletResponse对象,也不要尝试直接在Action中生成对客户端的输出!

如何理解以上这段话?我见xugq035的代码中包含有response.set***这些方法,能在struts2中使用吗?

楼主的代码,似乎是把图像放在一个InputStream流中了,我很想知道,在JSP页面端如何使用这个InputStream流?
5 楼 xugq035 2008-05-04  
newchengse 写道
大哥,写个完整点的例子嘛,帮人帮到底嘛。请问用于显示图片的JSP代码(最好用struts2标签)应该怎样写?

java:

        response.setHeader("Pragma","No-cache");
        response.setHeader("Cache-Control","no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");

        int width=72, height=18;
        BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        ...
        g.dispose();
        ImageIO.write(image, "JPEG", response.getOutputStream());

jsp:

<img src="authImg.action" id="authImg" onclick="document.getElementById('authImg').src='authImg.action?now='+new Date();" style="cursor: hand;" alt="点击刷新" align="absmiddle"/>
4 楼 newchengse 2008-05-04  
我现在只能做到把图片从数据库中读出,然后写到磁盘上存成一个文件,比如“a.jpg",然后在JSP中用<img src="a.jpg"></img>显示出来,有没有直接用输出流输出到JSP网页中的?
3 楼 newchengse 2008-05-04  
大哥,写个完整点的例子嘛,帮人帮到底嘛。请问用于显示图片的JSP代码(最好用struts2标签)应该怎样写?
2 楼 ilovemeimei 2008-04-24  
谢谢啦,正好用的着。
1 楼 cesia1984 2008-04-06  
多谢楼主分享,是个好方法,方便了好多

相关推荐

Global site tag (gtag.js) - Google Analytics