ServletAPI详解(三)-HttpServletRequest

我们来看第二个类:HttpServletRequest

HttpServletRequest

HttpServletRequest表示的是一个http请求对象,是tomcat自动构造的,tomcat会实现监听端口,接收连接,读取请求,解析请求,构造请求对象等一系列操作

下面的方法可用在 Servlet 程序中读取 HTTP 头。这些方法通过 HttpServletRequest 对象可用。

序号 方法 & 描述
1 Cookie[] getCookies()
返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。
2 Enumeration getAttributeNames()
返回一个枚举,包含提供给该请求可用的属性名称。
3 Enumeration getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
4 Enumeration getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。
5 HttpSession getSession()
返回与该请求关联的当前 session 会话,或者如果请求没有 session 会话,则创建一个。
6 HttpSession getSession(boolean create)
返回与该请求关联的当前 HttpSession,或者如果没有当前会话,且创建是真的,则返回一个新的 session 会话。
7 Locale getLocale()
基于 Accept-Language 头,返回客户端接受内容的首选的区域设置。
8 Object getAttribute(String name)
以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。
9

ServletInputStream getInputStream()
使用 ServletInputStream,以二进制数据形式检索请求的主体。

用于读取请求的body内容,返回一个InputStream对象

10 String getAuthType()
返回用于保护 Servlet 的身份验证方案的名称,例如,"BASIC" 或 "SSL",如果JSP没有受到保护则返回 null。
11 String getCharacterEncoding()
返回请求主体中使用的字符编码的名称。
12 String getContentType()
返回请求主体的 MIME 类型,如果不知道类型则返回 null。
13 String getContextPath()
返回指示请求上下文的请求 URI 部分。
14 String getHeader(String name)
以字符串形式返回指定的请求头的值。
15 String getMethod()
返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
16

String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。

querystring是查询字符串,是键值对的结构,这个方法通过key来获取到value

17 String getPathInfo()
当请求发出时,返回与客户端发送的 URL 相关的任何额外的路径信息。
18 String getProtocol()
返回请求协议的名称和版本。
19 String getQueryString()
返回包含在路径后的请求 URL 中的查询字符串。
20 String getRemoteAddr()
返回发送请求的客户端的互联网协议(IP)地址。
21 String getRemoteHost()
返回发送请求的客户端的完全限定名称。
22 String getRemoteUser()
如果用户已通过身份验证,则返回发出请求的登录用户,或者如果用户未通过身份验证,则返回 null。
23 String getRequestURI()
从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。
24 String getRequestedSessionId()
返回由客户端指定的 session 会话 ID。
25 String getServletPath()
返回调用 JSP 的请求的 URL 的一部分。
26 String[] getParameterValues(String name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null。
27 boolean isSecure()
返回一个布尔值,指示请求是否使用安全通道,如 HTTPS。
28 int getContentLength()
以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1。
29 int getIntHeader(String name)
返回指定的请求头的值为一个 int 值。
30 int getServerPort()
返回接收到这个请求的端口号。
31 int getParameterMap()
将参数封装成 Map 类型。

 通过代码演示主要的方法

创建一个StringBuilder,将api的结果拼接起来写回到响应中

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/showRequest")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建一个StringBuilder,将api的结果拼接起来写回到响应中
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(" ");
        //协议名称
        stringBuilder.append(req.getProtocol());
        stringBuilder.append(" ");
        //方法名称
        stringBuilder.append(req.getMethod());
        stringBuilder.append(" ");
        //URL
        stringBuilder.append(req.getRequestURL());
        stringBuilder.append(" ");
        //项目路径
        stringBuilder.append(req.getContextPath());
        stringBuilder.append(" ");
        //查询字符串
        stringBuilder.append(req.getQueryString());

        //写回
        resp.getWriter().write(stringBuilder.toString());
    }
}

启动服务器,发现有个错误

 Caused by: java.lang.IllegalArgumentException: servlet映射中的[showRequest]无效

这个是因为注解不正确,一定不要忘记/

@WebServlet("/showRequest")

我们看结果

ServletAPI详解(三)-HttpServletRequest_第1张图片

获取header中的所有键值对
Enumeration getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
resp.setContentType("text/html");设置内容类型后,浏览器会按照这个解析

ServletAPI详解(三)-HttpServletRequest_第2张图片

ServletAPI详解(三)-HttpServletRequest_第3张图片

发送请求后如果进行抓包,看到的结果也是相同的


接下来我们说说前端如何给后端传参

方式:

1.GET,querystring

获取 GET 请求中的参数

GET 请求中的参数一般都是通过 query string 传递给服务器的

String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。

querystring是查询字符串,是键值对的结构,这个方法通过key来获取到value

前端给后端传输两个数字,studentId, classId

?studentId=1&classId=30

@WebServlet("/getParameter")

public class GetParameterServlet extends HttpServlet {
    //预期浏览器会发送一个/getParameter?studentId=1&classId=30请求
    //借助req的getParameter方法获取到querystring的键值对内容

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        resp.setContentType("text/html");
        resp.getWriter().write("studentId = "+studentId+"classId = "+classId);
    }
}

获取到了 ,可以看到query string键值对会被tomcat处理成Map的结构,就可以用getParameter方法通过key获取到值了,如果key不存在,就返回null

ServletAPI详解(三)-HttpServletRequest_第4张图片

2.POST,form

POST 请求的参数一般通过 body 传递给服务器

body 中的数据格式有很多种. 如果是采用 form 表单的 形式, 仍然可以通过 getParameter 获取参数的值.

服务器代码几乎不变,还是使用getParameter方法获取

form之前也讲到过,和querystring的格式是一样的,只是内容在body中

我们现在通过HTML的form标签构造请求

    
    

 重启服务器

ServletAPI详解(三)-HttpServletRequest_第5张图片

抓包结果与代码的对比

ServletAPI详解(三)-HttpServletRequest_第6张图片

Content-Type: application/x-www-form-urlencoded

说明了是通过form表单构造的请求

后端还未构造,所以发送请求后404了

ServletAPI详解(三)-HttpServletRequest_第7张图片 构造后端代码

@WebServlet("/postParameter")
public class PostParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        resp.setContentType("text/html");
        resp.getWriter().write("studentId = "+studentId+"classId = "+classId);
    }
}

代码和GET,querystring后端代码相同,但是这里构造的请求内容是在body中

ServletAPI详解(三)-HttpServletRequest_第8张图片

整个前后端交互过程: 

ServletAPI详解(三)-HttpServletRequest_第9张图片

使用getParameter方法既可以获取querystring中的键值对,也可以获取到form表单构造的body中的键值对

3.POST,josn

 josn也是一种常用的数据格式,也是键值对结构

如果 POST 请求中的 body 是按照 josn的格式来传递, 那么获取参数的代码就要发生调整

前端可以通过ajax方式构造,或者使用postman构造

ServletAPI详解(三)-HttpServletRequest_第10张图片

后端代码

@WebServlet("/postParameter2")
public class GetParameter2Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过这个方法来处理body为json格式的数据
        //将req对象里的body完整读取
        //getInputStream
        //在流对象中读取字节多少取决于Content-Lengt
        int length = req.getContentLength();
        byte[] buffer = new byte[length];

        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);

        //构造成String
        String body  = new String(buffer);
        System.out.println("body = "+ body);
        resp.getWriter().write(body);
    }
}

启动服务器后,点击postman的send发送请求

服务器打印出了

读到的body,是从请求的body中获取到的 

ServletAPI详解(三)-HttpServletRequest_第11张图片

抓包也能看到

ServletAPI详解(三)-HttpServletRequest_第12张图片

 交互过程:

postman构造请求,请求到达tomcat后被解析成req对象

后端代码req.getInputStream();读取body内容并构造成resp对象返回给postman

ServletAPI详解(三)-HttpServletRequest_第13张图片

 当前通过传递数据,服务器只能将body整个读出来,不能通过键值对的形式管理,也不能通过key获取到value

可以使用第三方库解析,比如jackson,spring mvc天然内置了jackson这个库来解析json格式

通过maven引入第三方库

ServletAPI详解(三)-HttpServletRequest_第14张图片

ServletAPI详解(三)-HttpServletRequest_第15张图片 粘贴到pom.xml文件的依赖中,ServletAPI详解(三)-HttpServletRequest_第16张图片

如果红了就刷新,导入依赖项

更改代码

ServletAPI详解(三)-HttpServletRequest_第17张图片

readValue():将json字符串转换成java对象  writeValue():把java对象转换成json字符串

这段代码做的工作:

1.会从body中读取出json格式的字符串

{

    "studentId":20,

    "classId":101

}

2. 根据第二个参数类对象,创建Student实例

3.解析上述json格式的字符串,处理成map键值对结构

4.遍历所有的键值对,看key的名字和Student实例的哪个属性名字相匹配,就把对应的value设置到该属性中

5.返回该Student实例

重启服务器,再次发送请求

ServletAPI详解(三)-HttpServletRequest_第18张图片

 控制台打印了body信息b82e475bdc024c5093d94aa777b147c9.png

总结:

1.GET,参数通过query string传递,服务器使用req.getParameter方法获取参数的值

2.POST,参数通过body(form表单的格式传递) ,服务器用req.getParameter方法获取参数的值

3.POST,参数通过body(json格式传递) ,服务器使用getInputStream读取body的值 

 

你可能感兴趣的:(servlet,tomcat,java)