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>
  • 相关阅读:
    Android获取两条线之间的夹角度数
    Android字体度量(FontMetrics)
    Android下如何计算要显示的字符串所占的宽度和高度
    Android 颜色渲染PorterDuff及Xfermode详解
    从输入URL到页面加载的全过程
    滚动优化
    常用的前端相关chrome插件
    DNS预解析prefetch
    资源预加载preload和资源预读取prefetch简明学习
    使用chrome开发者工具中的performance面板解决性能瓶颈
  • 原文地址:https://www.cnblogs.com/zs0322/p/11119782.html
Copyright © 2011-2022 走看看