1、关于响应

响应简单来说就是服务端收到了客户端的请求,把处理结果再发生回客户端。

Servlet中定义了协议相关的对象 ServletReponse 接口和协议无关的对象 HttpServletResponse 接口

2、常见状态码

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

状态码首位含义

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

3、常用方法

1)字节流响应消息
返回值方法名说明
ServletOutputStreamgetOutputStream()获取响应字节输出对象
voidserContentType("text/html;charset=UTF-8")设置响应内容类型,解决中午乱码问题

tips: 会存在乱码 idea的字符集是UTF-8 而chrome和ie浏览器默认字符集是GB2312

解决办法:

  1. 修改浏览器编码

  2. 向页面输出一个标签,设置字符集

     <meta http-equiv="content-type" content="text/html;charset=UTF-8">
    
  3. 设置响应消息头,告知浏览器响应正文的MIME类型和字符集

  4. 推荐办法,本质是设置一个响应头消息

@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取字节流输出对象
        ServletOutputStream outputStream = resp.getOutputStream();
        //2.定义一个消息
        String str = "你好 outputStream";
        //3.通过字节流对象输出 getBytes 默认根据系统平台选择编码格式 winds默认gbk
        //同时设置浏览器编码
        //outputStream.write(str.getBytes("UTF-8"));
        //未生效
        //outputStream.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes());
        //生效
        //resp.setHeader("Content-Type","text/html;charset=UTF-8");
        //推荐使用
        resp.setContentType("text/html;charset=UTF-8");
        outputStream.write(str.getBytes("UTF-8"));
    }
}
2)字符流响应消息
返回值方法名说明
PrintWritetgetWritet()获取响应字符输出对象
voidserContentType("text/html;charset=UTF-8")设置响应内容类型,解决中午乱码问题
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        //1.获取字节流输出对象
        PrintWriter writer = resp.getWriter();
        //2.定义一个消息
        String str = "你好 writer";
        //3.通过字符流对象输出
        writer.write(str);
    }
}

tips: resp.setContentType("text/html;charset=UTF-8"); 放在开头否则不生效

4、响应图片

@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 通过文件的相对路径获取绝对路径
        String realPath = getServletContext().getRealPath("/images/head.png");
        System.out.println(realPath);
        //1.创建字节输出流对象,关联图片路径
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(realPath));

        //2.通过响应对象获取字节输出流对象
        ServletOutputStream outputStream = resp.getOutputStream();
        //3.循环读取
        byte[] arr = new byte[1024];
        int len;
        while ((len = bufferedInputStream.read(arr)) != -1){
            outputStream.write(arr,0,len);
        }

    }
}

路径是关键

5、缓存

对于不常变化的资源,设置合理的缓存时间,可以避免频繁访问服务器,提升效率。

返回值方法名说明
voidsetDateHeader(String name,long time)设置消息头添加缓存

@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = "hello ";
        //设置编码格式
        resp.setContentType("text/html;charset=UTF-8");
        //设置缓存
        resp.setDateHeader("Expires",System.currentTimeMillis() + 60*60*1000);
        //写出数据
        resp.getWriter().write(name);
        //判断是否访问服务器
        System.out.println("servletDemo02");
    }
}
  1. Date:

Sat, 03 Sep 2022 01:25:02 GMT

  1. Expires:

Sat, 03 Sep 2022 02:25:02 GMT

6、定时刷新

过了指定时间,页面自动刷新

返回值方法名说明
voidsetHeader(String name,String value)设置消息头定时刷新
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = "三秒后跳转注册页面";
        //设置编码格式
        resp.setContentType("text/html;charset=UTF-8");
        //写出数据
        resp.getWriter().write(name);
        //定时刷新
        resp.setHeader("refresh","3;URL=/crm/regist.html");
    }
}

7、重定向

客户端接收到请求需要其他Servlet来完成

请求转发相比,浏览器地址会发生变化,请求域对象数据不能共享,可以重定向到其他服务器

重定向实现原理

  • 设置状态码为302
    • resp.setStatus(302);
  • 设置响应的资源路径(通过响应头location指定)
返回值方法名说明
voidsendRedirect(Srting name)设置重定向
public class PeopleServlet  extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("PeopleServlet");
        Object encoding = req.getAttribute("encoding");
        System.out.println(encoding+"people");
    }
}
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("servletDemo02");
        req.setAttribute("encoding","css");
        //req.getContextPath() 获取虚拟路径
        resp.sendRedirect(req.getContextPath()+"/peopleServlet");
    }
}

servletDemo02 PeopleServlet nullpeople

可以发现数据无法共享

8、文件下载

@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建字节输入流,关联读取的文件
        String realPath = getServletContext().getRealPath("/images/head.png");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(realPath));
        //设置响应消息头支持的类型
        resp.setHeader("Content-Type","application/octet-stream");
        //设置响应消息头以下载方式打开资源
        //attachment;filename=hm.png 消息头参数 附件形式进行处理 指定下载文件的名称
        resp.setHeader("Content-Disposition","attachment;filename=hm.png");
        //通过响应对象获取字节输出流对象
        ServletOutputStream outputStream = resp.getOutputStream();
        //循环读写
        byte[] arr = new byte[1024];
        int len;
        while ((len = bufferedInputStream.read(arr))!=-1){
            outputStream.write(arr,0,len);
        }
        //释放资源
        bufferedInputStream.close();
    }
}