HttpServletResponse(JAVAEE4)

HttpServletResponse

1.HttpServletResponse概述

服务器端发送给客户端的数据。 我们在创建Servlet时会覆盖service()⽅法,或doGet()/doPost(),这些⽅法都有两个参数,代表 请求的request和代表响应response。 service⽅法中的response的类型是ServletResponse,⽽doGet/doPost⽅法的response的类型 是HttpServletResponse,HttpServletResponse是ServletResponse的⼦接⼝,功能和⽅法更加 强⼤,所以我们学习HttpServletResponse。

2. response的运⾏流程

 3.通过抓包⼯具抓取Http响应

 因为response代表响应,所以我们可以通过该对象分别设置Http响应的响应⾏,响应头和响应体

4.通过response设置响应⾏

响应状态码:服务器告诉客户端浏览器本次请求和响应的⼀个状态。

  • 1. 1xx:服务器就收客户端消息,但没有接受完成,等待⼀段时间后,发送1xx多状态码
  • 2. 2xx:成功。代表:200
  • 3. 3xx:重定向。代表:302(重定向),304(访问缓存)
  • 4. 4xx:客户端错误 .。 代表: 404(请求路径没有对应的资源) 405:请求⽅式没有对应的doXxx⽅法
  • 5. 服务器端错误。代表:500(服务器内部出现异常)

设置响应⾏的状态码 :   setStatus(int sc)

5.通过response设置响应头

常⻅的响应头:

  • 1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
  • 2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据 in-line:默认值,在当前⻚⾯内打开 attachment;filename=xxx:以附件形式打开响应体。⽂件下载

设置响应头:可以设置也可以添加

  • addHeader(String name, String value)
  • addIntHeader(String name, int value)
  • addDateHeader(String name, long date)
  • setHeader(String name, String value)
  • setDateHeader(String name, long date)
  • setIntHeader(String name, int value) 其中,add表示添加,⽽set表示设置

6 通过response设置响应体

6.1 响应体设置⽂本

  • PrintWriter getWriter()
    获得字符流,通过字符流的write(String s)⽅法可以将字符串设置到response缓冲区中,随 后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
  • 关于设置中⽂的乱码问题
    原因:response缓冲区的默认编码是ISO8859-1,此码表中没有中⽂。 可以通过response的setCharacterEncoding(String charset) 设置response的编码(在 获取流之前设置)。
  • 但我们发现客户端还是不能正常显示⽂字
    原因:我们将response缓冲区的编码设置成UTF-8,但浏览器的默认编码是本地系统的编 码,因为我们都是中⽂系统,所以客户端浏览器的默认编码是GBK,我们可以⼿动修改浏览 器的编码是UTF-8。
  • 我们还可以在代码中指定浏览器解析⻚⾯的编码⽅式
    通过response的setContentType(String type)⽅法指定⻚⾯解析时的编码是UTF-8:
    上⾯的代码不仅可以指定浏览器解析⻚⾯时的编码,同时也内含 setCharacterEncoding 的 功能,所以在实际开发中只要编写response.setContentType("text/html;charset=UTF-8");就可以解决⻚⾯输出中⽂乱码问题
    response.setContentType("text/html;charset=UTF-8");

@WebServlet("/Demo1Servlet")
public class Demo1Servlet extends HttpServlet {
    //响应体
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应输出缓冲区的字符集
//        resp.setCharacterEncoding("UTF-8");
        //设置响应体(内容)类型 MIME类型 ,在web.xml找对应的类型 ,同时设置输出流的字符集
        resp.setContentType("text/html;charset=utf-8");
        //获得字符输出流(缓冲流)
        PrintWriter writer = resp.getWriter();
        //字符流的三种方法 ,tomcat帮我们刷新缓冲区,也不用关闭资源
        writer.print("hello ");
        writer.print("hello 你好");  //设置缓冲区字符集才不会乱码
        writer.println("javaweb ");
        writer.write("<h1>"+new Date()+"</h1>");
        writer.write("<h1>欢迎来到我的世界!</h1>");    //设置输出的响应体的类型 才会解释Html代码
        //模拟表格   ---原理
        Map<String , Date> map = Map.of("lucy",new Date(2021,8,4),
                "tom",new Date(2012,8,4),
                "jack",new Date(2020,8,4),
                "rose",new Date(2018,8,4) );
        writer.write("<table border='1' cellspacing='0' cellpadding='5'>");
        for(String name : map.keySet()){
            Date date = map.get(name);
            System.out.println(name+map.get("lucy"));
            writer.write("<tr><td>lucy</td><td>"+date+"</td></tr>");
        }
        writer.write("</table>");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

6.2 响应头设置字节

ServletOutputStream getOutputStream() 获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写⼊字节,再由 Tomcat服务器将字节内容组成Http响应返回给浏览器。

6.3 案例  - - 下载文件

@WebServlet("/downloadServlet")
public class downloadServlet extends HttpServlet {
    //文件下载
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获得要下载的文件的名字  - 是跟着文件请求的URL  - 在html中设置他的名字
        String filename = req.getParameter("filename");
        System.out.println("2,"+filename);
        //2.获得要下载的文件的绝对路径
        String path = this.getServletContext().getRealPath("/download/"+filename);
        System.out.println(path);
        //问题3[下载后的文件名乱码]  解决
        filename = URLEncoder.encode(filename, "utf-8");
        //问题1 设置响应的内容类型  - MimeType - web.xml
        resp.setContentType(this.getServletContext().getMimeType(filename));
        //问题2 告诉浏览器,是以附件形式打开文件(下载)
        resp.setHeader("Content-Disposition","attachment;filename="+filename);
        System.out.println("2,"+filename);
        //3.复制文件 - 创建读文件的输入流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
        //4.复制文件 - 获得响应对的输出流
        ServletOutputStream os = resp.getOutputStream();
        //5.复制文件的过程
        byte[] bytes = new byte[1024];
        int ln = -1;
        while((ln = bis.read(bytes)) != -1){
            os.write(bytes,0,ln);
        }
        //servlet的输出流不需要关闭
        bis.close();
        System.out.println("下载成功!");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件下载</title>
</head>
<body>
    <a href="/day04_war_exploded/downloadServlet?filename=a.zip" >a.zip</a><br>
    <a href="/day04_war_exploded/downloadServlet?filename=a.jpg" >a.jpg</a><br>
    <a href="/day04_war_exploded/downloadServlet?filename=美女.jpg" >美女.jpg</a><br>
</body>
</html>

7.重定向

重定向:资源跳转的⽅式 ,是客户端和服务器端的之间的行为 ,所以路径必须是带应用名的

//1. 设置状态码为302
response.setStatus(302);
//2.设置响应头location
response.setHeader("location","/day15/responseDemo2");
//简单的重定向⽅法
response.sendRedirect("/day15/responseDemo2");

7.1 重定向和转发

7.1.1 重定向的特点:redirect

  • 1. 地址栏发⽣变化
  • 2. 重定向可以访问其他站点(服务器)的资源
  • 3. 重定向是两次请求。不能使⽤request对象来共享数据

7.1.2 转发的特点:forward

  • 1. 转发地址栏路径不变
  • 2. 转发只能访问当前服务器下的资源
  • 3. 转发是⼀次请求,可以使⽤request对象来共享数据

7.2 路径写法

路径分类

  • 1. 相对路径:通过相对路径不可以确定唯⼀资源
    • 如:./index.html
    • 不以 / 开头以 . 开头路径
    • 规则:找到当前资源和⽬标资源之间的相对位置关系
    • ./:当前⽬录
    • ../:后退⼀级⽬录
  • 2. 绝对路径:通过绝对路径可以确定唯⼀资源
    • 如:http://localhost/day15/responseDemo2 /day15/responseDemo2
    • 以 / 开头的路径
    • 规则:判断定义的路径是给谁⽤的?判断请求将来从哪⼉发出
      • 给客户端浏览器使⽤:需要加虚拟⽬录(项⽬的访问路径)
        • 建议虚拟⽬录动态获取:request.getContextPath() 
        • <a> ,<form>
      • 给服务器使⽤:不需要加虚拟⽬录 转发路径

8.JSP

//响应体
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置缓冲区的字符集
        //设置响应体(内容)类型 MIME类型 ,在web.xml找对应的类型
        resp.setContentType("text/html;charset=utf-8");
        //获得字符输出流(缓冲流)  ,有两个输出流一个字符流,另一个字节流
        PrintWriter writer = resp.getWriter();
        //模拟表格
        Map<String , Date> map = Map.of("lucy",new Date(2021,8,4),
                "tom",new Date(2012,8,4),
                "jack",new Date(2020,8,4),
                "rose",new Date(2018,8,4) );
        req.setAttribute("map",map);
        //转让以后上面的响应会被覆盖掉的 -- 在jsp 文件写表格
        req.getRequestDispatcher("/table.jsp").forward(req,resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<%@ page import="java.util.Date" %>
<%@ page import="java.util.Map" %><%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2021/8/4
  Time: 11:37
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>表格jsp</title>
    <style>
        td{
            border-color: chartreuse;
        }
    </style>
</head>
<body>
    <%--  body标签里面的<%  %>这个标签里面写java代码  --%>
    <%--  <% java脚本 %>  --%>
    <table border="1px" cellspacing="0" cellpadding="10">
        <%--  jsp中已经提供了 request 和 response(jsp里面叫out) 对象 直接用就可以      --%>
        <% Map<String, Date> map = (Map<String, Date>) request.getAttribute("map");
            for(String name : map.keySet()){
                Date date =  map.get(name);
                %>
                <tr><td> <% out.write(name); %> </td><td> <% out.write(String.valueOf(date)); %></td></tr>
            <% }%>
    </table>
</body>
</html>

9.Cookie

用于在客户端存储数据

总结:

  response
    响应行  setStatus()
    响应头  setHeader(name,value)
              location  Content-Disposition  set-cookie

响应体: 输出流
    resp.getOutputStream()
    resp.getWriter()

    注意: 两种流不能同时使用, 不需要关闭

    输出流, 响应体内容是先写入到response缓冲区, 缓冲区的字符集就是ISO8859-1
    设置缓冲区的字符集: response.setCharacterEncoding()
        需要在获得输出流之前设置
        客户端还是默认字符集(GBK UTF-8), 可能还需要在客户端手动设置字符集

    字符流: 输出页面内容
    字节流: 下载文件(文件复制)  验证码(图片)

会话技术: 客户端连接上服务器(应用)开始, 到客户端断掉连接结束, 一次会话
    作用: 存数据   session  cookie

    存数据: 域对象(存任意类型数据) cookie(只能存字符串)
           存在服务器上          存在浏览器[客户端]上

    cookie: 存在客户端, 不安全, 服务器压力减小
    session:存在服务器端, 安全, 服务器压力大

    cookie的本质: 响应头信息 set-cookie  将cookie存到客户端
                 请求头信息 cookie      将cookie携带到服务器端
    域对象:
      ServletContext: 一个应用
      session: 一次会话(可能会有多次请求)
      request: 一次请求 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值