• JSP入门 导出文件


    1.图片校验码

    <img  src="captcha.jpg"  />

    web.xml配置

    <servlet> 
        <servlet-name>CaptchaServlet</servlet-name>
         <servlet-class>anni.CaptchaServlet</servlet-class>
     </servlet> 
    <servlet-mapping> 
        <servlet-name>CaptchaServlet</servlet-name>
         <url-pattern>/captcha.jpg</url-pattern>
     </servlet-mapping>

    名叫/captcha.jpg的请求会交给CaptchaServlet处理

    jsp和servlet并不是只能返回html格式的数据,实际上它们可以生成任意格式的数据,比如这里我们就用servlet生成了一个图片。

    浏览器只是向服务器发送了一个请求,这个请求的地址是/captcha.jpg还是/index.jsp并没有什么区别,在服务器看来他们仅仅是一个字符串而已,接收到请求后服务器先去按照web.xml中的配置做映射,将请求交给对应的servlet处理,如果web.xml中没有对应这个请求的映射,才会去磁盘查找是否有这么一个文件,找到文件则输出到响应中传回客户端,如果找不到就返回经典的404(找不到访问资源)。

    img只可能通过GET方式发送请求

    public void doGet(HttpServletRequest request, HttpServletResponse response)     throws ServletException, IOException {  
        //设置页面不缓存 
        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(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));     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 
        request.getSession().setAttribute("captcha", sRand);  
        // 图象生效     g.dispose();  
        // 输出图象到页面 
        ImageIO.write(image, "JPEG", response.getOutputStream()); }

    代码最先设置response(响应)中的头部配置,告诉浏览器不要缓存对/captcha.jpg的请求结果,这样才能保证每次刷新页面都看到最新生成的图片,要是设置了缓存很可能每次看到的都是最先请求看到的图片。

    中间一大段代码实现动态生成图片的功能,我们先随机获得几个数字,然后写到BufferedImage中,最后就可以把图片数据写到response,因为图片是二进制数据,所以我们使用了response.getOutputStream()而不是response.getWriter()。

    为了达到验证的功能,每次生成图片之后要记得讲随机得到的数字保存到session中,session中的变量可以跨越多个请求周期存在,等用户输入验证码提交后就能与session中的数据做比较了,这些是在CheckServlet中实现的。

    public void doPost(HttpServletRequest request, HttpServletResponse response)     throws ServletException, IOException {  
        HttpSession session = request.getSession();  
        String requestCaptcha = request.getParameter("captcha"); 
        String sessionCaptcha = (String) session.getAttribute("captcha");  
        if (sessionCaptcha != null && sessionCaptcha.equals(requestCaptcha)) {         session.removeAttribute("captcha"); 
            request.getRequestDispatcher("/success.jsp").forward(request, response);     } else { 
            request.setAttribute("message", "验证码输入错误"); 
            request.getRequestDispatcher("/index.jsp").forward(request, response);     } }

    2.图片验证码 JSP版本

    <%@ 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(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)); 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.setAttribute("captcha", sRand);  
    // 图象生效 
    g.dispose();  
    // 输出图象到页面 
    ImageIO.write(image, "JPEG", response.getOutputStream());  
    out.clear(); 
    out = pageContext.pushBody(); 

    在jsp中使用response.getOutputStream()很可能引起一个问题。

    getOutputStream() has already been called for this response

    在tomcat5下jsp中出现此错误,一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等)后没有妥善处理好。

    具体的原因就是在tomcat中,jsp转换成servlet之后在函数_jspService(HttpServletRequest request, 
    HttpServletResponse response)的最后有一段这样的代码

    finally { 
        if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context); } 

    这里是在释放在jsp中使用的对象,会调用response.getWriter(),因为这个方法是和
    response.getOutputStream()相冲突的,所以会出现以上这个异常。 
    然后当然是要提出解决的办法,其实挺简单的(并不是和某些朋友说的那样--将jsp内的所有空格和回车符号所有都删除掉),在使用完输出流以后调用以下两行代码即可:

    out.clear(); 
    out = pageContext.pushBody();
  • 相关阅读:
    python urllib urllib2
    python 标准库获取网络信息
    dell N1500 安全配置
    python jinjia2模板使用
    flask-admin
    github使用
    python中文处理
    C++输入和输出中进制问题
    hdu1708(C++)
    hdu1017(C++)
  • 原文地址:https://www.cnblogs.com/Dhouse/p/3396986.html
Copyright © 2020-2023  润新知