Filter & listener

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

Keywords: Java Front-end Web Development server

Added by rpieszak on Mon, 24 Jan 2022 18:13:59 +0200