• 响应


    1 响应对象

    1.1 响应对象概述

    1.1.1 关于响应

    响应,它表示了服务器端收到请求,同时也已经处理完成,把处理的结果告知用户。简单来说,指的就是服务器把请求的处理结果告知客户端。在B/S架构中,响应就是把结果带回浏览器。

    响应对象,顾名思义就是用于在JavaWeb工程中实现上述功能的对象。

    1.1.2 常用响应对象

    响应对象也是是Servlet规范中定义的,它包括了协议无关的和协议相关的。

    协议无关的对象标准是:ServletResponse接口

    协议相关的对象标准是:HttpServletResponse接口

    类结构图如下:

    我们课程中涉及的响应对象都是和HTTP协议相关的。即使用的是HttpServletResponse接口的实现类。

    这里有些同学可能会产生疑问,我们在使用Servlet时,需要定义一个类,然后实现Servlet接口(或者继承它的实现类)。现在我们想要实现响应功能,要不要定义一个类,然后实现HttpServletResponse接口呢?

    此问题的答案是否定的,我们无需这么做。我们只需要在自己写的Servlet中直接使用即可,因为这个对象的实现类是由Tomcat提供的,无须我们自定义。同时它还会帮我们把对象创建出来并传入doGet和doPost方法中。

    1.2 常用方法介绍

    在HttpServletResponse接口中提供了很多方法,接下来我们通过API文档,来了解一下这些方法。

    常用状态码:

    状态码说明
    200 执行成功
    302 它和307一样,都是用于重定向的状态码。只是307目前已不再使用
    304 请求资源未改变,使用缓存。
    400 请求错误。最常见的就是请求参数有问题
    404 请求资源未找到
    405 请求方式不被支持
    500 服务器运行内部错误

    状态码首位含义:

    状态码说明
    1xx 消息
    2xx 成功
    3xx 重定向
    4xx 客户端错误
    5xx 服务器错误

    1.3 响应对象的使用示例

    1.3.1 响应-字节流输出中文问题

    返回值                                方法名        说明

    ServletOutputStream  getOutputStream()  获取响应字节输出流对象

    void          setContentType("text/html";charset="utf-8")   设置响应内容类型,解决中文乱码问题

    package com.itheima.Servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.nio.charset.StandardCharsets;
    
    /*
    * 字节流响应消息

    * 问题:
    * String str = "字节流中文乱码问题";
    * 使用字节流输出,会不会产生中文乱码?
    * 答案:
    * 会产生乱码
    * 原因:
    * String str = "字节流中文乱码问题"; 在保存时用的是IDEA创建文件使用的字符集UTF-8。
    * 到浏览器上显示,chrome浏览器和ie浏览器默认的字符集是GB2312(其实就是GBK),存和取用的不是同一个码表,就会产生乱码。
    *
    * 引申:
    * 如果产生了乱码,就是存和取用的不是同一个码表
    * 解决办法:
    * 把存和取的码表统一。
    */

    * */
    @WebServlet("/servletDemo01")
    public class ServletDemo01 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html;charset=UTF-8");
            //获取字节输出流对象
            ServletOutputStream os = resp.getOutputStream();
            //定义一个消息
            String str="你好";
            //通过字节流对象输出
            os.write(str.getBytes("utf-8"));
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

      字符流响应消息

    返回值                                方法名        说明

    PrintWriter      getWriter()    获取响应字符输出流对象

    void         setContentType("text/html;charset=utf-8")  设置响应内容类型,解决中文乱码问题

    1.3.2 响应-字符流输出中文问题

    package com.itheima.Servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /*
    * 字符流响应消息
    *
     */
    @WebServlet("/servletDemo02")
    public class ServletDemo02 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html;charset=UTF-8");
            //获取到字符输出流对象
            PrintWriter pw = resp.getWriter();
            //准备一个消息
            String str="你好";
            //通过字符流输出
            pw.write(str);
    
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

     响应图片

    1.创建字节输入流对象,关联读取的图片路径

    2.通过响应对象获取字节输出流对象

    3.循环读取和写出图片

    package com.itheima.Servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /*
    * 响应图片
    *
     */
    @WebServlet("/servletDemo03")
    public class ServletDemo03 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //通过文件的相对路径获取绝对路径
            String realPath = getServletContext().getRealPath("/img/Request.png");
            System.out.println(realPath);
            //创建字节输入流对象,关联图片路径
    
            BufferedInputStream bis=new BufferedInputStream(new FileInputStream(realPath));
            //通过响应对象获取字节输出流对象
            ServletOutputStream os = resp.getOutputStream();
            //循环读写操作
            byte[] arr=new byte[1024];
            int len;
            while((len=bis.read(arr))!=-1){
                os.write(arr,0,len);
            }
            //释放资源
            bis.close();
    
    
    
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

      设置缓存:

    缓存:对于不经常变化的数据,我们可以设置合理缓存时间,以避免浏览器频繁请求服务器 ,以此来提高效率!

    返回值                                方法名        说明 

    void       setDateHeader(String name,long time)  设置  消息头,添加缓存

     

    package com.itheima.Servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    /*
    * 设置缓存
    *
     */
    @WebServlet("/servletDemo04")
    public class ServletDemo04 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String news="这是一条很火爆的新闻";
            //设置缓存   1小时的缓存时间
            resp.setDateHeader("Expires",System.currentTimeMillis()+1*60*60*1000);
    
    
    
    
            //设置编码的格式
            resp.setContentType("text/html;charset=UTF-8");
            //写出数据
            resp.getWriter().write(news);
    
            System.out.println("aaa");
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

     定时刷新:过了指定时间后,页面自动进行跳转

    返回值                                方法名        说明

    void      setHeader(String name,String value)  设置消息头定时刷新

    package com.itheima.Servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /*
    * 定时刷新
    *
     */
    @WebServlet("/servletDemo05")
    public class ServletDemo05 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String str="您的用户名或密码有误,三秒后自动跳转到登陆页面";
    
            resp.setContentType("text/html;charset=utf-8");
            //写出数据
            resp.getWriter().write(str);
            //定时刷新
            resp.setHeader("Refresh","3,URL=/response/login.html");
    
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    1.3.6 请求重定向:注意地址栏发生改变。

    客户端的一次请求到达后,发现需要借助其他Servlet来实现功能

    特点:浏览器地址栏会发生改变,两次请求,请求域对象中不能共享数据,可以重定向到其他服务器。

    重定向的实现原理

      设置响应状态码为302  resp.setStatus(302);

      设置相应的资源路径(响应到哪里去,通过响应消息头location来指定)

      resp.setHeader("location","response/responseDemo07")

    响应对象重定向方法

    返回值                                方法名        说明  

    void      sendRedirect(String name)   设置重定向

    ResponseDemo6

    package com.itheima.Servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /*
    * 请求重定向
    *
     */
    @WebServlet("/servletDemo06")
    public class ServletDemo06 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("servletDemo06执行了");
            //设置请求共享数据
            req.setAttribute("username","张三");
    
            //设置重定向
            resp.sendRedirect(req.getContextPath()+"/servletDemo07");
    
    
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    ResponseDemo7  

    public class ResponseDemo7 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.getWriter().write("welcome to ResponseDemo7");
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    

    1.3.3 响应-生成验证码

    package com.itheima.Servlet;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    
    /*
    * 图片显示验证码
    *
     */
    @WebServlet("/servletDemo08")
    public class ServletDemo08 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            int width=200;
            int height=35;
            /*
            * 1.创建图像内存对象
            * 2.拿到画笔
            * 3.设置颜色,画矩形边框
            * 4.设置颜色,填充矩形
            * 5.设置颜色,画干扰线
            * 6.设置颜色,画验证码
            * 7.把内存图像输出到浏览器上
            * */
            //创建内存图像
            BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//参数:宽度,高度(指的都是像素),使用的格式(RGB)
            Graphics g=image.getGraphics();//画笔就一根
            //设置颜色
            g.setColor(Color.BLUE);
            //画边框
            g.drawRect(0,0,width,height);
            //设置颜色
            g.setColor(Color.GRAY);
            //填充矩形
            g.fillRect(1,1,width-2,width-2);
            //设置颜色
            g.setColor(Color.WHITE);
            //那随机数对象
            Random r=new Random();
            //话干扰线10条
            for (int i = 0; i < 10; i++) {
                g.drawLine(r.nextInt(width),r.nextInt(height),r.nextInt(width),r.nextInt(height));
            }
            //设置颜色
            g.setColor(Color.red);
            //改变字体大小
            Font font=new Font("宋体",Font.BOLD,30);
            g.setFont(font);//设置字体
            //画验证码  4个
            int x=35;
            for (int i = 0; i < 4; i++) {
                g.drawString(String.valueOf(10),x,25);
                x+=35;
            }
            //输出到浏览器上
            //参数:1.内存对象。2.输出的图片格式。3.使用额输出流
            ImageIO.write(image,"jpg",resp.getOutputStream());
    
    
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

      

    1.3.7 响应和消息头组合应用-文件下载

    1.创建字节输入流,关联 读取的文件

    2.设置响应消息头支持的类型

    3.设置响应消息头以下载方式打开资源

    4.通过响应对象获取字节输出流对象

    5.循环读写

    6.释放资源

    package com.itheima.Servlet;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Random;
    
    /*
    * 下载文件
    *
     */
    @WebServlet("/servletDemo09")
    public class ServletDemo09 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           //1.创建字节输入流,关联 读取的文件
            String realPath = getServletContext().getRealPath("/img/Request.png");
            BufferedInputStream bis=new BufferedInputStream(new FileInputStream(realPath));
            /*
            * Content-Type  消息头名称  支持的类型
            * application/octet-stream 消息头参数  应用的类型为字节流
            * */
    
            //2.设置响应消息头支持的类型
            resp.setHeader("Content-Type","application/octet-stream");
            //3.设置响应消息头以下载方式打开资源
            /*
            * Content-Disposition 消息头名称  处理的形式
            * attachment;filename=Request.png  消息头参数  附件形式进行处理 指定下载文件的名称
            * */
            resp.setHeader("Content-Disposition","attachment;filename=Request.png");
            //4.通过响应对象获取字节输出流对象
            ServletOutputStream os = resp.getOutputStream();
            //5.循环读写
            byte []arr=new byte[1024];
            int len;
            while((len= bis.read(arr))!=-1){
                os.write(arr,0,len);
            }
            //6.释放资源
            bis.close();
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

      

      

     

     

     

     

     

     

     

     

  • 相关阅读:
    [PA2014]Muzeum
    [TJOI2015]概率论
    To Do List
    【洛谷4172】 [WC2006]水管局长(LCT)
    HNOI2019退役记
    hdu 2159 FATE
    USACO 2019 January Contest, Platinum 题解
    luogu4774 [NOI2018]屠龙勇士
    NOI 2019游记
    loj #3145. 「APIO 2019」桥梁
  • 原文地址:https://www.cnblogs.com/faded8679/p/14208881.html
Copyright © 2020-2023  润新知