【HTTP】初识

HTTP协议

1.HTTP请求

比如我们在浏览器地址栏输入一个地址:http://www.sina.com,到底发送了什么呢?

#GET请求
GET / HTTP/1.1 #第一行是HTTP协议的请求主要部分 GET代表请求的方法 /是请求的路径 HTTP/1.1是请求的协议和版本
#后面就都是http请求的属性键值对
Host: www.sina.com
User-Agent: insomnia/6.5.4
Accept: */*

#Post请求
POST /bac HTTP/1.1
Host: localhost:8080
User-Agent: insomnia/6.5.4
Content-Type: application/x-www-form-urlencoded
Accept: */*
Content-Length: 26

name=zhangsan&sex=M&age=20

Get请求和响应

在这里插入图片描述

Post请求和响应

在这里插入图片描述

请求方法包括
GET 获取请求资源

POST 给服务器发送数据

PUSH 往服务放东西(用的比较少一般不会默认支持)

DELETE 删除服务器上的资源(用的比较少一般不会默认支持)

Trace

Options

2.HTTP响应

 HTTP/1.1 200 OK #第一行是HTTP协议响应的主要部分 HTTP/1.1代表协议和版本 200是响应码代表成功 OK是响应消息
#后面就都是http响应的属性键值对
 Server: Tengine
 Content-Type: text/html
 Content-Length: 23994
 Connection: keep-alive
 Date: Sun, 11 Aug 2019 01:05:09 GMT
 Last-Modified: Sun, 11 Aug 2019 01:01:38 GMT
 ETag: "5d4f68f2-5dba"
 Expires: Sun, 11 Aug 2019 01:10:09 GMT
 Cache-Control: max-age=300
 Accept-Ranges: bytes
 Ali-Swift-Global-Savetime: 1565485509
 Via: cache17.l2cn1819[0,200-0,H], cache39.l2cn1819[0,0], cache5.cn800[79,200-0,M], cache1.cn800[102,0]
 Age: 252
 X-Cache: MISS TCP_REFRESH_MISS dirn:5:91445735
 X-Swift-SaveTime: Sun, 11 Aug 2019 01:09:21 GMT
 X-Swift-CacheTime: 48
 X-Via-CDN: f=alicdn,s=cache1.cn800,c=113.143.156.43;
 Timing-Allow-Origin: *
 EagleId: 015101c915654857612364747e

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
!-- [ published at 2019-08-11 09:01:38 ] -->
html>
    head>
        meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        title>WWW.SINA.COM/title>
        meta name="keywords" content="sina, 新浪" />
        meta name="description" content="新浪首页" />
    /head>
    body>
    	.....
    /body>
/html>

3.Http响应码

200 - 299 代表成功响应

300 - 399代表请求转发

400 - 499代表客户端的错误

500 - 599代表服务端错误

Servlet处理HTTP请求和响应

既然一次WEB请求分请求和响应两总部分那么Servlet必然也可以处理Web请求的数据,向客户端发送Web响应

1.Servet处理Web请求

怎么是把web请求中的数据取出来?全依赖HttpServletRequest对象,HTTP请求的数据都被封装成了Request对象

1.1.HttpServletRequest获取请求头中的数据

请求头中的字符串

在这里插入图片描述

//获取Get请求重写Servlet中的doGet()方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            //取出请求方法
            String method = req.getMethod();
            //取出请求路径
            String url = req.getRequestURL().toString();
            //取出协议及版本
            String protocol = req.getProtocol();
            //取出请求头中的内容
            String host_head = req.getHeader("host");
            String accept_head = req.getHeader("accept");
            String userAgent_head = req.getHeader("user-agent");
            System.out.println(method + " " + url + " " + protocol);
            System.out.println("host:" + host_head);
            System.out.println("user-agent:" + userAgent_head);
            System.out.println("accept:" + accept_head);
            //取查询字符串中的数据
            String name = req.getParameter("name");
            String sex = req.getParameter("sex");
            System.out.println("name:" + name + ",sex:" + sex);

            resp.getWriter().println("Hello World !");


        } catch (Exception e) {
            System.out.println(e);
        }
    }

输出结果:

在这里插入图片描述

1.2.Servlet处理不同类型的请求会由servcie()方法派发给不同的方法

GET请求 ----> doGet()方法

POST请求 ----> doPost()方法

PUT请求 ---->doPut()方法

DELETE请求---->doDelete()方法

1.3.HttpServletRequest对象获取查询字符串中的数据

其实我们向服务器传递自己的数据进行交互,并非经常利用HTTP请求头,更多的是利用查询字符串参数和表单,查询字符串是写在URL路径中"?"号后的被“&”符号分开的一组键值对如:

//下面URL中的查询字符串name=zhangsan&sex=M
http://localhost:8080/bac?name=zhangsan&sex=M

获取查询字符串的代码

//取查询字符串中的数据
String name = req.getParameter("name");
String sex = req.getParameter("sex");
//取查询字符串中的集合数据

获取查询字符串集合数据,如下面的URL中有多个name查询字符串属性,保存了多个不同的值

http://localhost:8080/bac?name=zhangsan&sex=M&name=lisi&name=wangmazi

获取name属性得到的就必定是一个集合,此时如果getParameter(“name”)返回的只有一个值,所以得用其它方法

//取查询字符串中的集合数据
String[] names=req.getParameterValues("name");System.out.println(Arrays.asList(names));//转发换成列表输出

HttpServletRequest对象中是把查询字符存储成一个查询字符串的Map集合

 //查询字符串在request当中本质是存储为Map集合,用以下方法可取出
MapString,String[]> params = req.getParameterMap();
String[] namePamrams = params.get("name");//取到name属性值的集合
System.out.println(Arrays.asList(namePamrams));//转换成列表输出
String[] sexParams = params.get("sex");
System.out.println(Arrays.asList(sexParams));//转换成列表输出

输出:

在这里插入图片描述
可以看出,实际map中存的每个属性的值都是一个字符串数组,那么getParameter(“…”)方法实际是返回某属性的值集合中的第一个元素,getParameterValues("…")则是返回属性原本的字符串集合

1.4.HttpServletRequest获取表单数据

1.定义表单

html>
  head>
    meta charset="gb2312"/>
    title>测试表单/title>
    script type="text/javascript" src="js/jquery-3.4.1.min.js">/script>
    script type="text/javascript" src="js/js.js">/script>
  /head>
  body>
  form method="post" action="/form">
      帐号:input type="text" name="name"/>br/>
      密码:input type="password" name="pwd"/>br/>
      性别:input type="radio" name="sex" value="男" checked/>男
            input type="radio" name="sex" value="女"/>女br/>
      爱好:input type="checkbox" name="fav" value="吹"/>吹
            input type="checkbox" name="fav" value="拉"/>拉
            input type="checkbox" name="fav" value="弹"/>弹
            input type="checkbox" name="fav" value="唱"/>唱br/>
      年份:select name="year">/select>br/>
      描述:textarea name="desc" rows="8" cols="20">/textarea>br/>
      input type="submit"/>input type="reset"/>
  /form>
  /body>
/html>

2.创建Servlet

package edu.xalead;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
public class FormServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //取表单中的数据
        String name = request.getParameter("name");//取name属性的值
        String pwd = request.getParameter("pwd");//取pwd属性的值
        String sex = request.getParameter("sex");//取sex属性的值
        String[] fav = request.getParameterValues("fav");//取fav属性值的集合
        String year = request.getParameter("year");//取year属性的值
        String desc = request.getParameter("desc");//取desc属性的值
        System.out.println(name + ":" + pwd + ":" + sex + ":" + Arrays.asList(fav) +
                ":" + year + ":" + desc);
    }
}

3.web.xml添加servlet配置

?xml version="1.0" encoding="UTF-8"?>
web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    !--.....-->
    servlet>
        servlet-name>FormServlet/servlet-name>
        servlet-class>edu.xalead.FormServlet/servlet-class>
    /servlet>
    servlet-mapping>
        servlet-name>FormServlet/servlet-name>
        url-pattern>/form/url-pattern>
    /servlet-mapping>
    !--.....-->
/web-app>

4.注意在表单中添加action请求的servlet路径,要和web.xml中配置的servlet路径一致

在这里插入图片描述

\1565682613675

6.Servlet处理Web响应

处理响应是由HttpServletResponse对象操作,我们可以利用这个对象,在向客户发送的响应中添加我们希望格式化的内容

1.1.HttpServletResponse对象向响应头中添加文本信息

利用getWriter()方法获得文本流,这个是向响应体中添加文本的,实际就是在写HTML文档字符

//向响应体中(html页面)添加字符数据(html页面)
response.getWriter().println("<html>");
response.getWriter().println("<head>");
response.getWriter().println("<title>动态页面</title>");
response.getWriter().println("</head>");
response.getWriter().println("<body>");
response.getWriter().println(name + ":" + pwd + ":" + sex + ":" + Arrays.asList(fav) +
                             ":" + year + ":" + desc);
response.getWriter().println("</body>");
response.getWriter().println("</html>");
1.2.HttpServletResponse对象向响应体中添加字节数据

利用getOutputStream()方法获得字节流,就可以向客户端发送字节数据了,字节可以是图片,音频,视频,文件等等

1.创建字节数据比如画一张图片,利用response对象的getOutputStream()字节流把字节写到响应体中

BufferedImage img = new BufferedImage(200,200, BufferedImage.TYPE_INT_ARGB);
try {
    Graphics2D g = (Graphics2D) img.getGraphics();
    g.setColor(Color.WHITE);
    g.drawString("Hello World !",30,80);
    //imageIo的write()方法,第一个参数是要写的图片内存缓存对象,第二个参数是要格式化的字节格式,第三个是准备用什么类型的字节流写,这里是向响应体中写字节的流
    ImageIO.write(img,"jpg",response.getOutputStream());
    response.getOutputStream().flush();
} catch (Exception e) {
    e.printStackTrace();
}

2.向客户端写字节要注意,如果浏览不知道字节是什么类型,不知道如何打开,就会默认打开“另存为”对话框,像图片,音频,视频格式如果你认为浏览器应该能识别并展示播放,则需要在响应头中添加contentType头属性,我们把contentType类型称作mime类型

//添加mime类型,下面两种方式均可,推荐第二种
//response.setHeader("contentType","image/jpg");        response.setContentType("image/jpg");

7.请求转发

1.1.Response对象在请求头中设置转发属性

//把响应头中的状态码改为302
response.setStatus(302);
//在请求头中设置location属性为要转发的路径
response.setHeader("location","http://www.sohu.com");

这类请求首先客户端发起初始请求 http://localhost:8080/abc 这个我们配置的请求Servlet

GET /abc HTTP/1.1

Host: localhost:8080
User-Agent: insomnia/6.5.4
Accept: /

Servlet通过response修改了状态码为302,并在响应头中添加转发路径 location属性,下面的响应信息发送到了客户端浏览

HTTP/1.1 302
< Content-Type: text/html;charset=utf-8
< Content-Language: zh-CN

< location:http://www.sohu.com

< Content-Length: 1072
< Date: Wed, 14 Aug 2019 07:18:10 GMT

浏览器接收到响应消息后,发现响应是302,就在头属性中找出location属性,重新封装下面的Http请求 http://www.sohu.com ,再次发出请求

GET / HTTP/1.1

Host:http://www.sohu.com
User-Agent: insomnia/6.5.4
Accept: /

最后得到的是转发页面

在这里插入图片描述

但是上面的代码稍嫌麻烦,实际上response封装了一个sendRedirect()方法,实际实现上面两行代码的功能

8. SendRedirect方法(重定向)

因为直接操作响应头的代码有点麻烦,所以response把上面的两行代码封装成了sendRedirect()方法

特点:可以实现跨域转发

response.sendRedirect("http://www.sohu.com");
//等同于
//把响应头中的状态码改为302
response.setStatus(302);
//在请求头中设置location属性为要转发的路径
response.setHeader("location","http://www.sohu.com");

1.1请求派发

1.创建请求派发对象

RequestDispatcher dispatcher = request.getRequestDispatcher("/bbc");//得到请求派发对象

2.forWard(request,response)

dispatcher.forward(request,response);//转发

说明:用forward()方法转发,第一个Servlet无法向客户端响应,只有转给的第二个Servlet可以向客户端响应

3.include(request,response)

dispatcher.include(request,response);//包含

说明:用include方法转发,第一个Servlet和第二个Servlet均可向客户端响应,响应顺序按代码顺序响应,形成一种第一个Servlet的响应信息包含第二个Servlet的响应信息效果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值