servlet生命周期
初识interface Servlet
接口
public interface Servlet {
//初始化调用(只会调用一次)
void init(ServletConfig var1) throws ServletException;
//获取ServletConfig域
ServletConfig getServletConfig();
//每次请求会调用service方法
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
//销毁时调用(只会调用一次)
void destroy();
}
HttpServlet抽象方法(GenericServlet imp Servlet)
//5 注意 你的sevlet尽量只对do*方法进行重写,例如doGet、doPost方法, 不去重写service方法,HttpServlet中的service方法对Get资源请求做了时间的限定,让客户端不用每次Get请求都进行资源的加载,对于大量静态资源的情况节省了客户端相应时间,也对服务器资源消耗做到一定上减少
public abstract class HttpServlet extends GenericServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
//1.获得Last-Modified上次修改时间
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
//2.If-Modified-Since 最后可能修改资源的时间
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if (ifModifiedSince < lastModified / 1000L * 1000L) {
//3.请求的资源在If-Modified-Since时间之后情况下才会将资源返回
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
//4.如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的 304 响应
resp.setStatus(304);
}
}
} else if (method.equals("POST")) {
this.doPost(req, resp);
}
}
}
一个Servlet
继承HttpServlet
public class servlet_dome extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
访问方式
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—name=servlet的名称
servlet-class=servlet类路径
servlet-mapping:servlet映射路径
servlet—name=servlet的servlet-nmae
url-pattern= the URL patterns of the servlet
-->
<servlet>
<servlet-name>servlet</servlet-name>
<servlet-class>com.test.servletdome.servlet_dome</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet</servlet-name>
<url-pattern>/servlet_01.do</url-pattern>
</servlet-mapping>
</web-app>
注解方式
import javax.servlet.annotation.WebServlet;
@WebServlet(name = "servlet_dome02",urlPatterns = "/servlet_02.do")
//name=servlet-name,urlPatterns=vlue=url-pattern
public class servlet_dome02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print("Hi! this is servlet_dome02");
}
}
三大域对象
请求对象域
请求对象方法
以下对域对象操作方法
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
getParameter | 获取前端请求的参数。(Get时获取url上?后的键值对,Post时获取请求体中的键值对) | String key | String value | ServletRequestWrapper |
parameterNames | 获取前端所有请求参数名的迭代器(通过hasMoreElements和nextElement迭代获取参数) | 无 | Enumeration | ServletRequestWrapper |
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("name","小明");
System.out.println("获取req域中属性值:name:"+req.getAttribute("name"));
}
以下对请求参数获取
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
setAttribute | 向req域中添加属性 | String var1, Object var2 | 无 | ServletRequestWrapper |
getAttribute | 获取req域中添加 的属性 | String var1 | Object | ServletRequestWrapper |
getAttributeNames | 获取req域中所有属性的参数名的迭代器(通过hasMoreElements和nextElement迭代获取参数) | 无 | Enumeration | ServletRequestWrapper |
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String parameter = req.getParameter("username");
System.out.println("获取前端传入属性值username:"+parameter);
Enumeration<String> parameterNames = req.getParameterNames();
while (parameterNames.hasMoreElements()){
System.out.println("获取前端所有属性名:"+parameterNames.nextElement());
}
}
以下为获取路径的几个方法
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
getContextPath | 当前项目根路径 | 无 | String | ServletRequestWrapper |
getRequestURL | 请求全路径URL | 无 | StringBuffer | ServletRequestWrapper |
getRequestURI | 请求路径 | 无 | String | ServletRequestWrapper |
getServletPath | servlet路径名 | 无 | String | ServletRequestWrapper |
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("当前项目根路径:"+req.getContextPath());
System.out.println("请求全路径URL:"+req.getRequestURL());
System.out.println("请求路径:"+req.getRequestURI());
System.out.println("servlet路径名:"+req.getServletPath());
}
req其他方法
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
getCookies | 获取前端传过来的所有cookie | 无 | Cookie[] | ServletRequestWrapper |
getSession | 创建一个cookie,名字为JSESSIONID,并返回一个HttpSession对象 | 无 | HttpSession | ServletRequestWrapper |
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//cookie 操作
Cookie cookie = new Cookie("cookie","thisiscooki01");
resp.addCookie(cookie);
Cookie[] cookies = req.getCookies();
for (Cookie c:cookies){
System.out.println("cookie is name :"+c.getName());
System.out.println("cookis is value:"+c.getValue());
}
//session 操作
HttpSession session = req.getSession();
}
响应对象方法
响应头操作
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
setHeader | 添加响应头 | String var1, String var2 | 无 | |
getHeaderNames | 过去所有响应头列表 | 无 | Collection |
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("hname","this is hname");
resp.setHeader("htype","this is htype");
System.out.println(resp.getHeader("hname"));
Collection<String> headerNames = resp.getHeaderNames();
System.out.println(Arrays.toString(headerNames.toArray()));
}
设置响应编码
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
setCharacterEncoding | 设置返回响应字符编码 | String var1 | 无 |
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("ISO-8859-1");
}
响应类容
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
getWriter | 返回一个操作流PrintWriter | 无 | PrintWriter |
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("hello word!");
}
添加cookie操作
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
addCookie | 在响应头中添加一个cookie,其中对cookie响应做了一定的限制 | Cookie | 无 |
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("cookie","thisiscooki01");
resp.addCookie(cookie);
}
请求与转发
session域
cookie and session
什么是cookie:客户端的文本数据,一般和seeion一起使用
什么是session:存储在服务端的文本数据,用来确认用户的真实性(比如不用重复登陆同一个网站)放在响应头cookie中传给客户端
如何获取cookie
//注意:cookie中的key 不能为Comment、Discard、Domain、Expires、Max-Age、Path、Secure、Version、和包含$,且每个字符中不能包含`c < ' ' || c >= 127 || ",; "`,错误为:cookie_name_is_token
Cookie cookie = new Cookie("cookie","thisiscookie01");//可以添加
//调用resp.addCookie(cookie)添加cookie时value也不能包含空格:以下为错误示范
Cookie cookie = new Cookie("cookie","this is cookie 01");
resp.addCookie(cookie);
//添加失败:java.lang.IllegalArgumentException: Cookie值中存在无效字符
如何获取session
HttpSession session = req.getSession();
cookie的方法
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
setMaxAge | 设置cookie最大保存时间 | int expiry | 无 | |
getMaxAge | 获取cookie最大保存时间 | 无 | int | |
setSecure | 传入true为只对安全协议发送cookie,如https,ssl,缺省值false | boolean flag | 无 | |
getSecure | 获取客户端是否是安全协议 | 无 | boolean |
session方法
session操作域对象
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
setAttribute | 在session域中添加对象 | String var1, Object var2 | 无 | |
getAttribute | 获取session域中的某个对象 | String var1 | Object | |
getAttributeNames | 获取session域中所有参数名的迭代器(通过hasMoreElements和nextElement迭代获取参数) | 无 | Enumeration | |
removeAttribute | 删除某个对象 | String var1 | 无 |
session会话时间
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
setMaxInactiveInterval | 指定servlet容器将使会话失效之前客户机请求之间的时间(以秒为单位) | int var1 | 无 | |
getMaxInactiveInterval | 获取指定的失效时间 | 无 | int |
context域
如何获取context
ServletContext servletContext = req.getServletContext();
context方法
方法名 | 作用 | 传入参数 | 返回参数 | 实现类 |
---|---|---|---|---|
setAttribute | context域中添加对象 | String var1, Object var2 | 无 | |
getAttribute | 获取context域中对象 | String var1 | Object | |
getAttributeNames | 获取context域中所有参数名的迭代器(通过hasMoreElements和nextElement迭代获取参数) | 无 | Enumeration | |
removeAttribute | 删除context域中对象 | String var1 | 无 |
过滤器
初识Filter
public interface Filter {
//项目启动时触发,且一次
void init(FilterConfig var1) throws ServletException;
//每次被过滤的servlet被请求时触发
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
//项目关闭时触发
void destroy();
}
一个Filter
实现Filter
public class Filter_dome01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("invoke filter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("invoke dofilter");
}
@Override
public void destroy() {
System.out.println("invoke filter destroy");
}
}
XML方式
<filter>
<filter-name>filter02</filter-name>
<filter-class>com.test.servletdome.filter.Filter_dome02</filter-class>
</filter>
<filter-mapping>
<filter-name>filter02</filter-name>
<servlet-name>servlet</servlet-name>
<!-- <url-pattern>/*</url-pattern> -->
</filter-mapping>
注解方式
@WebFilter(filterName = "filter01",urlPatterns = "/*")
public class Filter_dome01 implements Filter {
}
filter如何放行
了解责任链模式
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("invoke dofilter");
//调用filterChain方法给下一个filter或servlet
filterChain.doFilter(servletRequest,servletResponse);
}
多个filter执行顺序问题
xml方式根据filter书写的排列顺序执行
<filter>
<filter-name>filter02</filter-name>
<filter-class>com.test.servletdome.filter.Filter_dome02</filter-class>
</filter>
<filter-mapping>
<filter-name>filter02</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>filter01</filter-name>
<filter-class>com.test.servletdome.filter.Filter_dome01</filter-class>
</filter>
<filter-mapping>
<filter-name>filter01</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注解的方式,根据filtername的ASCII码顺序来执行
//类Filter01,filterName=me2
@WebFilter(urlPatterns = "/*",filterName = "me2")
public class Filter01 implements Filter {}
//类Filter02,filterName=me1
@WebFilter(urlPatterns = "/*",filterName = "me1")
public class Filter02 implements Filter {}
监听器
监听器模式
三大监听对象
对三大域对象进行监听
ServletRequestListener
public interface ServletRequestListener extends EventListener {
//项目关闭时执行
void requestDestroyed(ServletRequestEvent var1);
//servlet执行init方法时执行,一般不配置项目启动时创建servlet,就是servlet第一次访问时执行
void requestInitialized(ServletRequestEvent var1);
}
HttpSessionListener
public interface HttpSessionListener extends EventListener {
//每一个会话创建时执行
void sessionCreated(HttpSessionEvent var1);
//项目关闭时执行
void sessionDestroyed(HttpSessionEvent var1);
}
ServletContextListener
public interface ServletContextListener extends EventListener {
//项目启动时执行
void contextInitialized(ServletContextEvent var1);
//项目关闭时执行
void contextDestroyed(ServletContextEvent var1);
}
一个监听器
实现三大监听对象,下面已ServletRequestListener为例
public class Listener_dome01 implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("Destroyed: this is ServletRequestListener");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("Initialized: this is ServletRequestListener");
}
}
监听器与Servlet进行绑定
XML形式
<listener>
<listener-class>com.test.servletdome.listener.Listener_dome02</listener-class>
</listener>
注释形式
@WebListener
public class Listener_dome03 implements ServletRequestListener{
}
监听器的使用请看这位博主博文
Servlet、Filter、Listener执行顺序
项目启动时执行顺序
- ServletContextListener init -> Filter init
Initialized: this is ServletContextListener
invoke filter_02 init
invoke filter init
请求servlet 执行顺序
- Initialized: this is ServletRequestListener -> Servlet init -> doFilter-> servlet doGet/service -> Created: this is HttpSessionListener -> Destroyed: this is ServletRequestListener
Initialized: this is ServletRequestListener
invoke servlet init
invoke dofilter02
invoke dofilter
invoke servlet doGet
Created: this is HttpSessionListener
Destroyed: this is ServletRequestListener
项目关闭时执行顺序
- Servlet destroy -> Filter destroy -> Destroyed: this is ServletContextListener
invoke servlet destroy
invoke filter_02 destroy
invoke filter destroy
Destroyed: this is ServletContextListener
结语
你好!^ _ ^ 谢谢你能看到这里
如果你对文章类容有不同看发或文章类容存在错误,请在下方评论处指出,谢谢^ _ ^
你好!如果文章符合你的胃口,你是否愿意点个赞呢?
你好!如果文章对你有帮助,你不妨分享出去,让更多人成长!
如果文章让你喜欢,不妨点个关注交个朋友,一起共同学习!
谢谢,你的点赞,关注,分享是对我写文章不小的动力!!!