HTTP(Response)

5 HTTP(响应消息)

5.1 响应消息数据格式

1、响应行

​ 协议/版本 响应的状态码 状态码描述

HTTP/1.1 200 OK

响应状态码:

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

2、响应头

​ 响应头名称:响应头值

Content-Type: text/html;charset=UTF-8

​ …

常见的响应头:

1、Content-Type:服务器告诉客户端本次响应数据格式以及编码格式

2、Content-disposition:服务器告诉客户端以什么格式打开响应体数据

​ 值:in-line:默认值,在当前页面打开 attachment:以附件形式打开响应体。(文件下载)

3、响应空行

​ 空行

4、响应体

​ 传输的数据

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 99
Date: Sun, 16 Aug 2020 02:30:18 GMT
Keep-Alive: timeout=20
Connection: keep-alive

<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  hello response
  </body>
</html>

6 Response

6.1 response对象的功能

6.1.1 设置响应消息数据

6.1.1.1 设置响应行

HTTP/1.1 200 OK

方法:

设置状态码:setStatus(int sc)

6.1.1.2 设置响应头

Content-Type: text/html;charset=UTF-8

​ …

方法:

setHeader(String name,String value)

6.1.1.3 设置响应体

使用步骤:

1、获取输出流

  • 字符输出流:PrintWriter getWriter()
  • 字节输出流:ServletOutputStream getOutputStream()
  1. 使用输出流,将数据输出到客户端浏览器

7 案例

7.1 完成重定向

重定向:资源跳转的方式

在这里插入图片描述

7.1.1 代码实现

两种方法:

@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("demo1........"); 

        //方法一:
        //访问/responseDemo1,会自动跳转到/responseDemo2资源
        //1. 设置状态码为302
        response.setStatus(302);
        //2.设置响应头location
        response.setHeader("location","/day15/responseDemo2");

        //动态获取虚拟目录
        String contextPath = request.getContextPath();
        
        //方法二:
        //简单的重定向方法
        response.sendRedirect(contextPath+"/responseDemo2");     
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
@WebServlet("/responseDemo2")
public class ResponseDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo2222222........");

        Object msg = request.getAttribute("msg");
        System.out.println(msg);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

7.1.2 特点

转发的特点:(forword)

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

重定向的地点:(redirect)

1、地址栏发生变化

2、重定向可以访问其他服务器的资源

3、重定向是两次请求,不能使用request对象共享数据

7.1.3 路径的写法

7.1.3.1 相对路径
  • 不以 / 开头的路径,以.开头的路径,如:./index.html
  • 规则:确定当前资源和目标资源的关系

./ : 当前目录

…/ : 后退一级目录

举例一:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>相对路径</h1>
    <h1>找到当前资源和目标资源之间的相对位置关系</h1>
    <P>
        当前资源:location.html
        http://localhost/day15/location.html

    </P>
    <P>
        目标资源:
        http://localhost/day15/responseDemo2

    </P>

    <a href="./responseDemo2">
        responseDemo2
    </a>

    <a href="responseDemo2">   <!-- 可省略./ -->
        responseDemo2
    </a>
    <br>
    <hr>
</body>
</html>

举例二:

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <h1>找到当前资源和目标资源之间的相对位置关系</h1>
    <P>
        当前资源:location.html
        http://localhost/day15/htmls/location2.html

    </P>
    <P>
        目标资源:
        http://localhost/day15/responseDemo2

    </P>

    <a href="../responseDemo2">
        responseDemo2
    </a>

</body>
</html>
7.1.3.2 绝对路径
  • 以 / 开头的路径,如:/day15/responseDemo2
  • 规则:判断定义的路径是给谁用的?判断请求从哪发出

给客户端浏览器使用:需要加虚拟目录(项目的访问路径),举例:html中的、、重定向

​ 建议虚拟目录动态获取 String contextPath = request.getContextPath();

给服务器使用:不需要加虚拟目录,举例:转发

7.2 服务器输出字符数据到浏览器

步骤:

1、获取字符输出流

2、输出数据

**注:**中文乱码问题:

方法一:

response.setCharacterEncoding("utf-8")

response.setHeader("content-type","text/html;charset=utf-8")

方法二:简单的形式

response.setContentType("text/html;charset=utf-8")

在这里插入图片描述

@WebServlet("/responseDemo4")
public class ResponseDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取流对象之前,设置流的默认编码:ISO-8859-1 设置为:GBK
       // response.setCharacterEncoding("utf-8");

        //告诉浏览器,服务器发送的消息体数据的编码。建议浏览器使用该编码解码
        //response.setHeader("content-type","text/html;charset=utf-8");

        //简单的形式,设置编码
        response.setContentType("text/html;charset=utf-8");

        //1.获取字符输出流
        PrintWriter pw = response.getWriter();
        //2.输出数据
        //pw.write("<h1>hello response</h1>");
        pw.write("你好啊啊啊 response");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

7.3 服务器输出字节数据到浏览器

步骤:

1、获取字节输出流

2、输出数据

@WebServlet("/responseDemo5")
public class ResponseDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");

        //1.获取字节输出流
        ServletOutputStream sos = response.getOutputStream();
        //2.输出数据
        sos.write("你好".getBytes("utf-8"));
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

7.4 验证码(扩展案例)

步骤:

1、创建一对象,在内存中显示图片

2、美化图片

3、将图片输出到页面展示

7.4.1 代码实现1

@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        int width = 100;
        int height = 50;

        //1.创建一对象,在内存中图片(验证码图片对象)
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);


        //2.美化图片
        //2.1 填充背景色
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.PINK);//设置画笔颜色
        g.fillRect(0,0,width,height);

        //2.2画边框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,width - 1,height - 1);

        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
        //生成随机角标
        Random ran = new Random();

        for (int i = 1; i <= 4; i++) {
            int index = ran.nextInt(str.length());
            //获取字符
            char ch = str.charAt(index);//随机字符
            //2.3写验证码
            g.drawString(ch+"",width/5*i,height/2);
        }


        //2.4画干扰线
        g.setColor(Color.GREEN);

        //随机生成坐标点

        for (int i = 0; i < 10; i++) {
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);

            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1,y1,x2,y2);
        }

        //3.将图片输出到页面展示
        ImageIO.write(image,"jpg",response.getOutputStream());
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

7.4.2 代码实现2(点击切换)

**注:**浏览器有缓存,如果使用img.src = "/day15/checkCodeServlet?",浏览器会直接使用缓存里的数据,而不会对服务器发起一次新的请求。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script>
        /*
            分析:
                点击超链接或者图片,需要换一张
                1.给超链接和图片绑定单击事件

                2.重新设置图片的src属性值

         */
    window.onload = function(){
        //1.获取图片对象
        var img = document.getElementById("checkCode");
        //2.绑定单击事件
        img.onclick = function(){
            //加时间戳
            var date = new Date().getTime();

            img.src = "/day15/checkCodeServlet?"+date;
        }
    }
    </script>
</head>
    
<body>
    <img id="checkCode" src="/day15/checkCodeServlet" />

    <a id="change" href="">看不清换一张?</a>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值