`

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  
多谢楼主分享,是个好方法,方便了好多

相关推荐

    struts2 result type 介绍

    在Struts2中,Result Type是由`struts-default.xml`配置文件中的`&lt;package&gt;`元素的`defaultResultType`属性指定的,默认情况下,这个值通常是“dispatcher”,意味着Action完成后会使用Dispatcher Result来渲染JSP...

    struts2的action的几种result type说明

    在Struts2中,Action是业务逻辑的核心组件,而Result是控制流程的关键部分,它定义了Action执行后如何展示结果。Result Type是Result的一种预定义类型,决定了结果如何被处理和展现给用户。在`struts-default.xml`...

    struts2 result配置详解

    Struts2 框架中 Result 配置是一种非常重要的配置,它直接影响着应用程序的执行结果。Result 配置通常用于定义 Action 的执行结果,例如将结果.redirect 到一个新的 URL,或者将结果.render 到一个 JSP 页面。Struts...

    struts2中result类型之redirect

    在Struts2框架中,`Result`类型是动作(Action)执行后的一种处理方式,它定义了动作执行完后页面跳转或者数据处理的行为。`Redirect`是`Result`类型中的一种,它涉及到Web应用程序中的URL重定向概念,对用户浏览器...

    Struts2 result和type

    ### Struts2中的Result与Type详解 #### 一、引言 在Struts2框架中,`Result`和`Type`是两个非常重要的概念。它们主要用于控制Action执行完毕后页面的跳转方式以及如何处理Action返回的结果。通过合理配置`Result`与...

    Struts2 Result类型

    Struts2 Result类型是Struts2框架中一个关键的概念,它是控制Action执行后响应到何处的重要组件。在处理用户请求并执行相应的业务逻辑后,Action需要将结果返回给客户端,而Result类型就是用来定义这个返回过程的...

    struts2的result标签使用

    在Struts2中,`Result`标签是核心组件之一,用于定义动作执行后如何跳转到相应的视图。让我们深入探讨一下`Result`标签的使用以及在Struts2框架中的作用。 ### 1. Struts2框架概述 Struts2框架基于MVC设计模式,...

    Struts2学习资源Result part1.rar

    在Struts2中,Result主要负责将处理后的数据传递给相应的视图,如JSP、HTML或者其他的静态资源。Result类型是通过配置在Action类的execute方法返回值或者struts.xml配置文件中定义的。默认情况下,如果未明确指定...

    解决struts2下载异常的jar包 struts2-sunspoter-stream-1.0.jar

    在struts2中使用result里type="stream"的结果类型时,可以实现文件的下载管理,使用时也是比较顺畅,但是当在“下载提示窗口”中点击“取消按钮”时,总是报出“java.lang.IllegalStateException”异常,异常内容...

    Struts2--result配置的各种视图转发类型

    在Struts2中,结果(Result)是Action执行后控制流程的重要部分,它负责将处理后的数据或者控制逻辑转向合适的视图。这篇博文将深入探讨Struts2中的result配置以及各种视图转发类型。 首先,让我们理解Result的基本...

    在Struts2中使用JasperReports生成报表

    首先,我们需要了解Struts2中整合JasperReports的基本步骤: 1. **环境准备**:确保你已经安装了MyEclipse开发环境,并且在项目中引入了Struts2和JasperReports的相关库。这些库通常包括struts2-core、...

    struts2的XSLTResult结果类型

    Struts2中预定义了一些结果类型,例如dispatcher(用于转发到一个JSP页面)、stream(用于流式传输文件)和redirect(用于重定向到另一个URL)。XSLTResult是其中之一,它专门用于处理XML数据的转换。 要使用XSLT...

    struts2实现文件下载功能

    - 在Action类中,设置返回值(Result)为`stream`类型。这告诉Struts2框架需要以流的形式传输数据。在Struts2的配置文件(struts.xml)中添加相应的配置。 3. **设置Content-Type和Content-Disposition**: - 在...

    struts2 中文文件名文件下载

    解决Struts2中的中文文件名下载问题,可以按照以下步骤进行: 1. **配置Struts2 Action类**: 在处理文件下载的Action类中,需要指定文件名的字符编码。可以使用`ContentDisposition`类来自定义HTTP响应头,以指定...

    struts2 向结果传参数

    在Struts2中,结果(Result)是动作(Action)执行后跳转的目标,它可以是一个JSP、Servlet或其他资源。有时我们需要在Action执行后向结果传递参数,以便在目标页面中使用这些参数来呈现数据或执行某些逻辑。本文将...

    Struts2中实现文件下载(修正中文问题).pdf

    总结来说,Struts2中实现文件下载的关键在于正确配置`struts.xml`,使用`stream`类型的结果,并处理好`Content-Disposition`中的文件名编码。对于中文文件名,需要在Action中提供编码转换的方法,并在配置文件中引用...

    Struts 2中实现文件下载

    在Struts 2中,文件下载功能是通过Action和Result类型的组合实现的,允许用户从服务器端下载文件到客户端。以下将详细介绍如何在Struts 2中实现文件下载,特别是处理中文文件名的问题。 首先,你需要创建一个Action...

    struts2自定义结果类型demo

    在Struts2中,结果类型(Result Type)是动作执行后处理结果的关键部分,它决定了如何将控制权转移给下一个资源,如JSP、FreeMarker模板或者重定向到其他URL。自定义结果类型允许开发者根据项目需求定制化结果处理...

    struts2实现文件上传下载

    首先,我们需要了解Struts2中的文件上传机制。Struts2提供了`FileUploadInterceptor`拦截器来处理文件上传请求。在处理文件上传时,开发者需要在Action类中声明一个`List&lt;FileInfo&gt;`类型的字段,用于接收上传的文件...

    Struts2之struts2文件下载详解案例struts012

    本案例"Struts2之struts012"将深入探讨如何在Struts2中实现文件下载的功能。 首先,我们需要创建一个Action类,它是Struts2的核心组件,用于处理用户的请求。在Action类中,我们将定义一个方法,该方法负责获取要...

Global site tag (gtag.js) - Google Analytics