blog
原创

HTTP——基本概念、请求消息、Request

HTTP

概念

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准

传输协议:定义了客户端和服务端通信时,发送数据的格式

HTTP是一个基于TCP/IP通信协议来传递数据

HTTP的默认端口为80

基于请求/响应模型:一次请求对应一次响应

HTTP是一种无状态协议,每次请求之间相互独立,无法交互数据

请求消息数据格式

请求行

请求方式 请求URL 请求协议/版本

○ 请求方式

HTTP标准有9种请求方式

方法 描述
GET 请求指定的页面信息,并返回实体主体
HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
POST 向指定资源提交数据进行处理请求,数据被包含在请求体中,POST 请求可能会导致新的资源的建立和/或已有资源的修改
PUT 从客户端向服务器传送的数据取代指定的文档的内容
DELETE 请求服务器删除指定的页面
CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器
OPTIONS 允许客户端查看服务器的性能
TRACE 回显服务器收到的请求,主要用于测试或诊断
PATCH 是对 PUT 方法的补充,用来对已知资源进行局部更新
GET与POST请求的区别

GET:请求参数在==请求行==中(拼接在URL之后),请求的URL长度有限制

POST:请求参数在==请求体==中,请求的URL长度没有限制

请求头

请求头名称:请求头值

○ 常见的请求头
  1. User-Agent:访问服务器使用的浏览器版本信息,可获取该头信息来解决浏览器兼容问题
  2. Accept:浏览器可接收的文件类型
  3. Accept-Language:浏览器可接收的语言
  4. Accept-Encoding:浏览器可支持的编码类型
  5. Referer:告知服务器请求的来源URL,可用来做统计工作和防止盗链

请求空行

空行,分隔请求头和请求体

请求体

封装POST请求消息的请求参数

Request

继承体系结构

在这里插入图片描述

功能

获取请求消息数据
(1). 获取请求行数据
方法 描述
String getMethod() 获取请求方式
String getContextPath() 获取虚拟目录
String getServletPath() 获取Servlet路径
String getQueryString() 获取get方式请求参数
String getRequestURI() 获取请求URI
String getProtocol() 获取协议及版本
String getRomoteAddr() 获取客户机IP地址
@WebServlet("/requestDemo")
public class RequestDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取请求方式
        String method = request.getMethod();
        System.out.println(method);
        // 获取虚拟目录
        String contextPath = request.getContextPath();
        System.out.println(contextPath);
        // 获取Servlet路径
        String servletPath = request.getServletPath();
        System.out.println(servletPath);
        // 获取get请求方式参数
        String queryString = request.getQueryString();
        System.out.println(queryString);
        // 获取请求URI
        String requestURI = request.getRequestURI();
        StringBuffer requestURL = request.getRequestURL();
        System.out.println(requestURI);
        System.out.println(requestURL);
        // 获取协议及版本
        String protocol = request.getProtocol();
        System.out.println(protocol);
        // 获取客户机IP地址
        String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);
    }
}
(2). 获取请求头数据
方法 描述
String getHeader(String name) 根据请求头名称获取请求头的值
Enumeration< String > getHeaderNames() 获取所有的请求头名称
@WebServlet("/requestDemo")
public class requestDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取所有请求头名称
        Enumeration<String> headerNames = request.getHeaderNames();
        // 遍历
        while (headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            // 获取请求头的值
            String value = request.getHeader(name);
            System.out.println(name + "===" + value);
        }
    }
}
(3). 获取请求体数据

只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数

方法 描述
BufferedReader getReader() 获取字符输入流,只能操作字符数据
ServletInputStream getInputStream() 获取字节输入流,可以操作所有类型的数据
@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取字符流
        BufferedReader reader = request.getReader();
        // 读取数据
        String line = null;
        while ((line = reader.readLine()) != null){
            System.out.println(line);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
获取请求参数通用方式

无论是get还是post请求方式都可以使用以下方法获取请求参数,由于方式通用,所以不必在doGet和doPost中重复写相同的代码

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	// 通用方式代码
    }

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

① String getParameter(String name):根据参数名称获取参数值

String name = request.getParameter("name");
System.out.println(name);

② String[] getParameterValues(String name):根据参数名称获取参数值的数组

String[] checks = request.getParameterValues("check");
for (String check : checks) {
	System.out.println(check);
}

③ Enumeration< String > getParameterNames():获取所有的请求参数名称

Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
	String s = parameterNames.nextElement();
	System.out.println(s);
}

④ Map< String,String[] > getParameterMap():获取所有参数的Map集合

Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> keySet = parameterMap.keySet();
for (String key : keySet) {
	// 根据key获取value
	String[] values = parameterMap.get(key);
	for (String v : values) {
	System.out.println(v);
	}
}

完整代码

@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("post");
        System.out.println("------------");

        // 根据参数名获取参数值
        String name = request.getParameter("name");
        System.out.println(name);

        // 根据参数名获取多选参数值
        String[] checks = request.getParameterValues("check");
        for (String check : checks) {
            System.out.println(check);
        }

        // 获取所有请求的参数名称
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String s = parameterNames.nextElement();
            System.out.println(s);
        }

        // 获取所有参数的Map集合
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<String> keySet = parameterMap.keySet();
        for (String key : keySet) {
            // 根据key获取value
            String[] values = parameterMap.get(key);
            for (String v : values) {
                System.out.println(v);
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("get");
        System.out.println("------------");
        this.doPost(request,response);
    }
}
获取请求参数中的中文乱码问题

tomcat8 已经解决了get方式的中文乱码问题,但post方式仍会出现乱码问题

可以通过setCharacterEncoding()方法在==获取参数之前==将Request编码更改为 utf-8

request.setCharacterEncoding("utf-8");
请求转发

一种在服务器内部的资源跳转方式

请求转发步骤
  1. 通过Request对象获取请求转发器对象

RequestDispatcher getRequestDispatcher(String path)

  1. 使用RequestDispatcher对象的forward()方法来进行转发

void forward(ServletRequest request, ServletResponse response)

示例

demo4代码

@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("this is demo 4");
        // 转发到demo5
        request.getRequestDispatcher("RequestDemo5").forward(request,response);
    }

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

demo5代码

@WebServlet("/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("this is demo 5");
    }

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

访问RequestDemo4控制台输出为

this is demo 4
this is demo 5
请求转发特点
  1. 浏览器地址栏路径不会发生变化
  2. 只能转发到当前服务器内部资源中,不能转发到外部资源
  3. 转发是一次请求
共享数据
域对象

一个具有作用范围的对象,可以在范围内共享数据

Request域

代表一次请求的范围,一般用于请求转发的多个资源中共享数据

方法
方法 描述
void setAttribute(String name, Object o) 存储数据
Object getAttribute(String name) 通过键来获取值
void removeAttribute(String name) 通过键移除键值对

demo4代码

@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("this is demo 4");
        // 存储数据到Request域中
        request.setAttribute("name","name1");
        // 转发到demo5
        request.getRequestDispatcher("RequestDemo5").forward(request,response);
    }

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

demo5代码

@WebServlet("/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取并输出Request域中的数据
        Object name = request.getAttribute("name");
        System.out.println(name);
        System.out.println("this is demo 5");
    }

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

访问RequestDemo4后控制台输出

this is demo 4
name1
this is demo 5
获取ServletContext

○ ServletContext getServletContext()

@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        System.out.println(servletContext);
    }

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

输出结果

org.apache.catalina.core.ApplicationContextFacade@158ac881
HTTP
  • 作者:Melonico
  • 发表时间:2021-03-15 17:51
  • 更新时间:2021-03-15 17:51

评论

暂无评论,快来发表第一个评论吧!
留言
TOP