Today we are going to write a common filter and listener in your project.

1. Filter

Filters: Yesjavax.servlet.FilterThe class of the interface

Principle: Filters can intercept requests and responses from clients, and process the requests and responses.

Execution process: Request <-> Servlet container <-> filter 1<-> filter 2<-> filter n<-> Servlet container <->servlet

Three important methods in the Filter interface

Execution process:

When the Web program starts, the servlet creates each filter instance based on the configuration file in web.xml, which filters requests in the URL based on the configuration

When you configure filters, you can map them toURL path patternAnd ` ` ` Servlet name

In web. XML, the following formula is used to configure filter:

<filter> <filter-name>characterFilter</filter-name> <filter-class>com.yueqian.store.filter.characterFilter</filter-class> </filter> <! -- The order of Filter execution is related to the order of filter-mapping. Multiple Dispatchers can be set to indicate which requests need to be filtered. -> <filter-mapping> <filter-name>characterFilter</filter-name> <url-pattern> <servlet-name>userServlet</servlet-name> <dispatcher>REQUEST</dispatcher> </filter-mapping>Copy the code
  • Do, / XXX /*, and/XXX /*. Do

    2. Url mapping takes precedence over servlet name mapping filters, but only one of the two can occur.

Application of filters

  • 1. Set the character encoding
package com.yueqian.store.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.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;

@WebFilter("/ *")
public class characterFilter implements Filter{

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("Filter instance is executed by filtering..."); / / set the request and response code request. SetCharacterEncoding ("UTF-8");
		response.setCharacterEncoding("UTF-8"); chain.doFilter(request, response); } @override public void Overridedestroy() {
		System.out.println("Filter instance destroyed...");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("Filter instance initialized..."); }}Copy the code
  • 2. Log and operation time consumption
package com.yueqian.store.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.annotation.WebFilter;

@WebFilter("/ *")
public class LogFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		String remote = request.getRemoteAddr()+":"+request.getRemoteHost()+":"+request.getRemotePort();
		long start = System.currentTimeMillis();
		chain.doFilter(request, response);
		long end = System.currentTimeMillis();
		System.out.println(remote+"Executed."+(end-start)+"毫秒!");
	}

	@Override
	public void destroy() {
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
}
Copy the code
  • 3. User permission Verification (important)
package com.yueqian.store.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.yueqian.store.common.Constans;
@WebFilter("/ *"// The order of execution of filters using annotations is dictionary by class name /** * to filter login requests * @author LinChi
 *
 */
public class LoginFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest rep = (HttpServletRequest)request; HttpServletResponse resp = (HttpServletResponse)response; String uri = rep.getrequesturi ();if(uri.contains("login.jsp") || uri.contains("register.jsp") || uri.contains("nologin.jsp")
				|| uri.endsWith(".jpg") || uri.endsWith(".css") || uri.endsWith(".jpeg") || uri.endsWith(".js")
				|| uri.contains("/user/login") || uri.contains("/user/logout") || uri.contains("/user/register")
				|| uri.contains("/verify")) { chain.doFilter(request, response); // pass the resource files that do not need to be checkedreturn;
		}
		Object login = rep.getSession().getAttribute(Constans.SESSION_LOGINED_INFO);
		if(login == null) {
			resp.sendRedirect(rep.getContextPath()+"/login.jsp");
		}else{ chain.doFilter(request, response); }}}Copy the code

2. Listener

Common listeners have three interfaces

  • 1. ServletContextListener interface: Listens for the life cycle of the servletContext class when the entire Web application starts and dies.

To enable and disable the database connection pool

package com.yueqian.store.listener; import java.util.LinkedList; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import com.yueqian.store.common.Constans; import com.yueqian.store.common.DBUtils; /** * Application context listeners (listening for creation and destruction of Servletontext objects) * listen for actions when the entire server is opened and closed * @author LinChi
 *
 */
@WebListener
public class ApplicationListener implements ServletContextListener {

	@Override
	public void contextDestroyed(ServletContextEvent event) {
		System.out.println("Database connection pool down..."); // Close the database connection pool dbutils.closedatasourse () at the end of the program; } @Override public void contextInitialized(ServletContextEvent event) { System.out.println("Database connection pool enabled..."); // Initialize database connection pool dbutils.init (); // Add a list to the servletContext object, Event.getservletcontext ().setAttribute(constans.application_list_id, new LinkedList<>()); }}Copy the code

Database connection pool class

package com.yueqian.store.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;

public class DBUtils {
	private static final String URL = "JDBC: mysql: / / 127.0.0.1:3306 / store? useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false";
	private static final String USERNAME = "root";
	private static final String PASSWORD = "root";
	private static BasicDataSource ds = null;
	public static void init() {/ / the load Driver try {/ / a DriverManager. RegisterDriver (. New com. Mysql. Cj. JDBC Driver ()); // Class.forname ()"com.mysql.cj.jdbc.Driver()"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // create a database connection pool ds = new BasicDataSource(); // Set connection information ds.setDriverclassName ("com.mysql.cj.jdbc.Driver"); ds.setUrl(URL); ds.setUsername(USERNAME); ds.setPassword(PASSWORD); Ds.setmaxidle (30); // Set the connection pool information. // Minimum number of free connections ds.setminIdle(2); // Set the initial connection number ds.setInitialSize(2); Ds.setmaxwaitmillis (4000); Ds.setdefaultautocommit (ds.setDefaultautoCommit)false); } // add a thread object to the ThreadLocal class, and use the current thread object as the key to store the conn object. Private static ThreadLocal<Connection> ThreadLocal = new ThreadLocal<Connection>(); /** * connect to database ** @return
	 */
	public static Connection getConnection() {// Get the connection from a threadLocal, which is similar to a map, with the key as the current thread object and the value as conn connection. Connection conn = threadLocal.get(); // If the connection is null, get the connection from the connection poolif(conn == null) { try { conn = ds.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Set the resulting connection to threadLocal threadlocal.set (conn); }returnconn; } public static void close(ResultSet rs, Statement STMT) {} public static void close(ResultSet rs, Statement STMT) {if(rs ! = null) { try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally {if(stmt ! = null) { try { stmt.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }}}}} // Commit transaction public static voidcommit() {
		Connection conn = threadLocal.get();
		if(conn ! = null){ try { conn.commit(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally {// Close the connection try {conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Clean up threadlocal.remove (); }}} // Rollback transaction public static voidrollback() {
		Connection conn = threadLocal.get();
		if(conn ! = null){ try { conn.rollback(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally {// Close the connection try {conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Clean up threadlocal.remove (); }} /** * Close the database connection pool */ public static voidcloseDataSourse() {
		if(ds ! = null) { try { ds.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }}}}Copy the code
  • 2, HttpSessionListener interface: realize the creation and destruction of the session object to monitor the number of people accessing the website through the creation of the session object

Achieve the number of visitors to the site

package com.yueqian.store.listener; import javax.servlet.ServletContext; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import com.yueqian.store.common.Constans; ** @author L ** @author L ** @author L **inChi * */ //@WebListener public class OnLineListener implements HttpSessionListener { public void SessionCreated (HttpSessionEvent Event) {// Get the context object ServletContext Context = event.getSession().getServletContext(); // Get the number of sessions in the context object Integer count = (Integer) context.getAttribute(constans.application_session_id);if (count == null) {
			count = 1;
		} else {
			count++;
		}
		context.setAttribute(Constans.APPLICATION_SESSION_ID, count);
	}

	/**
	 * @see HttpSessionListener#sessionDestroyed(HttpSessionEvent)Public void sessionDestroyed(HttpSessionEvent Event) {// Get the context object ServletContext context = event.getSession().getServletContext(); // Get the number of sessions in the context object Integer count = (Integer) context.getAttribute(constans.application_session_id);if(count ! = null) { count--; context.setAttribute(Constans.APPLICATION_SESSION_ID, count); }}}Copy the code

The number of visitors monitored by the front-end page :(count the number of visitors to the system according to the number of sessions created (different browsers, the same user login is also two online, create two sessions, so it is not accurate, tourists)

Number of users currently accessing the system :<% Integer count = (Integer)application.getAttribute(constans.application_session_id);if(count ! = null){ out.print(count); } % >.Copy the code
  • 3, HttpSessionBindingListener interface: are stored in the session instance objects implementing this interface

Realize the access of different online login number of users

Implementation principle:

1. We implement this interface with the object instance to be stored in session.

2, the number of online users in the collection list (the collection list has been created in the context listener when the program starts)

3. Check whether the user is the same user, otherwise add, when the class object is destroyed in the session, remove the user from the list

package com.yueqian.store.domain; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import com.yueqian.store.common.Constans; /** * implement accurate implementation of online statistics ** @author LinChi
 *
 */
public class UserInfo implements HttpSessionBindingListener {
	private Integer userId;
	private String account;
	private String username;
	private String password;

	public UserInfo() {
		super();
		// TODO Auto-generated constructor stub
	}

	public UserInfo(Integer userId, String account, String username, String password) {
		super();
		this.userId = userId;
		this.account = account;
		this.username = username;
		this.password = password;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "UserInfo [userId=" + userId + ", account=" + account + ", username=" + username + ", password="
				+ password + "]"; } // When the UserInfo object is set to session, @override public void valueBound(HttpSessionBindingEvent event) {// Saves the account of the current UserInfo object to the list, ServletContext Context = Event.getSession ().getServletContext(); // Get the List of access users from the application listener List<String> List = (List<String>) context.getAttribute(constans.application_list_id); // If the list does not contain the user, add (to prevent adding the same user at the same time)if(! list.contains(this.account)) { list.add(this.account); }} // When the UserInfo object is removed from the session object, @Override public void valueUnbound(HttpSessionBindingEvent event) {// Saves the account of the current UserInfo object to the list, ServletContext Context = Event.getSession ().getServletContext(); // Get the List of access users from the application listener List<String> List = (List<String>) context.getAttribute(constans.application_list_id); List.remove (this.account); }}Copy the code

Front-end page receiving statistics on the number of online users :(one user logs in online from different browsers to truly monitor the number of online users.)

<% List<String> List = (List<String>)application.getAttribute(constans.application_list_id);if(list ! = null){ out.print(list.size()); }else{
				out.print("0"); } %> people <br/> <%for(String account:list){ %>
		<%out.print(account+""); } % >Copy the code

Ok, that’s all for today’s content, with today’s sorting, we will use filters and listeners in the project in the future, then we can CV operation, looking forward to the wonderful display in the next period!