• Http响应response(文件下载、验证码)


    Http响应response

    response:响应

    作用:   往浏览器写东西
    组成部分: 响应行 响应头 响应体
    操作响应行 格式: 协议
    /版本 状态码 状态码说明
    状态码:
        1xx:已发送请求
        2xx:已完成响应
            200:正常响应
        3xx:还需浏览器进一步操作
            302:重定向 配合响应头:location
            304:读缓存
        4xx:用户操作错误
            404:用户操作错误.
            405:访问的方法不存在
        5xx:服务器错误
            500:内部异常
    常用方法:
        setStatus(int 状态码):针对于 1xx  2xx  3xx 
    
    了解 :sendError(int 状态码):针对于 4xx和5xx

    操作响应头
      格式:   key:value(value可以是多个值)

    常用的方法:
        setHeader(String key,String value):设置字符串形式的响应头
        了解:setIntHeader(String key,int value):设值整形的响应头
        了解:setDateHeader(String key,long value):设值时间的响应头
                
        addHeader(String key,String value):添加字符串形式的响应头 之前设置过则追加,若没有设置过则设置
        了解:addIntHeader(String key,int value):添加整形的响应头
        了解:addDateHeader(String key,long value):添加时间的响应头
    常用的响应头:
        location:重定向
        refresh:定时刷新
        content-type:设置文件的mime类型,设置响应流的编码及告诉浏览器用什么编码打开
        content-disposition:文件下载
    重定向:    
        方式1:
            ★response.sendRedirect("/day10/loc2");
        方式2:
            response.setStatus(302);
            respooen.setHeader("location","/day10/loc2");

    案例1:请求重定向

    web.xml文件配置

    <servlet>
          <servlet-name>SHServlet1</servlet-name>
          <servlet-class>com.hjh.request_response.SHServlet1</servlet-class>
      </servlet>
      <servlet-mapping>
          <servlet-name>SHServlet1</servlet-name>
          <url-pattern>/servlet1</url-pattern>
      </servlet-mapping>
    <servlet>
        <servlet-name>SHServlet2</servlet-name>
        <servlet-class>com.hjh.request_response.SHServlet2</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>SHServlet2</servlet-name>
        <url-pattern>/servlet2</url-pattern>
      </servlet-mapping>

    SHServlet1.java源码

    package com.hjh.request_response;
    
    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 SHServlet1 extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                //重定向方式一
            //1.设置状态码
            response.setStatus(302);
            //2.设置响应头
            //response.setHeader("location", "/Servlet/servlet2");
            
            
            //重定向方式二:设置响应头
            response.sendRedirect("/Servlet/servlet2");   
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    SHServlet2.java源码:

    package com.hjh.request_response;
    
    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 SHServlet2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().print("跳转到这里啦,哈哈哈");
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    项目运行,在浏览器中输入“http://localhost:8080/Servlet/servlet1”,回车,url变为“http://localhost:8080/Servlet/servlet2”,浏览网页输出为:“跳转到这里啦,哈哈哈”

    定时刷新:
        方案1:设置头 refresh 
            respooen.setHeader("refresh","秒数;url=跳转的路径");
        方案2:http的meta标签
            <meta http-equiv="refresh" content="3;url=/day10/refresh2.html">

     案例参见servlet博文:https://www.cnblogs.com/hejh/p/10942445.html

    package com.hjh.servlet;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import com.hjh.domain.User;
    import com.hjh.service.UserService;
    
    public class LoginServlet extends HttpServlet {
    
        private static final long serialVersionUID = 1L;
        
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1.设置编码
            response.setContentType("text/html;charset=utf-8");
            
            //2.接收用户名和密码
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            
            //3.调用UserService的login(username,password),返回一个user对象
            User user  = new UserService().login(username,password);
            
            //4.判断user是否为空
            if(user==null) {
                //user为空
                response.getWriter().print("用户名和密码不匹配,3秒后跳转");
                //优化,定时跳转
                response.setHeader("refresh","3;url=/Servlet/login.html");
            }else {
                //user为不为空
                response.getWriter().print(user.getUsername()+":欢迎回来");
            }    
        }    
    }

    案例二:

    refresh1.html:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    
    <!-- 
        http-equiv:响应头
        content:响应体
     -->
    <meta  http-equiv="refresh" content="3;url=/Servlet/refresh2.html" >
    
    <title>注册页面</title>
    </head>
    <body>
        注册成功,<span id="sid">5</span>秒之后跳转到登录页面
    </body>
    
    <script type="text/javascript">
        onload=function(){
            //设置定时器
            setInterval(changeS,1000);
        }
        i=5;
        function changeS(){
            //1.获取元素
            var obj = document.getElementById("sid");
            //2.操作元素的标签体
            obj.innerHTML=--i;
        }    
    </script>
    
    </html>

    refresh2.html:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    </head>
    <body>
        访问前,请先进行登录!
    </body>
    </html>

    启动项目,在浏览器中输入“http://localhost:8080/Servlet/refresh1.html”,回车,页面显示显示:

    页面上时间会自减,5秒后页面跳转到refresh2.html

    操作响应体:页面上要展示的内容
        常用方法:
            Writer getWriter():字符流
            ServletOutputStream getOutputStream() :字节流
                
            自己写的东西用字符流,其他一概用字节流.
                
        处理响应中文乱码:
            方式1:★
                response.setContentType("text/html;charset=utf-8");
            方式2:理解
                response.setHeader("content-type", "text/html;charset=utf-8");
    注意:
        两个流互斥。当响应完成之后,服务器会判断一下流是否已经关闭,若没有关闭,服务器会帮我们关闭.(底层使用的缓冲流)

    案例:

    web.xml配置信息如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <servlet>
        <servlet-name>PrintServlet</servlet-name>
        <servlet-class>com.hjh.servlet.PrintServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>PrintServlet</servlet-name>
        <url-pattern>/print</url-pattern>
      </servlet-mapping>
    </web-app>

    PrintServlet.java源码如下:
    package com.hjh.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class PrintServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //处理响应的中文乱码
            response.setContentType("text/html;charset=utf-8");
            
            //打印表格
            //获取字符流
            PrintWriter writer = response.getWriter();
            writer.print("<table border='1'><tr>");
            writer.print("<td>用户名:</td>");
            writer.print("<td>tom</td></tr>");
            writer.print("<tr><td>密码:</td>");
            writer.print("<td>123</td>");
            writer.print("</tr></table>");    
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

     在没有红色标注的这段代码时,启动项目访问,浏览器中显示的是以下数据:

    在加上红色标注的代码时,启动项目访问,浏览器中显示的是以下数据:

     

     文件下载:

    下载方式:
            1.超链接下载
                <a href="/day10/download/day10.txt">下载 day10.txt</a>
                若浏览器能解析该资源的mime类型,则打开;若不能接下则下载;
    2.编码下载 通过servlet完成 <a href="/day10/download?name=day10.txt">下载 day10.txt</a> a.设置文件的mime类型 String mimeType=context.getMimeType(文件名) response.setContentType(mimeType); b.设置下载头信息 content-disposition response.setHeader("content-disposition", "attachment;filename="+文件名称); c.提供流 response.getOutputStream();

    1.超链接下载文件:

     download.html内容如下:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>超链接文件下载</title>
    </head>
    <body>
        <a href='/Servlet/file/1.html'>1.html</a>
        <a href='/Servlet/file/2.txt'>2.txt</a>
        <a href='/Servlet/file/3.docx'>3.docx</a>
    </body>
    </html>

    启动项目,浏览器中输入url回车,页面显示如下:

     

    点击1.html这个超链接,浏览器能够识别html的文件类型,所以将1.html文件内容显示在浏览器中,页面显示如下:

    点击2.txt这个超链接,浏览器能够识别txt的文件类型,所以将2.txt文件内容显示在浏览器中,页面显示如下:

     

    点击3.docx这个超链接,浏览器无法识别docx的文件类型,浏览器中弹出选择下载保存位置,页面显示如下:

     

    案例二:编码下载,通过servlet实现

    download2.html:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>超链接文件下载</title>
    </head>
    <body>
        <a href="/Servlet/download?name=1.html">1.html</a><br/>
        <a href="/Servlet/download?name=2.txt">2.txt</a><br/>
        <a href="/Servlet/download?name=3.docx">3.docx</a><br/>
    </body>
    </html>

     DownloadServlet.java源码:

    package com.hjh.servlet;
    
    import java.io.IOException;
    import java.io.InputStream;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class DownloadServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取当前下载文件的文件名
            String fileName = request.getParameter("name");
            System.out.println(fileName);
            
            //获取上下文
            ServletContext context = this.getServletContext();
            
            //文件下载
            //1.首先获取文件的mime类型,并设置其类型
            String mimeType = context.getMimeType(fileName);
            response.setContentType(mimeType);
            //2.设置下载的头信息
            response.setHeader("content-disposition", "attchment;filename="+fileName);
            
            //3.对拷流
            //3.1获取输入流
            InputStream is = context.getResourceAsStream("/file/"+fileName);
            //3.2获取输出流
            ServletOutputStream os = response.getOutputStream();
            int len = -1;
            byte[] b = new byte[1024];
            while((len=is.read(b))!=-1) {
                os.write(b, 0,len);
            }
            //关闭流
            os.close();
            is.close();
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

     web.xml配置:

     <servlet>
        <servlet-name>DownloadServlet</servlet-name>
        <servlet-class>com.hjh.servlet.DownloadServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>DownloadServlet</servlet-name>
        <url-pattern>/download</url-pattern>
      </servlet-mapping>

     启动项目,浏览器中输入url,回车,页面显示如下:

     

    点击1.html、2.txt、3.docx超链接,浏览器中弹出选择下载保存位置,页面显示如下:

     

    文件下载优化:解决文件名带中文

      download.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>超链接文件下载</title>
    </head>
    <body>
        <a href='/Servlet/file/1a.html'>1a.html</a>
        <a href='/Servlet/file/2.txt'>2.txt</a>
        <a href='/Servlet/file/3答案.docx'>3答案.docx</a>
    </body>
    </html>

      工具类DownLoadUtils.java源码:

    package com.hjh.util;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    import sun.misc.BASE64Encoder;
    
    public class DownLoadUtils {
        public static String getName(String agent, String filename) throws UnsupportedEncodingException {
            if (agent.contains("MSIE")) {
                // IE浏览器
                filename = URLEncoder.encode(filename, "utf-8");
                filename = filename.replace("+", " ");
            } else if (agent.contains("Firefox")) {
                // 火狐浏览器
                BASE64Encoder base64Encoder = new BASE64Encoder();
                filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
            } else {
                // 其它浏览器
                filename = URLEncoder.encode(filename, "utf-8");
            }
            return filename;
        }
    }

      DownloadServlet.java源码:

    package com.hjh.servlet;
    
    import java.io.IOException;
    import java.io.InputStream;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.io.IOUtils;
    import com.hjh.util.DownLoadUtils;
    
    public class DownloadServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取当前下载文件的文件名
            String fileName = request.getParameter("name");
            //System.out.println(fileName);
            
            //解决文件下载文件名带中文问题,方式1
            fileName = new String(fileName.getBytes("iso8859-1"),"utf-8");
            
            //获取上下文
            ServletContext context = this.getServletContext();
            
            //文件下载
            //1.首先获取文件的mime类型,并设置其类型
            String mimeType = context.getMimeType(fileName);
            response.setContentType(mimeType);
            //2.设置下载的头信息
            response.setHeader("content-disposition", "attachment;filename="+fileName);
            
            //通过工具类编码;解决文件下载文件名带中文问题,方式2
            //String filename = DownLoadUtils.getName(request.getHeader("user-agent"), fileName);
            //response.setHeader("content-disposition", "attachment;filename="+filename);
            
            //3.对拷流
            //3.1获取输入流
            InputStream is = context.getResourceAsStream("/file/"+fileName);//方式2,fileName应改为filename
            //3.2获取输出流
            ServletOutputStream os = response.getOutputStream();
            
    //        int len = -1;
    //        byte[] b = new byte[1024];
    //        while((len=is.read(b))!=-1) {
    //            os.write(b, 0,len);
    //        }
            
            IOUtils.copy(is, os);
                
            //关闭流
            os.close();
            is.close();
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    代码优化:引入commons-io-1.4.jar包

     在代码中以下面红色部分代码替代黄色部分代码:

    IOUtils.copy(is, os);

    代替

       int len = -1;
        byte[] b = new byte[1024];
        while((len=is.read(b))!=-1) {
         os.write(b, 0,len);
      }

    案例:验证码

      web.xml配置:

    <servlet>
        <servlet-name>CodeServlet</servlet-name>
        <servlet-class>com.hjh.servlet.CodeServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>CodeServlet</servlet-name>
        <url-pattern>/code</url-pattern>
      </servlet-mapping>

      code.html:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>验证码</title>
    </head>
    <body>
        <img alt="验证码" src="/Servlet/code" title="看不清,换一张" onclick="changeImg(this)">
    </body>
    <script type="text/javascript">
        function changeImg(obj){
            //操作src属性
            obj.src="/Servlet/code?i="+Math.random();
        }
    </script>
    </html>

    CodeServlet.java源码:

    package com.hjh.servlet;
    
    import javax.servlet.http.HttpServlet;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class CodeServlet extends HttpServlet {
    
        private static final long serialVersionUID = 1L;
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
    
                // 使用java图形界面技术绘制一张图片
    
                int charNum = 4;
                int width = 30 * 4;
                int height = 30;
    
                // 1. 创建一张内存图片
                BufferedImage bufferedImage = new BufferedImage(width, height,
                        BufferedImage.TYPE_INT_RGB);
    
                // 2.获得绘图对象
                Graphics graphics = bufferedImage.getGraphics();
    
                // 3、绘制背景颜色
                graphics.setColor(Color.YELLOW);
                graphics.fillRect(0, 0, width, height);
    
                // 4、绘制图片边框
                graphics.setColor(Color.BLUE);
                graphics.drawRect(0, 0, width - 1, height - 1);
    
                // 5、输出验证码内容
                graphics.setColor(Color.RED);
                graphics.setFont(new Font("宋体", Font.BOLD, 20));
    
                // 随机输出4个字符
                Graphics2D graphics2d = (Graphics2D) graphics;
                 String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789";
                Random random = new Random();
                //session中要用到
                String msg="";
                int x = 5;
                for (int i = 0; i < 4; i++) {
                    int index = random.nextInt(32);
                    String content = String.valueOf(s.charAt(index));
                    msg+=content;
                    double theta = random.nextInt(45) * Math.PI / 180;
                    //让字体扭曲
                    graphics2d.rotate(theta, x, 18);
                    graphics2d.drawString(content, x, 18);
                    graphics2d.rotate(-theta, x, 18);
                    x += 30;
                }
    
                // 6、绘制干扰线
                graphics.setColor(Color.GRAY);
                for (int i = 0; i < 5; i++) {
                    int x1 = random.nextInt(width);
                    int x2 = random.nextInt(width);
    
                    int y1 = random.nextInt(height);
                    int y2 = random.nextInt(height);
                    graphics.drawLine(x1, y1, x2, y2);
                }
    
                // 释放资源
                graphics.dispose();
    
                // 图片输出 ImageIO
                ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
            }
        
        public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            doGet(request, response);
        }
    }

    启动项目,输入url,回车,页面显示如下,点击二维码区域,二维码刷新:

  • 相关阅读:
    02.简单的DOM操作
    03.获取和设置元素特性的值
    异常为"当IDENTITY_INSERT设置为OFF时" 的解决
    GridView的RowCommand事件中取得行索引 技巧
    01.判断页面加载完成的方法
    今天新开了博客园
    C#巧用anchor和dock设计复杂界面(控件随着窗体大小的变化而变化)
    C#如何使用webbrowser控件制作一个简易的IE浏览器(菜鸟级)
    断箭——不相信自己的意志,永远也做不成将军
    成长与成功
  • 原文地址:https://www.cnblogs.com/hejh/p/10968645.html
Copyright © 2020-2023  润新知