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映射中的<url pattern>[showRequest]无效

扫描二维码关注公众号,回复: 14851650 查看本文章

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

@WebServlet("/showRequest")

我们看结果

833406da18d94a2f986a16e05be0f25f.png

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

4abd8ec7f98c44109d8d4a9133eb0a87.png

5888eb26d9e34581977ac59453670686.png

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


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

方式:

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

2b3fa833d8504a329e979d47b21bd19c.png

2.POST,form

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

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

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

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

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

    <!-- form表单构造请求 -->
    <form action="postParameter" method="post">
        <input type="text" name="studentId">
        <input type="text" name="classId">
        <input type="submit" value="提交">
    </form>

 重启服务器

4abdaeaf423a48869741e1f058f2b207.png

抓包结果与代码的对比

5b092fd944c14074984fa71493dfa507.png

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

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

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

e57841a413c64d77970b5bf68ee64d9d.png 构造后端代码

@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中

4af2fe4e14194fce868e365a6316bb51.png

整个前后端交互过程: 

73c6c07e2ea54392b821d8fa9c7e19b3.png

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

3.POST,josn

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

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

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

4c7b1a22115f4824a4e81cbc1b47c1ec.png

后端代码

@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中获取到的 

ce08f6b3d4e14d7996e7a27673591c1e.png

抓包也能看到

0223bc614b944e938b5f47bbba1ef171.png

 交互过程:

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

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

b1eafb9520d24b8cbb280d4c969324dd.png

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

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

通过maven引入第三方库

4758e4c60ed74950832c4d783d9db126.png

9bdb8c7d4e5e424a9017c68697882d06.png 粘贴到pom.xml文件的依赖中,0e821a43828b48ed92dc0f0cd557a082.png

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

更改代码

14f3cb666bdf41ac90e914053f0b1b5e.png

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

这段代码做的工作:

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

{

    "studentId":20,

    "classId":101

}

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

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

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

5.返回该Student实例

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

f5effa550b2e45408422257fadd421c0.png

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

总结:

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

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

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

猜你喜欢

转载自blog.csdn.net/chenchenchencl/article/details/129888454
今日推荐