Servlet
一、Servlet继承结构
1. 概述
tomcat服务器提供了Servlet规范的实现。我们写的代码要想被服务器调用,也必须遵守Servlet规范。
自定义的Servlet类并没有去直接实现Servlet接口,是因为该接口中方法较多,Servlet接口有它的一系列实现类,我们继承实现类即间接的实现了Servlet接口。
2. 继承结构体系
2.1 Servlet接口
package javax.servlet; import java.io.IOException; public interface Servlet { //init(),创建Servlet对象后立即调用该方法完成一些初始化工作 void init(ServletConfig var1) throws ServletException; //getServletConfig(),ServletConfig是容器向servlet传递参数的载体 ServletConfig getServletConfig(); //service(),处理客户端请求,执行业务操作,通过响应对象响应客户端请求 void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; //getServletInfo(),获取servlet相关信息 String getServletInfo(); //destroy(),在销毁前Servlet对象之前调用该方法 void destroy(); }
2.2 ServletConfig接口
package javax.servlet; import java.util.Enumeration; public interface ServletConfig { //返回Servlet的名字,即web.xml中<servlet-name>的值 String getServletName(); //返回一个代表当前Web应用的ServletContext对象 ServletContext getServletContext(); //根据初始化参数返回对应的初始化参数值 String getInitParameter(String var1); //返回一个Enumeration对象,包含了所有的初始化参数名 Enumeration<String> getInitParameterNames(); }
2.3 GenericServlet抽象类
GenericServlet是实现了Servlet接口的抽象类;
在GenericServlet中进一步定义ileServlet接口的具体实现,设计目的是为了与应用层协议解耦;
在GenericServlet中包含一个Service抽象方法。
2.4 HttpServlet类
针对于处理HTTP协议的请求所定制;
HttpServlet继承了GenericServlet,实现了service方法,将ServletRequest对象和ServletResponse对象强转为HttpServletRequest对象和HttpServletResponse对象。
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request; HttpServletResponse response; try { //将请求对象、响应对象强转 request = (HttpServletRequest)req; response = (HttpServletResponse)res; } catch (ClassCastException var6) { throw new ServletException(lStrings.getString("http.non_http")); } //又调用了本类中的service方法(匹配请求方法作对应处理) this.service(request, response); }
2.5 注意事项
tomcat服务器在接收到浏览器的请求后,会调用Servlet的service方法处理器请求,如果当前自定义的Servlet类没有service方法会调用父类的service方法进行处理。
二、Servlet的生命周期
1. 执行过程
Servlet的生命周期是由容器管理的,分别经历三个阶段:
初始化:创建Servlet实例化对象,执行init()方法
服务:调用service()方法处理接收到的请求数据并响应
销毁:当退出服务器前,会调用destroy()方法进行servlet的销毁
2. 注意
1.Servlet对象只会被创建及初始化一次(无论多少客户端和多次请求),然后驻留在内存中而不是使用完就销毁;
2.创建及初始化Servlet对象时机
① 默认情况下在服务器第一次收到对应请求,经过解析创建Servlet实例对象
② 如果配置了 load-on-starup(优先级) 就在启动服务器时创建和初始化。
3.当服务器关闭时,Servlet才会被销毁
4.我们自始至终都使用同一个Servlet对象去处理请求(单例模式),如果同时有10个请求过来访问Tomcat服务器,服务器会创建10个线程来处理请求,
所以避免使用全局变量, 多个线程操作全局变量存在线程安全的问题, service()方法中的局部变量不存在线程安全问题。
三、Servlet在Tomcat中运行的原理
启动Tomcat服务器后,
1. 解析web项目的web.xml文件
①默认情况:
解析出url-partten和servlet-class
②配置了load-on-startup:
解析出的url-partten作为key,根据servlet-class通过反射创建Servlet的对象作为value,存储到map集合中。
2.Tomcat服务器接收请求
3.Tomcat服务器解析请求,查找请求的资源
①默认情况:根据url解析的结果,找到web.xml中匹配的url-partten,获取包名和类名,利用反射完成方法的调用。
②配置了load-on-startup:根据url解析的结果,在map集合中根据key(url-partten)获取对应的实例化对象,调用service方法。
注意:以上流程是Tomcat自动执行,是不可见的。
四、请求对象(HttpServletRequest)
-
-
GET请求只能进行url编码,而POST支持多种编码方式。
-
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
-
GET请求在URL中传送的参数是有长度限制的,而POST则没有。对参数的数据类型GET只接受ASCII字符,
-
POST既可是字符也可是字节。
-
GET相比POST来说不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
-
1. request对象来源
浏览器发送请求后,由tomcat服务器接收到,然后对请求的信息进行解析,将解析结果封装到HttpServletRequest和HttpServletResponse两个对象中。
然后tomcat通过反射调用service方法的时候,又将这两个对象传递给了service方法。
2. request对象的特点
-
-
每次请求,tomcat服务器都会重新创建。
-
3. request对象的使用
//获取请求行信息 //获取请求方式 String method = req.getMethod(); System.out.println("请求方式是:" + method); //获取请求的URI String uri = req.getRequestURI(); System.out.println("请求的URI是:" + uri); //获取请求协议 String scheme = req.getScheme(); System.out.println("请求的协议是:" + scheme);
2.request对象获取请求头数据
//获取请求头信息,根据键名去获取 //获取请求的主机信息 String host = req.getHeader("host"); System.out.println("请求的主机信息是:" + host); ------------------------------------------------------------------- //获取所有的请求头信息 //拿到所有请求头的名字 Enumeration<String> headerNames = req.getHeaderNames(); while(headerNames.hasMoreElements()){ String key = headerNames.nextElement(); String value = req.getHeader(key); System.out.println(key + ":" + value); }
3.request对象获取请求体数据
String name = req.getParameter("name"); //getParameterValues()方法可以获取多个参数名一样的数据,会得到一个数组(获取复选框的内容用这种方式) String[] hobbies = req.getParameterValues("hobby"); System.out.println("爱好是:" + Arrays.toString(hobbies));
//获取其他数据 //获取项目路径, 格式是 /项目名 String contextPath = req.getContextPath(); System.out.println("项目路径是:" + contextPath); //获取请求的url地址 String url = req.getRequestURL().toString(); System.out.println("请求的url地址是:" + url); //获取服务器的ip String serverName = req.getServerName(); System.out.println("服务器的ip地址是:" + serverName); //获取服务器的端口 int serverPort = req.getServerPort(); System.out.println("服务器的端口是:" + serverPort); } }
4. 乱码问题
在service方法中设置
req.setCharacterEncoding("utf-8");
注意:要在调用getParameter方法前设置编码
注意:tomcat8.0之后,无论是get请求还是post请求只需要设置req.setCharacterEncoding("utf-8")即可
tomcat8.0前,post请求乱码用req.setCharacterEncoding("utf-8")
get请求用String s = new String(req.getParameter("name").getBytes("iso-8859-1"),"utf-8");
五、响应对象(HttpServletResponse)
1. 介绍
response响应对象用于响应浏览器发起的请求,其中封装了响应结果数据及客户端的一些信息等。
2. 使用
response对象是在服务器收到请求解析完后创建的,之后被传到了我们写的servlet中的service方法中,可以直接使用。
Tomcat底层会将response响应的内容自动转换为HTTP协议的格式,输出给浏览器。
//setHeader()方法作用:设置响应头,key相同的话,后面设置的值会覆盖前面设置的 resp.setHeader("key1", "value1"); resp.setHeader("key2", "value2"); resp.setHeader("key1", "value1_1"); //addHeader()方法作用:设置响应头,key相同的话,后面设置的值不会覆盖前面设置的 resp.addHeader("name1", "value1"); resp.addHeader("name2", "value2"); resp.addHeader("name1", "value1_1"); //下面两行代码是等价的 resp.setContentType("text/html;charset=utf-8");//设置响应的数据类型及解码方式 resp.setHeader("Content-Type", "text/html;charset=utf-8");//设置响应的数据类型及解码方式
3. 注意
-
-
每次请求都会重新创建,请求结束后即销毁。
-
4. 乱码问题
resp.setContentType("text/html;charset=utf-8");
六、@WebServlet注解开发Servlet
在Servlet3.0以及之后的版本中支持注解式开发Servlet。对于Servlet的配置不再依赖于web.xml配置文件,而是使用@WebServlet注解完成Servlet的配置。
属性名 | 类型 | 作用 |
---|---|---|
initParams | WebInitParam[] | Servlet的init参数 |
name | String | Servlet的名称 |
urlPatterns | String[] | Servlet的访问URL,支持多个 |
value | String[] | Servlet的访问URL,支持多个 |
loadOnStartup | int | 自启动Servlet |
description | String |
@WebServlet(name = "first", value = "/first",
loadOnStartup = 1,
initParams = {@WebInitParam(name = "test", value = "aaa")},
description = "测试servlet")
注意:
只指定一个value时,可以省略value
@WebServlet("/请求路径")
515-443-5015
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异