高分求解:Jsp生成图片验证码,Tomcat报错
<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %><%!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); }%><%response.setHeader("Pragma","No-cache");response.setHeader("Cache-Control","no-cache");response.setDateHeader("Expires", 0);int width=60, height=20;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = image.getGraphics();Random random = new Random();g.setColor(getRandColor(250,252));g.fillRect(0, 0, width, height);g.setFont(new Font("Times New Roman",Font.PLAIN,20));g.setColor(getRandColor(150,160));for (int i=0;i<30;i++){ int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(10); int yl = random.nextInt(10); g.drawLine(x,y,x+xl,y+yl);}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.setAttribute("random",sRand);g.dispose();ImageIO.write(image, "JPEG", response.getOutputStream());%>
高分求解!
[解决办法]
tomcat 把这个jsp 翻译后的 代码如下
(注意看我注释的地方)
-------------------------------
package org.apache.jsp;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;import java.awt.*;import java.awt.image.*;import java.util.*;import javax.imageio.*;public final class testpic_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent {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 static final JspFactory _jspxFactory = JspFactory.getDefaultFactory(); private static java.util.List _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.AnnotationProcessor _jsp_annotationprocessor; public Object getDependants() { return _jspx_dependants; } public void _jspInit() { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName()); } public void _jspDestroy() { } public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try { response.setContentType("image/jpeg"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; // 注意这儿. 这儿用的是 PrintWriter &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ① out.write('\r'); out.write('\n'); out.write('\r'); out.write('\n'); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); int width = 60, height = 20; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); Random random = new Random(); g.setColor(getRandColor(250, 252)); g.fillRect(0, 0, width, height); g.setFont(new Font("Times New Roman", Font.PLAIN, 20)); g.setColor(getRandColor(150, 160)); for (int i = 0; i < 30; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(10); int yl = random.nextInt(10); g.drawLine(x, y, x + xl, y + yl); } 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.setAttribute("random", sRand); g.dispose(); // 这儿你又调用OutputStream , &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ③ ImageIO.write(image, "JPEG", response.getOutputStream()); // 注意这儿. 这儿用的是 PrintWriter &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ② out.write('\r'); out.write('\n'); } catch (Throwable t) { if (!(t instanceof SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { out.clearBuffer(); } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } }}
[解决办法]
我了写过一个, 把它贴出来吧.在我blog上呢. 还有好玩的. 欢迎看一下
http://newblog.tom.com/cn_z
-----------------
package cn.z.servlet;import java.awt.Color;import java.awt.Graphics;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 java.awt.Font;public class GenerateCheckCodeServlet extends HttpServlet { // 生成的验证码的宽与高 int WIDTH = 80, HEIGHT = 30; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setDateHeader("Expires", 0); response.setHeader("Cache-control", "no-cache"); response.setHeader("Pragma", "no-cache"); ServletOutputStream out = response.getOutputStream(); // 得到随机的验证码 char[] rands = generateCheckCode(); BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); // 先画背景 drawBackground(g); // 再画验证码 drawCheckCode(g, rands); g.dispose(); // 设置响应头为image/jpeg response.setContentType("image/jpeg"); // 把验证码也放到session里,以便和用户手工输入的进行对比 request.getSession().setAttribute("check-code", new String(rands)); System.out.println(new String(rands)); // 输出图片 ImageIO.write(image, "JPEG", out); out.flush(); out.close(); } // 生成4位随机验证码的函数 private char[] generateCheckCode() { // 这个是用ASCII的方法, char[] rands = new char[4]; int rand = -1; for (int i = 0; i < rands.length; i++) { while (rand < 48 || (rand > 57 && rand < 65) || (rand > 90 && rand < 97) || rand > 122) { rand = (int) (Math.random() * 127); // System.out.print(rand + "\t"); } rands[i] = (char) rand; } return rands; } // 第二种生成验证码的方法 private char[] generateCheckCode2() { // 这个是随机取出字符串中的字符. String chars = "abcdefghijklmnopqrstuvwxyz123456789"; char[] rands = new char[4]; int rand = -1; for (int i = 0; i < rands.length; i++) { rand = (int) (Math.random() * chars.length()); rands[i] = chars.charAt(rand); } return rands; } private void drawCheckCode(Graphics g, char[] rands) { // 在不同的高度画验证码的每一个字符 g.setColor(Color.BLACK); g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 18)); g.drawString("" + rands[0], 11, 25); g.drawString("" + rands[1], 26, 15); g.drawString("" + rands[2], 41, 23); g.drawString("" + rands[3], 56, 18); } private void drawBackground(Graphics g) { // 画背景 g.setColor(new Color(0xdcdcdc)); g.fillRect(0, 0, WIDTH, HEIGHT); for (int i = 0; i < 500; i++) { // 随机生成500个位置随机,颜色随机的干扰点,并画在背景上 int x = (int) (Math.random() * WIDTH); int y = (int) (Math.random() * HEIGHT); int red = (int) (Math.random() * 255); int green = (int) (Math.random() * 255); int blue = (int) (Math.random() * 255); g.setColor(new Color(red, green, blue)); g.drawOval(x, y, 2, 0); } }}
[解决办法]
来晚了 详细的解释一下吧
jsp编译成servlet之后
在释放在jsp中使用的对象,会调用response.getWriter()
因为这个方法是和response.getOutputStream()相冲突的!
所以会出现以上这个异常。
然后当然是要提出解决的办法,其实挺简单的
在使用完输出流以后调用以下两行代码即可:
out.clear();out = pageContext.pushBody();