1.maven warehouse
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2. Filter
The English name of Filter is Filter, which is the most practical technology in Servlet Technology.
Like its name, the filter is a filter between the client and server resource files, which helps us filter out some requests that do not meet the requirements. It is usually used as Session verification to judge user permissions. If it does not meet the set conditions, it will be intercepted to a special address or based on a special response.
@Log4j2 public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info("Initialize filter"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response); String requestUri = request.getRequestURI(); log.info("The request address is:"+requestUri); if (requestUri.contains("/addSession") || requestUri.contains("/removeSession") || requestUri.contains("/online") || requestUri.contains("/favicon.ico")) { filterChain.doFilter(servletRequest, response); } else { wrapper.sendRedirect("/online"); } } @Override public void destroy() { //Destroy on service shutdown log.info("Destroy filter"); } }
3. Interceptor
The interceptor in Java is an object that dynamically intercepts the call of an action, and then provides some operations that can be added before and after the action is executed, or the operation can be stopped before the action is executed. The function is similar to that of a filter, but the standard and implementation method are different.
-
Login authentication: in some applications, the user's login status may be verified through the interceptor. If there is no login or login fails, it will give the user a friendly prompt or return to the login page. Of course, this method is not used in large projects. It is to invoke the single sign on system interface to verify the user.
-
Record system log: in common applications, we usually record the user's request information, such as request ip, method execution time, etc. through these records, we can monitor the status of the system, so as to facilitate information monitoring, information statistics, PV calculation, performance tuning, etc.
-
General processing: there may be information to be returned by all methods in the application, which can be realized by interceptors, eliminating the redundant and repeated code implementation of each method.
@Log4j2 @Component public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("[MyInterceptor]Called:{}", request.getRequestURI()); request.setAttribute("requestTime", System.currentTimeMillis()); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (!request.getRequestURI().contains("/online")) { HttpSession session = request.getSession(); String sessionName = (String) session.getAttribute("name"); if ("haixiang".equals(sessionName)) { log.info("[MyInterceptor]The current browser does not exist session:{}",sessionName); } } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { long duration = (System.currentTimeMillis() - (Long)request.getAttribute("requestTime")); log.info("[MyInterceptor][{}]Call time:{}ms",request.getRequestURI(), duration); } }
4. Listener
Listeners are usually used to monitor the sending of actions such as the creation and destruction of objects in Web applications, and deal with the listening situation accordingly. They are most commonly used to count the number of online people and visits of websites.
-
ServletContextListener: used to listen to the operation of ServletContext attribute, such as adding, modifying and deleting.
-
HttpSessionListener: a Session object used to listen to Web applications. It is usually used to count online situations.
-
ServletRequestListener: used to listen to the attribute operation of the Request object.
4.1 use of listener
We use HttpSessionListener to count the current number of online people, ip and other information. In order to avoid concurrency, we use atomic int to count.
ServletContext is a global space for storing information. Its life cycle is consistent with that of the Servlet container, that is, the server. It is destroyed only after the server is shut down.
request, one user can have multiple;
session, one for each user; ServletContext is shared by all users. Therefore, in order to save space and improve efficiency, some necessary and important thread information that all users need to share is safe in ServletContext.
Therefore, it is most appropriate for us to use ServletContext to store the online number sessionCount.
@Log4j2 public class MyHttpSessionListener implements HttpSessionListener { public static AtomicInteger userCount = new AtomicInteger(0); @Override public synchronized void sessionCreated(HttpSessionEvent se) { userCount.getAndIncrement(); se.getSession().getServletContext().setAttribute("sessionCount", userCount.get()); log.info("[Number of people online] increased to:{}",userCount.get()); //Here, you can count the number of accesses in the ServletContext domain object, and then pass in the destruction method of the filter //The database is invoked in the destruction method, because the filter life cycle is consistent with the container. } @Override public synchronized void sessionDestroyed(HttpSessionEvent se) { userCount.getAndDecrement(); se.getSession().getServletContext().setAttribute("sessionCount", userCount.get()); log.info("[Number of people online] reduced to:{}",userCount.get()); } }
Listener listening for requests
public class MyHttpRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("request The listener was destroyed"); } @Override public void requestInitialized(ServletRequestEvent sre) { HttpServletRequest req = (HttpServletRequest) sre.getServletRequest(); String requestURI = req.getRequestURI(); System.out.println(requestURI+"--"+"Called"); } }
5. Instantiation
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor); } /** * Register filter * @return */ @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new MyFilter()); filterRegistration.addUrlPatterns("/*"); return filterRegistration; } /** * Register listener * @return */ @Bean public ServletListenerRegistrationBean registrationBean(){ ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean(); registrationBean.setListener(new MyHttpRequestListener()); registrationBean.setListener(new MyHttpSessionListener()); return registrationBean; } }
6. Test
@RestController public class TestController { @GetMapping("addSession") public String addSession(HttpServletRequest request) { HttpSession session = request.getSession(); session.setAttribute("name", "haixiang"); return "Number of people currently online" + session.getServletContext().getAttribute("sessionCount") + "people"; } @GetMapping("removeSession") public String removeSession(HttpServletRequest request) { HttpSession session = request.getSession(); session.invalidate(); return "Number of people currently online" + session.getServletContext().getAttribute("sessionCount") + "people"; } @GetMapping("online") public String online() { return "Number of people currently online" + MyHttpSessionListener.userCount.get() + "people"; } }
7. Difference between interceptor and filter
standard:
-
Filter is the standard of Java EE, which depends on the Servlet container, and its life cycle is consistent with that of the container. This feature can be used to release resources or store data during destruction.
-
Interceptor is the content in spring MVC and depends on the web framework. It is usually used to verify user permissions or log, but these functions can also be replaced by AOP.
Implementation method:
-
The filter is implemented based on callback function and cannot be injected into bean s in ioc container.
-
The interceptor is implemented based on reflection, so the interceptor can inject bean s in the ioc container, such as the business layer of Redis, to verify whether the user has logged in.