Servlet3.0新特性:動態(tài)控制 3 大組件注冊,太方便了!?。?/h1>
Servlet3.0 對于 ServletContext 進(jìn)行了功能增強,可以對 Servlet、Filter 及 Listener 進(jìn)行動態(tài)注冊。所謂動態(tài)注冊是指,Web 應(yīng)用在運行過程中通過代碼對 Servlet、Filter 或 Listener 進(jìn)行注冊。
為了系統(tǒng)安全考慮,這個動態(tài)注冊是有限制的,只能在應(yīng)用啟動時進(jìn)行,而不能在應(yīng)用運行過程中的進(jìn)行注冊。這個應(yīng)用啟動時間點,可以通過 servletContextListener 監(jiān)聽器來把握。
1、動態(tài)注冊 Servlet
比較簡單,直接上代碼,先自定義一個 servlet,這個 servlet 的功能比較簡單,將 servlet 的參數(shù)信息輸出了。
package com.javacode2018.springboot.lesson003;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//將servlet的參數(shù)信息輸出
resp.setContentType("text/html;charset=UTF-8");
Enumeration names = this.getInitParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = this.getInitParameter(name);
resp.getWriter().write(String.format("%s:%s
", name, value));
}
}
}
下面我們自定義一個ServletContextListener,在其contextInitialized方法中通過硬編碼的方式注冊上面自定義的MyServlet,為了演示效果,這里我們通過硬編碼的方式給注冊的 Servlet 設(shè)置了 2 個屬性,稍后訪問 servle 的時候,會被輸出到客戶端。
package com.javacode2018.springboot.lesson003;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.ServletRegistration;
import jakarta.servlet.annotation.WebListener;
//@0:本案例中沒有在web.xml中配置這個Listener,所以需要在MyServletContextListener上加上@WebListener注解,采用注解的方式來注冊Listener
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//@1、獲取ServletContext
ServletContext sc = sce.getServletContext();
//@2、調(diào)用sc.addServlet注冊自定義的Servlet,返回一個ServletRegistration.Dynamic對象
ServletRegistration.Dynamic myServlet = sc.addServlet("myServlet", MyServlet.class);
//@3、通過ServletRegistration.Dynamic對象可以設(shè)置servlet所有配置信息,這里我們只演示了2個方法,還有很多方法大家可以去試試
myServlet.addMapping("/myServlet");
myServlet.setInitParameter("name", "路人");
myServlet.setInitParameter("lesson", "SpringBoot系列!");
}
}
發(fā)布到 tomcat,然后訪問下面地址
http://localhost:8080/myServlet
輸出

2、動態(tài)注冊 Filter
過程和動態(tài)注冊 Servlet 類似,咱們先指定一個 Filter,代碼如下,這個 Filter 需要攔截所有請求,會將每個請求的耗時輸出到控制臺。
package com.javacode2018.springboot.lesson003;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CostTimeFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String url = req.getRequestURL().toString();
long st = System.currentTimeMillis();
try {
super.doFilter(req, res, chain);
} finally {
long costTime = System.currentTimeMillis() - st;
System.out.println(String.format("url:[%s],耗時(ms):[%s]", url, costTime));
}
}
}
注冊的代碼和上注冊 MyServlet 的代碼放在一起,在自定義的MyServletContextListener#contextInitialized方法中追加下面代碼。
//@4、注冊自定義的Filter,返回一個FilterRegistration.Dynamic對象
FilterRegistration.Dynamic costTimeFilter = sc.addFilter("costTimeFilter", CostTimeFilter.class);
//@5、通過FilterRegistration.Dynamic對象可以設(shè)置Filter的所有配置信息
costTimeFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
重啟 tomcat,再次訪問http://localhost:8080/myServlet,tomcat 控制臺輸出
url:[http://localhost:8080/myServlet],耗時(ms):[1]
3、動態(tài)注冊 Listener
這里以 ServletRequestListener 為例來說明,其他的 Listener 注冊方式一樣。
先自定義一個 Listener,如下:
package com.javacode2018.springboot.lesson003;
import jakarta.servlet.ServletRequestEvent;
import jakarta.servlet.ServletRequestListener;
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("MyServletRequestListener注冊成功!");
}
}
注冊 Lisenter 代碼比較簡單,如下,就一行代碼,將其追加在MyServletContextListener#contextInitialized方法中
sc.addListener(MyServletRequestListener.class);
重啟 tomcat,再次訪問http://localhost:8080/myServlet,tomcat 控制臺輸出
MyServletRequestListener注冊成功!
4、源碼
https://gitee.com/javacode2018/springboot-series

5、領(lǐng)取《Spring 系列高清 pdf》


獲取方式,點擊下面鏈接,發(fā)送:spring
6、領(lǐng)取《計算機必讀電子書》
計算機必讀電子書,進(jìn)行了詳細(xì)的分類,自己整理的,絕不是在網(wǎng)上那種打包下載的,而是自己需要學(xué)到某個方向的時候去網(wǎng)上挨個找的,最后匯總而成,這部分我是會不斷把它完善的,當(dāng)成自己的小電子書庫,不多,但貴在精。

獲取方式,掃碼發(fā)送:計算機
瀏覽
25
Servlet3.0 對于 ServletContext 進(jìn)行了功能增強,可以對 Servlet、Filter 及 Listener 進(jìn)行動態(tài)注冊。所謂動態(tài)注冊是指,Web 應(yīng)用在運行過程中通過代碼對 Servlet、Filter 或 Listener 進(jìn)行注冊。
為了系統(tǒng)安全考慮,這個動態(tài)注冊是有限制的,只能在應(yīng)用啟動時進(jìn)行,而不能在應(yīng)用運行過程中的進(jìn)行注冊。這個應(yīng)用啟動時間點,可以通過 servletContextListener 監(jiān)聽器來把握。
1、動態(tài)注冊 Servlet
比較簡單,直接上代碼,先自定義一個 servlet,這個 servlet 的功能比較簡單,將 servlet 的參數(shù)信息輸出了。
package com.javacode2018.springboot.lesson003;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//將servlet的參數(shù)信息輸出
resp.setContentType("text/html;charset=UTF-8");
Enumeration names = this.getInitParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = this.getInitParameter(name);
resp.getWriter().write(String.format("%s:%s
", name, value));
}
}
}
下面我們自定義一個ServletContextListener,在其contextInitialized方法中通過硬編碼的方式注冊上面自定義的MyServlet,為了演示效果,這里我們通過硬編碼的方式給注冊的 Servlet 設(shè)置了 2 個屬性,稍后訪問 servle 的時候,會被輸出到客戶端。
package com.javacode2018.springboot.lesson003;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.ServletRegistration;
import jakarta.servlet.annotation.WebListener;
//@0:本案例中沒有在web.xml中配置這個Listener,所以需要在MyServletContextListener上加上@WebListener注解,采用注解的方式來注冊Listener
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//@1、獲取ServletContext
ServletContext sc = sce.getServletContext();
//@2、調(diào)用sc.addServlet注冊自定義的Servlet,返回一個ServletRegistration.Dynamic對象
ServletRegistration.Dynamic myServlet = sc.addServlet("myServlet", MyServlet.class);
//@3、通過ServletRegistration.Dynamic對象可以設(shè)置servlet所有配置信息,這里我們只演示了2個方法,還有很多方法大家可以去試試
myServlet.addMapping("/myServlet");
myServlet.setInitParameter("name", "路人");
myServlet.setInitParameter("lesson", "SpringBoot系列!");
}
}
發(fā)布到 tomcat,然后訪問下面地址
http://localhost:8080/myServlet
輸出

2、動態(tài)注冊 Filter
過程和動態(tài)注冊 Servlet 類似,咱們先指定一個 Filter,代碼如下,這個 Filter 需要攔截所有請求,會將每個請求的耗時輸出到控制臺。
package com.javacode2018.springboot.lesson003;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CostTimeFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String url = req.getRequestURL().toString();
long st = System.currentTimeMillis();
try {
super.doFilter(req, res, chain);
} finally {
long costTime = System.currentTimeMillis() - st;
System.out.println(String.format("url:[%s],耗時(ms):[%s]", url, costTime));
}
}
}
注冊的代碼和上注冊 MyServlet 的代碼放在一起,在自定義的MyServletContextListener#contextInitialized方法中追加下面代碼。
//@4、注冊自定義的Filter,返回一個FilterRegistration.Dynamic對象
FilterRegistration.Dynamic costTimeFilter = sc.addFilter("costTimeFilter", CostTimeFilter.class);
//@5、通過FilterRegistration.Dynamic對象可以設(shè)置Filter的所有配置信息
costTimeFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
重啟 tomcat,再次訪問http://localhost:8080/myServlet,tomcat 控制臺輸出
url:[http://localhost:8080/myServlet],耗時(ms):[1]
3、動態(tài)注冊 Listener
這里以 ServletRequestListener 為例來說明,其他的 Listener 注冊方式一樣。
先自定義一個 Listener,如下:
package com.javacode2018.springboot.lesson003;
import jakarta.servlet.ServletRequestEvent;
import jakarta.servlet.ServletRequestListener;
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("MyServletRequestListener注冊成功!");
}
}
注冊 Lisenter 代碼比較簡單,如下,就一行代碼,將其追加在MyServletContextListener#contextInitialized方法中
sc.addListener(MyServletRequestListener.class);
重啟 tomcat,再次訪問http://localhost:8080/myServlet,tomcat 控制臺輸出
MyServletRequestListener注冊成功!
4、源碼
https://gitee.com/javacode2018/springboot-series

5、領(lǐng)取《Spring 系列高清 pdf》


獲取方式,點擊下面鏈接,發(fā)送:spring
6、領(lǐng)取《計算機必讀電子書》
計算機必讀電子書,進(jìn)行了詳細(xì)的分類,自己整理的,絕不是在網(wǎng)上那種打包下載的,而是自己需要學(xué)到某個方向的時候去網(wǎng)上挨個找的,最后匯總而成,這部分我是會不斷把它完善的,當(dāng)成自己的小電子書庫,不多,但貴在精。

獲取方式,掃碼發(fā)送:計算機
