filter
Filter introduction
What is a filter
Examples in life:
Strainer, sieve, fishing net
Filter in life: eliminate what we don't need, leave what we need.
The concept of filter in Java Web: the object that intercepts or enhances requests and responses is a filter. (key points)
What are the filters in the Java Web?
Filter interface: function - to enhance or intercept requests and responses.
Filter operation diagram in Java Web (emphasis)
Quick start to Filter (key: must master)
Filter definition and creation steps
Define a filter: * step 1: create a class to implement the filter interface * step 2: write the specific filtering tasks to be performed in doFilter * step 3: the filter needs to be on the web Configuration in XML
Code demonstration:
package cn.wit.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * * Filter Is configured in the deployment descriptor of the Web application * * Deployment descriptor: Web xml * * Define a filter: * Step 1: create a class to implement the filter interface * Step 2: write the specific filtering tasks to be performed in doFilter * Step 3: the filter needs to be on the web Configuration in XML * */ public class MyFilter implements Filter{ /** * Initialization method * */ @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } /** * Method of performing filtering task * */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("MyFilter....doFilter....."); } /** * Method of destruction * */ @Override public void destroy() { // TODO Auto-generated method stub } }
The Filter is configured in the deployment descriptor of the Web application -- after the Filter is created, it needs to be displayed on the Web Configuration in XML
On the web Configuring filters in XML files
<filter> <filter-name>MyFilter</filter-name> <filter-class>cn.wit.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/1.txt</url-pattern> </filter-mapping>
Filter interception effect
Object of filter release: introduction to FilterChain function
Conclusion: filter release depends on it
doFilter method of FilterChain:
code implementation
effect:
Filter release execution process:
Filter lifecycle
Review the servlet lifecycle:
Create: when first accessed
Destroy: when the server is shut down, or the current project is removed from the server
Review the session lifecycle:
Create: call getsession method for the first time and access jsp for the first time
Destroy: if the server is shut down abnormally and the survival time is exceeded, call the destroy method
Filter:
Create: when the server starts
Screenshot of server startup:
Destroy: the filter is destroyed when the server is shut down.
Screenshot of server shutdown:
Introduction to FilterConfig
servletConfig object: get servlet related configuration information.
FilterConfig definition: get the configuration information related to filter.
API introduction:
API code demonstration:
1) Set filter initialization parameters
2) Get the parameters through the filterconfig object
Parameter configuration:
<filter> <filter-name>MyFilter</filter-name> <filter-class>cn.wit.filter.MyFilter</filter-class> <init-param> <param-name>haha</param-name> <param-value>ha-ha</param-value> </init-param> <init-param> <param-name>heihei</param-name> <param-value>hey</param-value> </init-param> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/1.txt</url-pattern> </filter-mapping>
Effect demonstration:
Detailed explanation of Filter configuration (configuration in web.xml) (key)
About URL pattern configuration
How does the filter match the requested path?
Review the URL pattern of the servlet:
Full path matching——
Address bar: localhost:8080 / project root path / resource path localhost:8080 / wit Filter2 / 1 txt
Wildcard matching——
Address bar: localhost:8080 / project root path / abc/*
For the above two matching methods, the path must start with "/" when configuring
Suffix matching - * do: *.do *.txt *.action
Address bar: localhost:8080 / project root path / * txt
Suffix matching method. When configuring the path, it cannot start with "/"
The URL pattern configuration of the Filter is consistent with that of the servlet.
Filter execution order?
Test method:
1) Two filters to intercept the same request
2) Adjust the configuration of the two filters to see the order of execution
Summary:
The filter is executed in the order of, web The writing order of filter mapping tags in XML is executed (from top to bottom)
About filter name configuration
What is a filter name configuration?
Definition: configuration for intercepting or enhancing operations against a specified servlet
Servlet:
package cn.wit.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DemoServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("DemoServlet....doGet....."); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Filter:
package cn.wit.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class DemoFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("DemoFilter.....doFilter...."); chain.doFilter(request, response); } @Override public void destroy() { } }
Web.xml configuration:
<filter> <filter-name>demoFilter</filter-name> <filter-class>cn.wit.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>demoFilter</filter-name> <url-pattern>/demo</url-pattern> </filter-mapping>
effect:
Case 2 – solve the garbled code in the shop project
Requirements: the request parameters are processed separately in each servlet, and the code is repeated
The idea of optimization is to use a filter to set and encode the request object before the request reaches the servlet
All requests should be encoded, intercepted and enhanced. URL pattern:/*
Filter code:
package cn.wit.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class EncodingFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse res = (HttpServletResponse)response; //Handle garbled code, handle post request garbled code req.setCharacterEncoding("utf-8"); chain.doFilter(req, res); } @Override public void destroy() { } }
Web.xml configuration:
Realize the complete version of garbled code processing, filter:
Step 1: there should also be a filter for the task of garbled processing of requests (enhancement task), which is written in the doFilter method
Supplement (decoration (packaging) design mode method):
\1) Define a class that implements the interface of the decorated object
\2) Define a member variable and remember the reference of the decorated object
\3) Define the construction method and pass in the instance of the decorated object
\4) Overwrite the method you want to modify
\5) The method that does not need to be rewritten calls the original method of the decorated object
Complex filter implementation:
package cn.wit.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.wit.domain.MyRequest; public class EncodingFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Handle Chinese garbled code for requests and responses HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse res = (HttpServletResponse)response; res.setContentType("text/html;charset=utf-8"); //For different request modes, deal with garbled code, use a new request object, and deal with garbled code in the new request object //The req object in the constructor is set to ensure that the data in the request is obtained and then the garbled code is processed MyRequest myRequest = new MyRequest(req); //Test get request parameters System.out.println("name1:"+myRequest.getParameter("name")); System.out.println("name2:"+myRequest.getParameter("name")); //Processing completed requests and responses are garbled and only need to be released chain.doFilter(myRequest, res); } @Override public void destroy() { } }
Custom enhancement class:
package cn.wit.domain; import java.io.UnsupportedEncodingException; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; /** * @author yanyue * * @time 2017 May 26 * * MyRequest How to achieve: * * 1 Implement httpservletrequest interface -- by inheriting HttpServletRequestWrapper * 2 Set a variable to hold the request object created by the server * 3 To deal with garbled code is to rewrite the three methods to obtain request parameters * 4 Do not need to rewrite the method, use the original object method */ public class MyRequest extends HttpServletRequestWrapper{ //The request parameters in the request object created by the server can be used later //Set a variable to hold the request object created by the server private HttpServletRequest request ; //Define a tag to control the number of encoding and execute it only once private boolean flag = false; public MyRequest(HttpServletRequest request) { super(request); this.request = request; } @Override public Map<String, String[]> getParameterMap() { //Get the request mode and deal with garbled code according to different modes String method = request.getMethod(); if(method.equalsIgnoreCase("post")){ try { request.setCharacterEncoding("utf-8"); return request.getParameterMap(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return super.getParameterMap(); } }else if(method.equalsIgnoreCase("get")){ //Get all the request parameters, and then deal with the garbled code one by one Map<String, String[]> map = request.getParameterMap(); //If you control the coding, let him execute it only once? //flag is false by default, so execute next //flag is executed for the second time, true. It ends directly and is not executed. if(flag){ return map; } //Get data from variable map collection if(map != null){ for(String key :map.keySet()){ String[] values = map.get(key); if(values != null){ for (int i = 0; i < values.length; i++) { try { String string = new String(values[i].getBytes("iso-8859-1"),"utf-8"); values[i] = string; } catch (UnsupportedEncodingException e) { e.printStackTrace(); //If there is an exception, I hope that the data that has not been circulated in the future will continue to process the garbled code //End the current cycle and start the next cycle continue; } } } } } flag = true; return map; }else{ return super.getParameterMap(); } } @Override public String[] getParameterValues(String name) { Map<String, String[]> map = this.getParameterMap(); if(map != null){ String[] values = map.get(name); return values; } return super.getParameterValues(name); } @Override public String getParameter(String name) { String[] values = this.getParameterValues(name); if(values != null){ return values[0]; } return super.getParameter(name); } }
Note: finally, there is the code to remove the original setting code
monitor
Listener introduction
What is a listener
Listener: listen to the event source and make corresponding processing according to the events on the event source.
Related concepts of monitoring mechanism
Event source: the source of the event and the object that the listener needs to listen to.
Event: the action that occurs on the event source and the content monitored by the listener.
Listener: the object responsible for listening to the event source.
Introduction to web listener
Introduction to Java Web listener
Listeners in Java Web mainly listen to various changes of request, session and ServletContext objects in Java Web.
Main monitoring tasks:
Listen for the creation and destruction of request, ServletContext and session objects
ServletRequestListener
ServletContextListener
HttpSessionListener
Listen for data changes stored in request, session and ServletContext objects
ServletContextAttributeListener
HttpSessionAttributeListener
ServletRequestAttributeListener
Listen for the state of the JavaBean saved in the session
HttpSessionBindingListener
HttpSessionActivationListener
Java Web listener creation steps (example: ServletRequestListener)
You need to define a class to implement the corresponding listener interface
ServletRequestListener definition (API screenshot):
Code demonstration:
package cn.wit.listener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; public class MyServletRequestListener implements ServletRequestListener{ @Override //Method for listening to request object destruction public void requestDestroyed(ServletRequestEvent sre) { System.out.println("MyServletRequestListener.....requestDestroyed...."); } @Override //Method for listening to request object initialization public void requestInitialized(ServletRequestEvent sre) { System.out.println("MyServletRequestListener.....requestInitialized...."); } }
Configure listener object
Note: when the server loads the project, it reads the web If the listener tag is in the XML file, the server will automatically create the listener object and call its methods
Automatically calling its method is also called through reflection (because its method name and parameters are fixed)
Summary of listener:
1) Create a class to implement the listener interface
2) In the method of the listener object, write the relevant code
3) On the web Configure the current listener in XML.
ServletContext create destroy listener
ServletContextListener definition (API screenshot):
Code demonstration:
package cn.wit.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class MyServletContextListener implements ServletContextListener{ @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("MyServletContextListener.....contextInitialized...."); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("MyServletContextListener.....contextDestroyed...."); } }
Listener configuration:
<listener> <listener-class>cn.wit.listener.MyServletContextListener</listener-class> </listener>
Screenshot of listening servletcontext object initialization:
Screenshot of listening servletcontext object destruction:
ServletContextListener case: scheduled tasks
Requirement: when the project starts, obtain the server time (new Date()), update it every second, and print it on the console
Idea:
1) Monitor the startup of the project (use ServletContextListener to listen for the initialization of ServletContext object)
1) Get server time: new Date();
2) Update every second: Timer
4) Set a scheduled task for the timer
Timer: timer task scheduling object
Task: timer task (class)
delay: when to start execution. Immediate execution is set to: 0
period: the interval of repeated execution, in milliseconds, 1 second = 1000 milliseconds
TimerTask: timer task (class)
Our scheduled task should be written in the Run method: update the time every second and print it on the console
Code implementation:
package cn.wit.listener; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; /** * @author wjn * 1) Create a class to implement the listener interface 2) In the method of the listener object, write the relevant code 3) On the web Configure the current listener in XML. */ public class MyServletContextListener implements ServletContextListener{ @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("MyServletContextListener....contextInitialized..."); //Monitor the startup of the project (use ServletContextListener to listen for the initialization of ServletContext object) //2) Get server time: new Date(); //3) Update every second: Timer //4) Set a scheduled task for the timer //Get timer Timer timer = new Timer(); //Method of calling timer to set timing task //firstTime 0: execute now //period: how often to execute, 1000 timer.schedule(new TimerTask() { @Override public void run() { //In the run method, write the task to be executed //Outdated methods are generally not recommended. However, the jdk will not delete the effects of outdated methods. //For the current display time, you can use the time in the server - java code, new Date(); //Current display time - javascript code, new Date(); //javascript code is the time when the browser runs on the client, which is generally the time when the client is not used //Business: whole point second kill //Get the server time, the user, there is no way to control //Obtain the client time. The time is controlled by the client. The time is wrong //Generally follow the principle that as long as it can be controlled on the server, it will never be given to the client System.out.println(new Date().toLocaleString()); } }, 0, 1000); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("MyServletContextListener....contextDestroyed..."); } }
effect:
The HttpSessionListener object listens to the creation and destruction of a session
HttpSessionListener definition (API screenshot):
Code demonstration:
package cn.wit.listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class MyHttpSessionListener implements HttpSessionListener{ @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("MyHttpSessionListener....sessionCreated...."); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("MyHttpSessionListener....sessionDestroyed...."); } }
Profile:
<listener> <listener-class>cn.wit.listener.MyHttpSessionListener</listener-class> </listener>
Invalidate.jsp page code:
Effect screenshot:
Case - count the number of people online
Demand: how many people are currently visiting the website?
Question: when can we know that users have visited the website?
As long as the user visits our website, the session will be created. As long as the user leaves, click exit (logout), and the session will be destroyed.
Idea:
As long as you judge the creation of the session, the number of online people will be increased by one
As long as you judge that the session is destroyed, the number of online users will be reduced by one
Where should the data of online population exist?
A: in the ServletContext object, all application scopes can be obtained, and all users accessing the current website should be able to see the number of online users
General idea:
1. When the project starts, initialize the online number 0 and save it in the ServletContext
2. Add one to the session creation data
3 minus one if the session destroys the data
4 display data on the page
Code implementation:
Listener Code:
package cn.wit.listener; import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("MyHttpSessionListener....sessionCreated...."); // In the listener, as long as you judge the creation of the session, the number of online people will be increased by one ServletContext context = se.getSession().getServletContext(); // Get the number of online people inside Integer onlineNum = (Integer) context.getAttribute("onlineNum"); onlineNum = onlineNum + 1; context.setAttribute("onlineNum", onlineNum); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("MyHttpSessionListener....sessionDestroyed...."); // In the listener, as long as you judge that the session is destroyed, the number of online people will be subtracted by one ServletContext context = se.getSession().getServletContext(); // Get the number of online people inside Integer onlineNum = (Integer) context.getAttribute("onlineNum"); onlineNum = onlineNum - 1; context.setAttribute("onlineNum", onlineNum); } }
index.jsp displays the number of people online and the exit link:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> wit-filter2 Project Home <br> Number of people currently online: ${onlineNum } <a href="${pageContext.request.contextPath }/validate.jsp">sign out</a> </body> </html>
Page effect:
Listening for attribute changes
Introduction to attribute listener
It mainly uses setAttribute and removeAttribute methods for listening.
ServletContextAttributeListener is specifically used to listen for changes in attributes in ServletContext objects
HttpSessionAttributeListener is specifically used to listen for changes in attributes in the session object
ServletRequestAttributeListener is specifically used to listen for changes in attributes in the request object
The names of listening addition, deletion and modification methods in them are the same:
Code demonstration:
Jsp:
<% session.setAttribute("name", "First uncle"); session.replaceAttribute("name", "Second uncle"); session.removeAttribute("name"); %>
monitor:
package cn.wit.listener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener { @Override public void attributeAdded(HttpSessionBindingEvent se) { System.out.println("MyHttpSessionAttributeListener....attributeAdded..."); } @Override public void attributeRemoved(HttpSessionBindingEvent se) { System.out.println("MyHttpSessionAttributeListener....attributeRemoved..."); } @Override public void attributeReplaced(HttpSessionBindingEvent se) { System.out.println("MyHttpSessionAttributeListener....attributeReplaced..."); } }
Profile:
<listener> <listener-class>cn.wit.listener.MyHttpSessionAttributeListener</listener-class> </listener>
The bean(JavaBean) in the Session listens
When we save a Java object in the Session, or remove the Java object from the Session, we will trigger the methods in the listener specially used to listen for object changes in the Session. The object that owns this method -- the HttpSessionBindingListener interface
Differences between attribute listening and bean listening:
Attribute monitoring: it monitors the changes of any attribute (including object, non object data and basic type data) in the three containers
Bean listening: it only listens to the process of saving java bean objects into and out of a session.
Since HttpSessionBindingListener is used to listen to the binding (stored in the session container) and unbinding (removed from the session container) of a JavaBean object, the implementation class of this listener must be the JavaBean being operated on (HttpSessionBindingListener does not need to be configured in web.xml)
javaBean:
package cn.wit.domain; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; public class User implements HttpSessionBindingListener{ private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [age=" + age + ", name=" + name + "]"; } @Override public void valueBound(HttpSessionBindingEvent event) { System.out.println("User....valueBound..."); } @Override public void valueUnbound(HttpSessionBindingEvent event) { System.out.println("User....valueUnbound..."); } }
JSP:
<% session.setAttribute("user", new User()); session.removeAttribute("user"); %>
effect:
Bean monitoring requirements:
The number of online people can be increased or decreased according to the creation and destruction of the session.
Online membership statistics:
1) The User class implements the bean listening interface
2) Each time the loginUser object is bound to the session, the number of members is increased by one
3) Every time the loginUser object is unbound, the number of members will be reduced by one