Servlet接口的实现类HttpServlet
HttpServlet相关的类和接口:
HttpServlet 类、
GenericServlet 类、
HttpServletRequest 接口
HttpServletResponse 接口
1.Servlet的类继承体系
2.Servlet处理不同的请求
2.1.GET和POST请求的分发处理
/**
* @Author: Ron
* @Create: 2021 13:49
*/
public class HelloServlet implements Servlet {
public HelloServlet() {
System.out.println("1 构造器方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init初始化方法");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3 service === Hello Servlet!!!");
// 类型转换(因为它有 getMethod()方法)
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// 获取请求的方式
String method = httpServletRequest.getMethod();
if ("GET".equals(method)) {
doGet();
} else if ("POST".equals(method)) {
doPost();
}
}
private void doPost() {
System.out.println("处理 post 请求");
}
private void doGet() {
System.out.println("处理 get 请求");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("4 destroy销毁方法");
}
}
2.2.GenericServlet 类
什么是GenericServlet类?
定义一般的、与协议无关的 servlet
GenericServlet 实现 Servlet 和 ServletConfig 接口。servlet 可以直接扩展 GenericServlet,尽管扩展特定于协议的子类(比如 HttpServlet)更为常见。
GenericServlet 使编写 servlet 变得更容易。它提供生命周期方法 init 和 destroy 的简单版本,以及 ServletConfig 接口中的方法的简单版本。GenericServlet 还实现 log 方法,在 ServletContext 接口中对此进行了声明
要编写一般的 servlet,只需重写抽象 service 方法即可。
/**
1. @Author: Ron
2. @Create: 2021 17:10
*/
public class HelloGenericServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
}
3.HttpServlet
通过继承 HttpServlet 实现 Servlet 程序
一般在实际项目开发中, 都是使用继承 HttpServlet 类的方式去实现 Servlet 程序
- 编写一个类去继承 HttpServlet 类
- 根据业务需要重写 doGet 或 doPost 方法
- 到 web.xml 中的配置 Servlet 程序的访问地址
代码实现
HelloHttpServlet 类继承 HttpServlet
/**
* @Author: Ron
* @Create: 2021 17:09
*/
public class HelloHttpServlet extends HttpServlet {
/**
* doGet() 在 get 请求的时候调用
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
System.out.println("HelloHttpServlet 的 doGet 方法");
}
/**
* doPost() 在 post 请求的时候调用
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
System.out.println("HelloHttpServlet 的 doPost 方法");
}
}
web.xml 中的配置:
<!-- HttpServlet 访问路径-->
<servlet>
<servlet-name>HelloHttpServlet</servlet-name>
<servlet-class>com.servlet.test.HelloHttpServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloHttpServlet</servlet-name>
<url-pattern>/helloHttpServlet</url-pattern>
</servlet-mapping>
4.HttpServletRequest 类
4.1.HttpServletRequest 类有什么作用?
每次只要有请求进入 Tomcat 服务器, Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。然后传递到 service 方法( doGet 和 doPost) 中给我们使用。 我们可以通过 HttpServletRequest 对象, 获取到所有请求的信息
4.2.HttpServletRequest 类的常用方法
序号 | 方法 | 作用 |
---|---|---|
1 | getRequestURI() | 获取请求的资源路径 |
2 | getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
3 | getRemoteHost() | 获取客户端的 ip 地址 |
4 | getHeader() | 获取请求头 |
5 | getParameter() | 获取请求的参数 |
6 | getParameterValues() | 获取请求的参数(多个值的时候使用) |
7 | getMethod() | 获取请求的方式 GET 或 POST |
8 | setAttribute(key, value) | 设置域数据 |
9 | getAttribute(key) | 获取域数据 |
10 | getRequestDispatcher() | 获取请求转发对象 |
4.3.如何获取请求参数
表单:
<body>
<form action="http://localhost:8080/07_servlet/parameterServlet" method="get">
用户名: <input type="text" name="username"><br/>
密码: <input type="password" name="password"><br/>
兴趣爱好: <input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="js">JavaScript<br/>
<input type="submit">
</form>
</body>
或者 地址?username=guest
http://localhost:8080/servlet_test/requestForward1?username=guest
4.4.请求的转发
4.4.1.什么是请求的转发?
请求转发是指, 服务器收到请求后, 从一次资源跳转到另一个资源的操作叫请求转发
4.4.2.流程图
4.4.3.代码实现
RequestForward1 类继承 HttpServlet
/**
* @Author: Ron
* @Create: 2021 11:02
* 请求转发测试
*/
public class RequestForward1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在RequestForward1(柜台1)中查看参数(材料):" + username);
// 给材料 盖一个章,并传递到RequestForward2(柜台 2)去查看
req.setAttribute("key1","柜台1的章");
// 问路:RequestForward2(柜台 2)怎么走
/**
* 请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到IDEA代码的web目录<br/>
*
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/requestForward2");
// RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com");
// 走向RequestForward2(柜台 2)
requestDispatcher.forward(req,resp);
}
}
RequestForward2 类继承 HttpServlet
/**
* @Author: Ron
* @Create: 2021 11:02
* 请求转发测试
*/
public class RequestForward2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在RequestForward2(柜台2)中查看参数(材料):" + username);
// 查看 柜台1 是否有盖章
Object key1 = req.getAttribute("key1");
System.out.println("柜台1是否有章:" + key1);
// 处理自己的业务
System.out.println("RequestForward2 处理自己的业务 ");
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="http://localhost:8080/servlet_test/requestForward1" method="get">
用户名: <input type="text" name="username"><br/>
<input type="submit">
</form>
</body>
</html>
web.xml 配置文件
<!--请求转发测试-->
<servlet>
<servlet-name>RequestForward1</servlet-name>
<servlet-class>com.servlet.forward.RequestForward1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestForward1</servlet-name>
<url-pattern>/requestForward1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RequestForward2</servlet-name>
<servlet-class>com.servlet.forward.RequestForward2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestForward2</servlet-name>
<url-pattern>/requestForward2</url-pattern>
</servlet-mapping>
测试:
控制台打印结果
5.HttpServletResponse 类
5.1.HttpServletResponse 类的作用
HttpServletResponse 类和 HttpServletRequest 类一样。 每次请求进来, Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。 HttpServletRequest 表示请求过来的信息, HttpServletResponse 表示所有响应的信息,我们如果需要设置返回给客户端的信息, 都可以通过 HttpServletResponse 对象来进行设置
5.2.如何往客户端回传数据
5.3.请求重定向
5.3.1.什么是请求重定向?
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)
5.3.2.流程图
5.3.3.代码实现
RequestRedirect1 类继承 HttpServlet
/**
* @Author: Ron
* @Create: 2021 11:06
* 请求重定向测试
*/
public class RequestRedirect1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("曾到此一游 RequestRedirect1 ");
req.setAttribute("key1", "value1");
// 通过sendRedirect方法直接重定向到你需要的网址
resp.sendRedirect("http://localhost:8080/servlet_test/requestRedirect2");
}
}
RequestRedirect2 类继承 HttpServlet
/**
* @Author: Ron
* @Create: 2021 11:06
* 请求重定向测试
*/
public class RequestRedirect2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("request域中的数据:"+req.getAttribute("key1"));
resp.getWriter().write("RequestRedirect2's result!");
}
}
web.xml 配置文件
<!--请求重定向测试-->
<servlet>
<servlet-name>RequestRedirect1</servlet-name>
<servlet-class>com.servlet.redirect.RequestRedirect1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestRedirect1</servlet-name>
<url-pattern>/requestRedirect1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RequestRedirect2</servlet-name>
<servlet-class>com.servlet.redirect.RequestRedirect2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestRedirect2</servlet-name>
<url-pattern>/requestRedirect2</url-pattern>
</servlet-mapping>
测试:
http://localhost:8080/servlet_test/requestRedirect1
控制台打印结果:
浏览器显示结果:
5.4.请求转发和重定向的对比
对比项 | 请求转发 | 请求重定向 |
---|---|---|
浏览器地址栏 | 不会变化 | 会变化 |
几次请求 | 同一个请求 | 两次请求 |
API | Request对象 | Response对象 |
WEB-INF | 可以访问 | 不可以访问 |
共享request请求域数据 | 可以共享 | 不可以共享 |
目标资源 | 必须是当前Web应用中的资源 | 不局限于当前Web应用 |
6.请求中乱码问题的解决
6.1.Get 请求的中文乱码解决
// 获取请求参数
String username = req.getParameter("username");
//1 先以 iso8859-1 进行编码
//2 再以 utf-8 进行解码
username = new String(username.getBytes("iso-8859-1"), "UTF-8");
6.2.POST请求的中文乱码解决
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
// 设置请求体的字符集为 UTF-8, 从而解决 post 请求的中文乱码问题
req.setCharacterEncoding("UTF-8");
System.out.println("-------------doPost------------");
// 获取请求参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby");
System.out.println("用户名: " + username);
System.out.println("密码: " + password);
System.out.println("兴趣爱好: " + Arrays.asList(hobby));
}