zoukankan      html  css  js  c++  java
  • HttpServletResponse、页面文件下载、验证码

    summarize

    在创建Servlet时,会覆盖service方法或doGet()/doPost(),它俩都是 HTTPServletresponse这些方法都有俩参数,一个是请求request,一个是响应response,HttpServletResponseServletResponset的子接口,

    浏览器发出http请求,会直接传给Tomcat,Tomcat将请求的信息封装成request,和response 传给web,这时的response是空的,web调用write方法将内容存到缓冲区,此时,Tomcat从response里获取设置的内容组装成一个http响应(行、头、体)回写给客户端

    响应行只能设置状态码

    重定向特点:请求服务器两次,地址栏变化

    location:

    HttpServletResponse

    response运行流程图

    通过response设置响应行

    设置响应行的状态码setStatus(int sc)

    package com.oracle.demo01;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class HeadServlet
     */
    public class HeadServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;       
        /**
         * @see HttpServlet#HttpServlet()
         */
        public HeadServlet() {
            super();
        }
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //        设置响应头中的状态码
            response.setStatus(404);        
        }
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    重定向:1.状态码:302  + 2 .响应头:Location
    其实请求了两次 但客户端只做了一次请求

    原理图

    package com.oracle.demo01;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Servlet01 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*//        设置响应状态码
            response.setStatus(302);
    //        设置响应头中的Location  
            response.setHeader("Location","/WEB05/Servlet02");*/
            
    //        重定向 sendRedirect方法  下面这一句话就等于上面两句话
            response.sendRedirect("/WEB05/Servlet02");
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }
    ----------------------------------------------
    package com.oracle.demo01;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Servlet02 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().write("Servlet02");
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    通过response设置响应头

    package com.oracle.demo01;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class RefreshServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //        设置定时刷新的头
            response.setHeader("Refresh","5;url=https://www.baidu.com");
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    用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>
    <script type="text/javascript">
        window.onload=function(){
            //获取span元素
            var second=document.getElementById("second");
            //定义秒数
            var time=5;
            //设置定时器
            var timer=setInterval(function(){
                //获得元素里面的文本节点
                second.innerHTML=time;
                time--;
                if(time<0){
                    clearInterval(timer);
                    location.href="http://www.baidu.com";
                }
            },1000);
        }    
    </script>
    </head>
    <body>
        恭喜你,注册成功!
        <span id="second" style="color:red">5</span>
        秒后跳转,如没跳转,请点击
        <a href="http://www.baidu.com">这里</a>
    </body>
    </html>

     通过response设置响应体

    (1)响应体设置文本

    PrintWriter getWriter()

    获得字符流,通过字符流的write(String s)方法可以将字符串设置到response   缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端

    package com.oracle.demo01;
    //设置码表让页面显示中文
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class BodyServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*//        设置缓冲区编码表
            response.setCharacterEncoding("UTF-8");
    //        设置客户端浏览器使用的码表
            response.setHeader("Content-Type","text/html;charset=utf-8");*/
    //        解决响应的中文乱码问题 用一个犯法就可以 代替上面两句话
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("中国");
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

     创建一个download.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>
        <a href="/WEB05/download/a.png">a.png</a>
        <a href="/WEB05/download/a.txt">a.txt</a>
        <a href="/WEB05/download/a.zip">a.zip</a>
    </body>
    </html>

    (1)响应头设置字节

    ServletOutputStream  getOutputStream()

    获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字 节,在由Tomcat服务器将字节内容组成Http响应返回给浏览器。

    2.案例-完成文件下载

    文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。所以文件下载需     要IO技术将服务器端的文件使用InputStream读取到,在使用    ServletOutputStream写到response缓冲区中

    代码如下:

    上述代码可以将图片从服务器端传输到浏览器,但浏览器直接解析图片显示在页面上,  而不是提供下载,需要设置两个响应头,告知浏览器文件的类型和文件的打开方 式

    1)告知浏览器文件的类型:response.setContentType(文件的MIME类型);

    2)告示浏览器文件打开方式下载response.setHeader("Content-Disposition","attachment;filename=文件名称");

    //            告知浏览器文件的类型
                response.setContentType(getServletContext().getMimeType(filenameEncoder));
    //            告知浏览器以附件的方式提供下载功能 而不是解析
    //            Content-Disposition:设置用什么方式打开  attachment:代表附件
    response.setHeader("Content-Disposition","attachment;filename="+filenameEncoder);

    3)解决中文名显示乱码问题

    //        获取文件名
            String filename=request.getParameter("file");//??.png
    //        解决文件名中文乱码问题
            filename=new String(filename.getBytes("ISO-8859-1"),"UTF-8");//乱码.png
    //        获取User-Agent获取客户端浏览器是哪个浏览器 
            String agent=request.getHeader("User-Agent");
            String filenameEncoder="";
            if (agent.contains("MSIE")) {
                    // IE浏览器
                    filenameEncoder= URLEncoder.encode(filename, "utf-8");
                    filenameEncoder= filenameEncoder.replace("+", " ");
            } else if (agent.contains("Firefox")) {
                    // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
                    filenameEncoder= "=?utf-8?B?"
                            + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
            } else {
                    // 其它浏览器
                    filenameEncoder= URLEncoder.encode(filename, "utf-8");                
            }
    //            告知浏览器文件的类型
                response.setContentType(getServletContext().getMimeType(filenameEncoder));
    //            告知浏览器以附件的方式提供下载功能 而不是解析 
    //            Content-Disposition:设置用什么方式打开  attachment:代表附件
                response.setHeader("Content-Disposition","attachment;filename="+filenameEncoder);

    全部代码

    <%@ 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>
        <a href="/WEB05/DownLoadServlet?file=a.png">a.png</a>
        <a href="/WEB05/DownLoadServlet?file=a.txt">a.txt</a>
        <a href="/WEB05/DownLoadServlet?file=a.zip">a.zip</a>
    </body>
    </html>
    ---------------------------------------
    package com.oracle.demo02;
    //页面文件下载 显示中文
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.net.URLEncoder;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import sun.misc.BASE64Encoder;
    
    public class DownLoadServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //        获取文件名
            String filename=request.getParameter("file");//??.png
    //        解决文件名中文乱码问题
            filename=new String(filename.getBytes("ISO-8859-1"),"UTF-8");//乱码.png
    //        获取User-Agent获取客户端浏览器是哪个浏览器 
            String agent=request.getHeader("User-Agent");
            String filenameEncoder="";
            if (agent.contains("MSIE")) {
                    // IE浏览器
                    filenameEncoder= URLEncoder.encode(filename, "utf-8");
                    filenameEncoder= filenameEncoder.replace("+", " ");
            } else if (agent.contains("Firefox")) {
                    // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
                    filenameEncoder= "=?utf-8?B?"
                            + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
            } else {
                    // 其它浏览器
                    filenameEncoder= URLEncoder.encode(filename, "utf-8");                
            }
    //            告知浏览器文件的类型
                response.setContentType(getServletContext().getMimeType(filenameEncoder));
    //            告知浏览器以附件的方式提供下载功能 而不是解析
                response.setHeader("Content-Disposition","attachment;filename="+filenameEncoder);
    //        获取字节输出流
            ServletOutputStream sos=response.getOutputStream();
    //        获取数据源绝对路径
            String realpath=getServletContext().getRealPath("download/"+filename);
    //        获取字节输入流
            FileInputStream fis=new FileInputStream(realpath);
    //        开始复制
            byte[] bytes=new byte[1024];
            int len=0;
            while((len=fis.read(bytes))!=-1){
                sos.write(bytes,0,len);
            }
    //        释放资源
            fis.close();
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    生成验证码

     这是一个写好的  验证码代码

    package com.oracle.demo02;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 验证码生成程序
     * 
     * 
     * 
     */
    public class CheckImgServlet extends HttpServlet {
    
        // 集合中保存所有成语
        private List<String> words = new ArrayList<String>();
    
        @Override
        public void init() throws ServletException {
            // 初始化阶段,读取new_words.txt
            // web工程中读取 文件,必须使用绝对磁盘路径
            String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
            try {
    //            读取这个文件
                BufferedReader reader = new BufferedReader(new FileReader(path));
                String line;
                while ((line = reader.readLine()) != null) {
                    words.add(line);
                }
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 禁止缓存
            // response.setHeader("Cache-Control", "no-cache");
            // response.setHeader("Pragma", "no-cache");
            // response.setDateHeader("Expires", -1);
    
            int width = 120;
            int height = 30;
    
            // 步骤一 绘制一张内存中图片
            BufferedImage bufferedImage = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
    
            // 步骤二 图片绘制背景颜色 ---通过绘图对象
            Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
            // 绘制任何图形之前 都必须指定一个颜色
            graphics.setColor(getRandColor(200, 250));
            graphics.fillRect(0, 0, width, height);
    
            // 步骤三 绘制边框
            graphics.setColor(Color.WHITE);
            graphics.drawRect(0, 0, width - 1, height - 1);
    
            // 步骤四 四个随机数字
            Graphics2D graphics2d = (Graphics2D) graphics;
            // 设置输出字体
            graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
    
            Random random = new Random();// 生成随机数
            int index = random.nextInt(words.size());
            String word = words.get(index);// 获得成语
    
            // 定义x坐标
            int x = 10;
            for (int i = 0; i < word.length(); i++) {
                // 随机颜色
                graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
                        .nextInt(110), 20 + random.nextInt(110)));
                // 旋转 -30 --- 30度
                int jiaodu = random.nextInt(60) - 30;
                // 换算弧度
                double theta = jiaodu * Math.PI / 180;
    
                // 获得字母数字
                char c = word.charAt(i);
    
                // 将c 输出到图片
                graphics2d.rotate(theta, x, 20);
                graphics2d.drawString(String.valueOf(c), x, 20);
                graphics2d.rotate(-theta, x, 20);
                x += 30;
            }
    
            // 将验证码内容保存session
            request.getSession().setAttribute("checkcode_session", word);
    
            // 步骤五 绘制干扰线
            graphics.setColor(getRandColor(160, 200));
            int x1;
            int x2;
            int y1;
            int y2;
            for (int i = 0; i < 30; i++) {
                x1 = random.nextInt(width);
                x2 = random.nextInt(12);
                y1 = random.nextInt(height);
                y2 = random.nextInt(12);
                graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
            }
    
            // 将上面图片输出到浏览器 ImageIO
            graphics.dispose();// 释放资源        
            //将图片写到response.getOutputStream()中
            ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
        /**
         * 取其某一范围的color
         * 
         * @param fc
         *            int 范围参数1
         * @param bc
         *            int 范围参数2
         * @return Color
         */
        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);
        }
    }

    在配置一下 web.xml,因为这个验证码代码 没有配置过Servlet,所以从新配置,更改一下 name 和class就可以

    <servlet>
        <description></description>
        <display-name>CheckImgServlet</display-name>
        <servlet-name>CheckImgServlet</servlet-name>
        <servlet-class>com.oracle.demo02.CheckImgServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>CheckImgServlet</servlet-name>
        <url-pattern>/CheckImgServlet</url-pattern>
      </servlet-mapping>

    在导入已经写好的 验证码成语

    验证码生成程序 实现点击事件

    <%@ 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>
    <script type="text/javascript">
        function code(node){
            /* 这样请求每次都不一样 */
            node.src="/WEB05/CheckImgServlet?time="+new Date().getTime();
        }
    </script>
    </head>
    <body>
        <img alt="" src="/WEB05/CheckImgServlet" onClick="code(this)">
    </body>
    </html>
  • 相关阅读:
    wex5 实战 框架拓展之2 事件派发与data刷新
    wex5 实战 框架拓展之1 公共data组件(Data)
    wex5 实战 HeidiSQL 导入Excel数据
    wex5 实战 手指触屏插件 hammer的集成与优劣
    wex5 实战 登陆帐号更换与用户id一致性
    wex5 实战 用户点评与提交设计技巧
    wex5 实战 省市县三级联动与地址薄同步
    wex5 实战 wex5与js的组件关系与执行顺序(父子与先后)
    wex5 实战 单页模式下的多页面数据同步
    [BZOJ]4237: 稻草人
  • 原文地址:https://www.cnblogs.com/zs0322/p/11119782.html
Copyright © 2011-2022 走看看