文章目录
Servlet
1. Servlet 的三种创建方式
1.1 Servlet 程序基本架构
interface javax.servlet.Servlet 接口
整个 Java WEB 程序中,所有 Servlet 程序总接口,规范了 Servlet 必须完成的方法有哪些
abstract class javax.servlet.GenericServlet implement Servlet
其中完成的一些必要的方法,同时保留部分 abstract 修饰的抽象方法
abstract class javax.servlet.HttpServlet extends GenericServlet
其中没有任何一个抽象方法
1.2 Servlet 接口中的方法
// 初始化当前 Servlet 程序/ Servlet 对象。方法参数为 ServletConfig Servlet 配置对象。
public void init(ServletConfig config);
// 获取 ServletConfig Servlet 配置对象
public ServletConfig getServletConfig();
// 【核心方法】Servlet 程序提供 WEB 服务核心方法,方法参数是用户请求 ServletRequest 和 对应响应
// ServletResponse
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
// 获取 Servlet 字符串信息描述【鸡肋】
public String getServletInfo();
// Servlet 程序销毁操作,Tomcat 服务器在退出时,会将整个 Tomcat 服务器中的所有注册资源逐一 destroy
public void destroy();
1.3 遵从 Servlet 接口实现 Servlet 程序
package com.qfedu.a_createServlet ;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
/**
* @author Anonymous 2022/6/9 9:58
*/
@WebServlet("/servletImpl")
public class ServletImpl implements Servlet {
public ServletImpl() {
System.out.println("ServletImpl 无参数构造方法执行...");
}
// 初始化当前 Servlet 程序/ Servlet 对象。方法参数为 ServletConfig Servlet 配置对象。
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init 初始化方法执行...");
}
// 获取 ServletConfig Servlet 配置对象
@Override
public ServletConfig getServletConfig() {
return null;
}
// 【核心方法】Servlet 程序提供 WEB 服务核心方法,方法参数是用户请求 ServletRequest 和 对应响应
// ServletResponse
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("Service 方法执行...");
res.getWriter().append("<h1>Service Method Running....</h1>");
}
// 获取 Servlet 字符串信息描述【鸡肋】
@Override
public String getServletInfo() {
return null;
}
// Servlet 程序销毁操作,Tomcat 服务器在退出时,会将整个 Tomcat 服务器中的所有注册资源逐一 destroy
@Override
public void destroy() {
System.out.println("destroy 销毁方法执行...");
}
}
1.4 继承 GenericServlet 实现 Servlet 程序
package com.qfedu.a_createServlet;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
/**
* 继承 GenericServlet 有且只需要实现 service 其他与业务逻辑无关的方法,无需考虑,无需完成。
* 降低了程序员开发压力,同时给予后期的业务实现,提供必要的自由度。
* @author Anonymous 2022/6/9 10:07
*/
@WebServlet("/extendsGeneric")
public class ExtendsGenericServlet extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
res.getWriter().append("<h1>ExtendsGenericServlet service running...</h1>");
}
}
1.5 继承 HttpServlet 实现 Servlet 程序
package com.qfedu.a_createServlet;
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;
/**
* 继承 HttpServlet 完成 Servlet 程序
* 在 HttpServlet 中没有任何一个 abstract 修饰的抽象方法
*
* HttpServlet 类内自定义 service(HttpServletRequest request, HttpServletResponse response);
* 在针对于用户请求方式进行了解析和分发操作
* 用户请求
* GET ==> doGet(HttpServletRequest request, HttpServletResponse response)
* POST ==> doPost(HttpServletRequest request, HttpServletResponse response)
* 并且在 doGet 和 doPost 要求程序员必须重写,如果没有重写 405 Method Not Allowed
*
* @author Anonymous 2022/6/9 10:27
*/
@WebServlet("/extendsHttpServlet")
public class ExtendsHttpServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().append("<h1>Extends HttpServlet to Create Servlet Program</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.6 三种方式对比
1. 遵从 Servlet 接口
需要完成的方法很多,而且大部分方法和业务逻辑无关,并且存在操作的重复性。
2. 继承 GenericServlet 抽象类
有且只需要实现 service 核心方法,其他与业务逻辑无关的功能,不需要实现,简化的实现过程,同时留给后期实现业务的自由度,方便后期拓展【承上启下】
3. 继承 HttpServlet 抽象类
明确的协议类型 HTTP 协议。在满足 HTTP 协议的规范下完成 Servlet 程序,同时根据 HTTP 协议对请求方式完成对应方法处理的操作,在 HttpServlet 类内没有任何一个 抽象方法,但是使用 abstract 关键字修饰 HttpServlet 是为了保证执行任务目标的程序是程序员自行完成的程序。
4 BaseServlet 后期完成
2. Servlet 生命周期
2.1 涉及到的方法
1. Servlet 构造方法,而且一定是无参数构造方法。
2. init(ServletConfig config) Servlet 配置方法,在 Servlet 实例化之后,执行 service 功能之前,进行初始化操作
3. service 方法【核心方法】执行 Servlet 服务方法
4. destroy 销毁 Servlet 程序
实例化 --> 初始化 --> 服务(loop) --> 销毁
2.2 代码演示
package com.qfedu.b_lifecycle;
import javax.servlet.ServletConfig;
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;
/**
* @author Anonymous 2022/6/9 11:11
*/
@WebServlet("/lifeCycle")
public class ServletLifeCycleServlet extends HttpServlet {
// 无参数构造方法
public ServletLifeCycleServlet() {
System.out.println("----------------无参数构造方法,实例化当前 Servlet 程序----------------");
}
// 初始化方法
@Override
public void init(ServletConfig config) throws ServletException {
// 为了保证 Servlet 程序正常运行,保留 super 调用 GenericServlet 类内 init 方法形式
super.init(config);
System.out.println("----------------init 方法执行----------------");
}
// service 方法
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().append("<h1>我饿了</h1>");
}
@Override
public void destroy() {
super.destroy();
System.out.println("----------------servlet 程序销毁----------------");
}
}
2.3 小总结
1. Servlet 程序可以认为是一个【单例模式】在整个 Tomcat 服务器中,资源名称匹配的 Servlet 程序有且只有一个,一旦创建初始化之后,后期只有唯一,提供 service 操作
2. Servlet 程序有且只有在被用户请求时才会被 Tomcat 服务器创建
可以设置 Servlet 程序开机自启
3. Servlet 参数配置
3.1 Servlet 配置常用参数
主要参数
1. 开机自启
2. 初始化操作
其他参数:
1. servlet 名称
2. servlet 描述
3.2 web.xml 方式
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 在 Servlet 标签中配置对应 Servlet 程序相关参数信息 -->
<servlet>
<servlet-name>WebXMLConfigServlet</servlet-name>
<servlet-class>com.qfedu.c_configServlet.WebXMLConfigServlet</servlet-class>
<!-- init-param servlet 初始化参数 参数可以配置多个 -->
<init-param>
<!-- param-name 参数名称 -->
<param-name>老黑</param-name>
<!-- param-value 参数值 -->
<param-value>人黑心不黑</param-value>
</init-param>
<init-param>
<!-- param-name 参数名称 -->
<param-name>Feri</param-name>
<!-- param-value 参数值 -->
<param-value>老邢上车油耗增加 0.2L/100KM</param-value>
</init-param>
<!-- load-on-startup Tomcat 启动对应 Servlet 程序同时启动 1 表示开机自启 0 默认值请求之后创建加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WebXMLConfigServlet</servlet-name>
<url-pattern>/webXml</url-pattern>
</servlet-mapping>
</web-app>
package com.qfedu.c_configServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Anonymous 2022/6/9 11:32
*/
public class WebXMLConfigServlet extends HttpServlet {
public WebXMLConfigServlet() {
System.out.println("-------------WebXMLConfigServlet 构造方法-------------");
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
/*
Servlet 配置信息都在 ServletConfig 对象中,可以从 ServletConfig 对象中
获取对应的配置参数
通过参数名称获取对应参数值
*/
String value1 = config.getInitParameter("老黑");
String value2 = config.getInitParameter("Feri");
System.out.println(value1);
System.out.println(value2);
System.out.println("-------------init 初始化操作-------------");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
ServletConfig servletConfig = getServletConfig();
String value1 = servletConfig.getInitParameter("老黑");
String value2 = servletConfig.getInitParameter("Feri");
resp.getWriter().append("<h1>" + value1 + "</h1>");
resp.getWriter().append("<h1>" + value2 + "</h1>");
resp.getWriter().append("<h1>Servlet Config</h1>");
}
}
3.3 注解方式
package com.qfedu.c_configServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
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.PrintWriter;
/**
* @author Anonymous 2022/6/9 14:54
*/
@WebServlet(
value = {"/anno", "/webAnno"}, // url-pattern 资源注册名称,可以是多个
loadOnStartup = 1, // 当前 Servlet 程序 Tomcat 服务器启动自启动
initParams = {@WebInitParam(name = "大哥", value = "SingleDog"), @WebInitParam(name = "黑邢", value = "黑黝黑黑黑")}
// initParams 初始化参数
)
public class WebServletAnnotationConfigServlet extends HttpServlet {
public WebServletAnnotationConfigServlet() {
System.out.println("----------------WebServletAnnotationConfigServlet Constructor----------------");
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
String value1 = config.getInitParameter("大哥");
String value2 = config.getInitParameter("黑邢");
System.out.println(value1);
System.out.println(value2);
System.out.println("----------------init method----------------");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
ServletConfig servletConfig = getServletConfig();
PrintWriter writer = resp.getWriter();
writer.append("<h1>" + servletConfig.getInitParameter("大哥") + "</h1>");
writer.append("<h1>" + servletConfig.getInitParameter("黑邢") + "</h1>");
}
}
4. HTML页面提交数据到 Servlet
4.1 HTML 页面
JavaWEB 项目中 静态资源(HTML CSS JS img) 在 web 目录下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<!--
action
提交数据的目标资源路径,可以提交到当前 JavaWEB Application 中的 Servlet 资源
需要明确当前 Servlet 资源名称
Method:
GET
-->
<form action="registerUser" method="POST">
<span>名称:</span><input type="text" name="username"> <br>
<span>密码:</span><input type="password" name="password"> <br>
<input type="submit" value="提交">
</form>
</body>
</html>
4.2 RegisterUserServlet
package com.qfedu.d_operation;
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.nio.charset.StandardCharsets;
/**
* @author Anonymous 2022/6/9 15:25
*/
@WebServlet("/registerUser")
public class RegisterUserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username + ":" + password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.3 乱码问题
Tomcat 8, 9
1. GET 请求中文OK
2. POST 请求中文乱码
Tomcat 7
1. GET 请求中文 GG思密达
2. POST 请求中文 GG思密达
Tomcat 8, 9 中文乱码解决方案
/*
修改请求编码集
HttpServletRequest setCharacterEncoding(String encoding);
*/
req.setCharacterEncoding("utf-8");
Tomcat 7 解决方案
提交数据默认编码集为 ISO-8859-1
需要将所有提交数据全部重新编码 ==> UTF-8
username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
响应乱码需要通过:
/*
HttpServletResponse 符合 Http 协议 Servlet 规范的响应类对象
setContentType ==> 修改,设置响应头内容 Response Header Content-Type 响应头内容
*/
resp.setContentType("text/html;charset=utf-8");
// 目前需要在 Servlet 程序中加上
// 解决请求乱码
req.setCharacterEncoding("utf-8");
// 解决响应乱码
resp.setContentType("text/html;charset=utf-8");
5. 梦幻联动(Bug联动)
5.1 HTML => Servlet => MySQL
5.2 MySQL => Servlet => HTML
合 Http 协议 Servlet 规范的响应类对象
setContentType ==> 修改,设置响应头内容 Response Header Content-Type 响应头内容
*/
resp.setContentType(“text/html;charset=utf-8”);
```java
// 目前需要在 Servlet 程序中加上
// 解决请求乱码
req.setCharacterEncoding("utf-8");
// 解决响应乱码
resp.setContentType("text/html;charset=utf-8");
5. 梦幻联动(Bug联动)
5.1 HTML => Servlet => MySQL
[外链图片转存中…(img-QS7tLAUz-1654935041360)]
5.2 MySQL => Servlet => HTML
[外链图片转存中…(img-6LhF5ms4-1654935041364)]