之前,我是用jsp里生成的图片,链接到img标签中的,如下:
<img src="code.jsp"/> 
code.jsp中,为生成图片的java代码,大家应该都知道,我就不贴出来了。我现在想把code.jsp中的java代码,放在action中去,做成类似下面的,
<img src="codeGetCode.action"/> 也实现同样的效果,怎么做呢?
我调了很久,没能实现,我把关键代码都贴出来,请高人帮忙看下,哪里出问题了,谢谢。
struts.xml的主要代码:
    <action name="codeGetCode" class="test.CodeAction" method="getCode">
  <result name="success">null</result><!-- 这里肯定有问题的了,主要改这里和action中的getCode返回类型 -->
    </action>CodeAction中的getCode方法如下: public String getCode() throws Exception{
response = ServletActionContext.getResponse();
// response.addHeader("Pragma", "no-cache");
// response.addHeader("Cache-Control", "no-store");
// response.setHeader("Pragma", "no-cache");
// response.setDateHeader("Expires", 0);
// response.setContentType("text/html");
// response.setCharacterEncoding("UTF-8");

HttpSession session = request.getSession();

// 设置编码及响应类型
response.setContentType("image/jpeg");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);

//out.clear();//这句针对resin服务器,如果是tomacat可以不要这句
//out = pageContext.pushBody();
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 在内存中创建图象
int width = 60, height = 22;
BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics(); // 生成随机类
Random random = new Random(); // 设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height); // 设定字体
g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); // 画边框
// g.setColor(new Color());
// g.drawRect(0,0,width-1,height-1); // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160, 200));//getRandColor方法为得到一个随机的Color对象
for (int i = 0; i < 155; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
} // 取随机产生的认证码(4位数字)
String sRand = "";
for (int i = 0; i < 4; i++) {
String rand = String.valueOf(random.nextInt(10));
sRand += rand;
// 将认证码显示到图象中
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
g.drawString(rand, 13 * i + 6, 16);
} // 将认证码存入SESSION
// 保存入session,用于与用户的输入进行比较.
// 注意比较完之后清除session.
HttpSession session = request.getSession(false);
session.setAttribute("randCode", sRand); // 图象生效
g.dispose();
OutputStream output = response.getOutputStream(); // 输出图象到页面
ImageIO.write(image, "JPEG", response.getOutputStream());
output.flush();
output.close();                   return SUCCESS;
}
          //生成的随机颜色   
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);
}说明下吧,生成图片的代码肯定是没问题的了,跟这部分代码应该没关系的,问题应该是出在,return 类型这里,我试了下类似为流,也没成功,后来要认为,应该返回的类似为:org.apache.struts2.dispatcher.HttpHeaderResult 对象,httpheader,但感觉也不对,不知道那里出问题的了。

解决方案 »

  1.   

    嗯,问题就是出现在return那。
    下面是我使用AJAX+Struts生成图片的代码。
    在AJAX中使用Struts2生成图片显示在浏览器里:
    1. 创建BufferedImage并在它上面进行绘制.
    2. 取得response的output stream,然后使用ImageIO写入图片数据.
    3. 关闭output stream,这样图片就会发送到浏览器端.
    4. <img src="pic.action">: 设置img的src为Struts2里面action的名字即可.---------------------------------- strust.xml配置 -------------------------
    <package name="stuts-test" extends="struts-default" namespace="/">
        <action name="pic" class="action.PictureAction" method="createPicture"></action>
    </package>
    ----------------------------------服务器端代码:PictureAction.java -------------------------
    package action;import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;import javax.imageio.ImageIO;
    import javax.servlet.ServletOutputStream;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;@SuppressWarnings("serial")
    public class PictureAction extends ActionSupport {    public void createPicture() throws Exception {
            BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.getGraphics();
            g.setColor(Color.WHITE);
            g.fillOval(50, 50, 100, 100);        ServletActionContext.getResponse().setContentType("image/png");
            ServletOutputStream out = ServletActionContext.getResponse().getOutputStream();
            ImageIO.write(image, "png", out);
            out.close();
        }
    }
    ----------------------------------浏览器端网页代码:pic.html --------------------------------
    <html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>Title</title>    <script src="jquery.js"></script>
        <script type="text/javascript">
        $(function() {
            $("#ajaxImg").attr("src", "pic.action");
        });
        </script>
    </head><body>
        <img id="ajaxImg" />
    </body>
    </html>
      

  2.   

    下面是用Servlet生成验证码的代码
    1. 需要的jar包: patchca.jar: http://code.google.com/p/patchca/
       patchca使用LGPL协议: GNU Lesser General Public License
    2. 请求验证码的 JSP: validate.jsp
    3. 产生验证码的 Servlet: ValidationCode.java
    4. 验证验证码的 Servlet: ValidateCode.java验证过程: validate.jsp请求验证码 -> ValidationCode.java生成验证码图片和相应的字符给validate.jsp -> 用户输入验证码 -> ValidateCode.java验证用户的验证码是否输入正确.
    ================================== validate.jsp ==================================
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head><body>
        <img src="ValidationCode">
        <form action="ValidateCode" method="post">
            <input type="text" name="validateCode"/>
            <input type="submit" value="Submit"/>
        </form>
    </body>
    </html> ================================== ValidateCode.java ==================================import java.io.IOException;import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;/**
     * Servlet implementation class Validate
     */
    public class ValidateCode extends HttpServlet {
        private static final long serialVersionUID = 1L;    public ValidateCode() {
            super();
        }    @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
                                                                                      IOException {
            String validateCode = request.getParameter("validateCode");
            HttpSession session = request.getSession();
            
            // 从session中取得验证码与用户输入的验证码进行比较
            String storedValidateCode = (String) session.getAttribute(session.getId());
            
            response.setHeader("Content-type", "text/html; charset=UTF-8");
            if (validateCode.equalsIgnoreCase(storedValidateCode)) {
                response.getWriter().println("验证码输入正确: " + validateCode);
            } else {
                response.getWriter().println("验证码输入错误: " + validateCode);
            }
        }    @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
                                                                                       IOException {
            doGet(request, response);
        }
    }
     
    ================================== ValidationCode.java ==================================
    import java.awt.image.BufferedImage;
    import java.io.IOException;import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;import org.patchca.color.GradientColorFactory;
    import org.patchca.filter.predefined.CurvesRippleFilterFactory;
    import org.patchca.filter.predefined.DiffuseRippleFilterFactory;
    import org.patchca.filter.predefined.DoubleRippleFilterFactory;
    import org.patchca.filter.predefined.MarbleRippleFilterFactory;
    import org.patchca.filter.predefined.RippleFilterFactory;
    import org.patchca.filter.predefined.WobbleRippleFilterFactory;
    import org.patchca.service.Captcha;
    import org.patchca.service.ConfigurableCaptchaService;/**
     * Servlet implementation class ValidateCode
     */
    public class ValidationCode extends HttpServlet {
        private static final long serialVersionUID = 1L;    public ValidationCode() {
            super();
        }    // 关键之处,产生图片    @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
                                                                                      IOException {
            response.setContentType("image/png");
            ValidateEntry ve = new ValidateEntry();        HttpSession session = request.getSession();
            session.setAttribute(session.getId(), ve.getCode()); // 验证码保存在session中        ServletOutputStream out = response.getOutputStream();
            BufferedImage img = ve.getImage();
            ImageIO.write(img, "png", out);
            out.close();
        }    @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
                                                                                       IOException {
            doGet(request, response);
        }    protected class ValidateEntry {
            String code;
            BufferedImage image;        ValidateEntry() {
                createEntry();
            }        public String getCode() {
                return code;
            }        public BufferedImage getImage() {
                return image;
            }        private void createEntry() {
                ConfigurableCaptchaService cs = new ConfigurableCaptchaService();
                cs.setColorFactory(new GradientColorFactory());
                switch ((int) (System.currentTimeMillis() % 6)) {
                case 0:
                    cs.setFilterFactory(new CurvesRippleFilterFactory(cs.getColorFactory()));
                    break;
                case 1:
                    cs.setFilterFactory(new MarbleRippleFilterFactory());
                    break;
                case 2:
                    cs.setFilterFactory(new DoubleRippleFilterFactory());
                    break;
                case 3:
                    cs.setFilterFactory(new WobbleRippleFilterFactory());
                    break;
                case 4:
                    cs.setFilterFactory(new DiffuseRippleFilterFactory());
                    break;
                case 5:
                    cs.setFilterFactory(new RippleFilterFactory());
                    break;
                }            Captcha captcha = cs.getCaptcha();
                code = captcha.getChallenge();
                image = captcha.getImage();
            }
        }
    }
      

  3.   

    你是怎么触发这个action呢?<img src="codeGetCode.action"/>