1.常用类的关键API介绍
Servlet中常见的类有三个.介绍过了HttpServlet类.我们再来看看另外两个.
HttpServletRequest
这个类对应到发送的HTTP请求.
方法 | 描述 |
---|---|
String getProtocol() | 返回请求协议的名称和版本 |
String getMethod() | 返回请求的 HTTP 方法的名称 (GET,POST 或 PUT) |
String getRequestURI() | 返回该请求中的 URL 的一部分 (返回请求中从一级目录开始到到请求中查询字符串以前) |
String getContextPath() | 返回请求中上下文的请求 URI 部分 |
String getQueryString() | 返回包含在路径后的请求 URL 中的查询字符串 |
Enumeration getParameterNames() | 返回一个 String 对象的枚举 (包含在该请求中包含的参数的名称) |
String getParameter(String name) | 以字符串形式返回请求参数的值, 或者如果参数不存在则返回 null |
String[] getParameterValues(String name) | 返回一个字符串对象的数组, 包含所有给定的请求参数的值, 如果参数不存在则返回 null |
Enumeration getHeaderNames() | 返回一个枚举, 包含该请求中包含的所有的头名 |
String getHeader(String name) | 以字符串形式返回指定的请求头的值 |
String getCharacterEncoding() | 返回请求使用的字符编码的名称 |
String getContentType() | 返回请求类型,如果不知道类型则返回 null |
int getContentLength() | 以字节为单位返回请求主体的长度, 如果长度未知则返回 -1 |
InputStream getInputStream() | 用于读取请求的 body 内容. 返回一个 InputStream 对象. |
HttpServletResponse
这个类对应到返回的HTTP响应.
方法 | 描述 |
---|---|
void setStatus(int sc) | 设置响应的状态码 |
void setHeader(String name, String value) | 设置一个带有给定的名称和值的 header. 如果 name 已经存在, 则覆盖旧的值 |
void addHeader(String name, String value) | 添加一个带有给定的名称和值的 header. 如果 name 已经存在, 不覆盖旧的值, 并列添加新的键值对 |
void setContentType(String type) | 设置响应内容的类型 |
void setCharacterEncoding(String charset) | 设置响应的字符编码 |
void sendRedirect(String location) | 设置并发送重定向URL到客户端 |
PrintWriter getWriter() | 用于往 body 中写入文本格式数据 |
OutputStream getOutputStream() | 用于往 body 中写入二进制格式数据 |
2.构造和获取JSON数据
这里我们用到一个新的依赖 jackson
首先要在pom.xml中的 标签中添加jackson的依赖.
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.6.1</version>
</dependency>
2.1.使用jackson
在html中构造JSON数据
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>jackson</title>
</head>
<body>
<h2>JSON</h2>
<input type="text" id="userId"> <br/>
<input type="text" id="classId"> <br/>
<input type="submit" value="提交" id="submit"> <br/>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script>
let userIdInput = document.querySelector('#userId');
let classIdInput = document.querySelector('#classId');
let button = document.querySelector('#submit');
button.onclick = function () {
$.ajax({
type: 'post',
url: 'postJson',
contentType: 'application/json',
data: JSON.stringify({
userId: userIdInput.value,
classId: classIdInput.value
}),
success: function (body) {
console.log(body);
}
});
}
</script>
</body>
</html>
在后端中读取JSON数据
- ObjectMapper : jackson提供的工具类
- readValue方法 : 把JSON格式字符串转成Java的对象
- 第一个参数,表示对哪个字符串进行转换
- 这个参数可以填写成一个String
- 可以是一个流对象
- 可以是一个File
- 第二个参数,表示要把这个JSON格式字符串转成哪个Java对象
- 第一个参数,表示对哪个字符串进行转换
class User {
public int userId;
public int classId;
}
@WebServlet(name = "PostJsonServlet", value = "/postJson")
public class PostJsonServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//jackson提供的工具类
ObjectMapper objectMapper = new ObjectMapper();
//readValue方法.把JSON格式字符串转成Java的对象
//第一个参数,表示对哪个字符串进行转换,这个参数可以填写成一个String,也可以是一个流对象,还可以是一个File
//第二个参数,表示要把这个JSON格式字符串转成哪个Java对象.
User user = objectMapper.readValue(request.getInputStream(), User.class);
response.getWriter().write("userId=" + user.userId + "classId=" + user.classId);
}
}
readValue是怎么完成转换的?
- 先把 getInputStream对应的流对象里面的数据都读取出来
- 针对这个json字符串进行解析
- 从字符串=>键值对
- 遍历这个键值对赋值
- 依次获取到每一个key,根据这个key的名字,和User类里面的属性名字对比,看有没有匹配的名字
- 如果发现匹配的属性则把当前key 对应的value赋值到该User类的属性中
- 赋值的过程中同时会进行类型转换
- 如果没有匹配到的属性就跳过
3.编写代码来理解这两个API的方法.
3.1.输出请求中的信息
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(name = "ShowRequestServlet", value = "/show")
public class ShowRequestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//注意是 text !!不是test
//设置返回的数据格式.
response.setContentType("text/html; charset=utf8");
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<h3>首行部分</h3>");
//返回请求协议的名称和版本
stringBuilder.append(request.getProtocol());
stringBuilder.append("<br/>");
//返回请求使用的方法
stringBuilder.append(request.getMethod());
stringBuilder.append("<br/>");
//返回请求中从一级目录开始到到请求中查询字符串以前
stringBuilder.append(request.getRequestURI());
stringBuilder.append("<br/>");
//返回请求中上下文的请求 URI 部分
stringBuilder.append(request.getContextPath());
stringBuilder.append("<br/>");
//返回请求中的查询字符串(参数部分)
stringBuilder.append(request.getQueryString());
stringBuilder.append("<br/>");
stringBuilder.append("<h3>header部分</h3>");
//获取请求头中的内容(枚举的方式返回)
Enumeration<String> headerNames = request.getHeaderNames();
//循环读取返回的请求头中的内容
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerVlaue = request.getHeader(headerName);
stringBuilder.append(headerName + ": " + headerVlaue + "<br/>");
}
response.getWriter().write(stringBuilder.toString());
}
}
在浏览器路径中输入 http://localhost:8080/e/show?a=10&b=20 来查看结果.
3.2.获取请求中的参数
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(name = "GetParameterServlet", value = "/getParameter")
public class GetParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf8");
//预期请求格式 /getParameter?userId=123&classId=456
String userId = request.getParameter("userId");
String classId = request.getParameter("classId");
response.getWriter().write("userId = " + userId + " classId = " + classId);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf8");
//假设前端传过来的参数是 userId=10&classId=20
//服务器可以通过req.getParameter来获取参数.
String userId = request.getParameter("userId");
String classId = request.getParameter("classId");
response.getWriter().write("userId = " + userId + " classId = " + classId);
}
}
直接在浏览器路径中输入 http://localhost:8080/e/getParameter?userId=31&classId=10 .构造的是GET请求.获得如下结果. 因为逻辑代码相同,所以使用Postman构造POST请求获取的结果相同.
3.3.设置响应状态码并显示到页面
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(name = "StatusServlet", value = "/status")
public class StatusServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应状态码并显示到页面
response.setStatus(200);
response.getWriter().write(response.getStatus());
}
}
在浏览器路径中输入 http://localhost:8080/e/status 得到如下结果.
3.4.网页自动刷新
Header中有一个的 Refresh:xx 表示每隔多久刷新网页.单位是秒.所以我们在header中添加这个信息就可以实现网页自动刷新的功能.
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(name = "AutoRefreshServlet", value = "/auto")
public class AutoRefreshServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf8");
//Refresh Header中的Refresh:表示每隔多久刷新网页.
//这里表示1秒刷新一次
response.setHeader("Refresh", "1");
//获得时间戳并返回
response.getWriter().write("timeStamp: " + System.currentTimeMillis());
}
}
在浏览器路径中输入 http://localhost:8080/e/auto 得到如下结果.
等待一下会发现页面会一直自动刷新.
3.5.重定向
重定向 : 返回一个 302 重定向响应,并重定向到新页面
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(name = "RedirectServlet", value = "/redirect")
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//重定向 返回一个 302 重定向响应,自动跳转
response.setStatus(302);
response.setHeader("Location", "https://blog.csdn.net/m0_58154870/article/details/128259772");
}
}
Servlet提供的更简便的重定向写法.一句话完成两步工作.
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(name = "RedirectServlet", value = "/redirect")
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// response.setStatus(302);
// response.setHeader("Location", "https://blog.csdn.net/m0_58154870/article/details/128259772");
//重定向 Servlet提供的更简便的重定向写法.一句话完成上述两步工作.
response.sendRedirect("https://blog.csdn.net/m0_58154870/article/details/128259772");
}
}
地址栏输入 http://localhost:8080/e/redirect 后会重定向到新页面