响应

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);
    }
}

  

  

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/faded8679/p/14208881.html