HttpServletRequest
打印请求信息
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;
import java.util.Enumeration;
@WebServlet("/showRequest")
public class ShowRequestServlet extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
// 此处返回一个 html, 在 html 里面显示刚才看到的这些 API 的接口
// 把这些 API 的返回结果往这个 StringBuilder 里面来拼~
StringBuilder html = new StringBuilder();
html.append(req.getProtocol());
html.append("<br>");
html.append(req.getMethod());
html.append("<br>");
html.append(req.getRequestURI());
html.append("<br>");
html.append(req.getContextPath());
html.append("<br>");
html.append(req.getQueryString());
html.append("<br>");
html.append("<br>");
html.append("<br>");
html.append("<br>");
// 获取到请求的 header 头
//请求中的header是一组键值对结构
//下面这个循环,相当于拿到键值对中所有的key
Enumeration<String> headers = req.getHeaderNames();
while (headers.hasMoreElements()) {
String headerName = headers.nextElement();
html.append(headerName);
html.append(": ");
html.append(req.getHeader(headerName));
//req.getHeader(headerName)这个操作就是根据key来获取value
html.append("<br>");
}
resp.getWriter().write(html.toString());
}
}
浏览器输出结果:
StringBuilder和StringBuffer有啥区别?
StringBuilder:线程不安全
StringBuffer:线程安全,核心方法上带有synchronized关键字
上面的打印请求确实能够获取到请求的一些信息,但是这些方法其实用的并不是特别多
更常用的,还是获取到请求中的一些程序猿传来的参数
- query string(按照键值对
- body
query string
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("/getParameter")
public class GetParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 约定请求是一个 /getParameter?username=1234&password=5678
// 就可以通过 getParameter 方法拿到用户名和密码的值.
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
resp.getWriter().write("username=" + username + "<br>" + "password=" + password);
}
}
当通过一下路径进行访问时可以看到
http://127.0.0.1:8080/TestServlet/getParameter
当没有query string的时候,getParameter获取的值为null
但是如果通过一下路径进行访问,服务器就可以获取到客户端传递过来的参数。
http://127.0.0.1:8080/TestServlet/getParameter?username=1234&password=5678
处理HTTP请求的body中的数据
- 如果body里的内容格式,是按照x-www-form-urlencoded也是使用getParameter进行处理
- 如果body里的内容格式,是按照form-data,此时有单独方式处理
- 如果body里的内容格式,是json,此时需要借助第三方库来处理
方式一
这种情况,数据的格式就是和query string是一样的
创建类:PostParameterServlet
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("/postParameter")
public class PostParameterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 此处是要获取 body 的数据. 由于 GET 方法一般没有 body, 就使用 POST 方法来演示.
// 约定请求的 body 里面是这个格式: username=123&password=456
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
resp.getWriter().write("username=" + username + "<br>" + "password=" + password);
}
}
创建login.html,将其放置到webapp目录中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>login</title>
</head>
<body>
<form action="postParameter" method="post">
<input type="text" name="username">
<input type="text" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
- 部署程序,通过http://127.0.0.1:8080/TestServlet/login.html来进行访问
方式三
此处约定,HTTP请求形如:
{
"username":"123",
"password":"456"
}
创建JsonParameterServlet类
import com.fasterxml.jackson.databind.ObjectMapper;
import jdk.internal.util.xml.impl.Input;
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;
import java.io.InputStream;
class UserInfo {
public String username;
public String password;
}
@WebServlet("/jsonParameter")
public class JsonParameterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
// 1. 先把整个请求的 body 都读取出来.
String body = readBody(req);
System.out.println(body);
// 2. 在按照 json 的格式来进行解析. (对于 json 的解析, Java 标准库没有内置的方法. Servlet 也没有现成的方法. 就需要使用第三方库来完成)
// 此处我们想拿到的是用户名和密码~~ 因此就需要针对这里的 json 数据进行解析, 变成一个键值对结构/或者是变成一个对象.
// 如果我们是想自己实现 json 的解析, 非常麻烦的. (json 里面能嵌套, json 的 value 也可以是另一个 json)
// 因此, 我们就直接使用第三方库来完成~ 在 Java 中解析 json 的第三方库有很多. 此处用的是 Jackson 这个库.
// Jackson 是 spring 官方推荐的库.
ObjectMapper objectMapper = new ObjectMapper();
UserInfo userInfo = objectMapper.readValue(body, UserInfo.class);
resp.getWriter().write("username=" + userInfo.username + "<br>" + "password=" + userInfo.password);
}
private String readBody(HttpServletRequest req) throws IOException {
// 通过这个方法来读取请求中的整个 body
// 核心操作就是 req.getInputStream 这个方法. 这个方法会得到 InputStream 对象~ 然后就可以进一步的读取里面的内容了.
// InputStream 这个本来是咱们前面要介绍的内容. (文件操作章节) , 但是由于咱们要尽量赶一赶实习, 调整课程顺序~~
// 1. 先拿到 body 的长度, 单位是字节
int contentLength = req.getContentLength();
// 2. 准备一个字节数组, 来存放 body 内容
byte[] buffer = new byte[contentLength];
// 3. 获取到 InputStream 对象
InputStream inputStream = req.getInputStream();
// 4. 读取数据, 就是从 inputStream 对象中, 读取到数据, 放到 buffer 这字节数组中
inputStream.read(buffer);
// 5. 得到的结果构造成一个 String
return new String(buffer, "UTF-8");
}
}
使用postman构造一个json格式的HTTP请求
使用jackson
通过pom.xml引入依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>