Listener
introduce
- The listener comes from the servlet specification
- The listener is dedicated to monitoring [changes in domain object lifecycle] and [changes in domain object shared data]
- The implementation class of listener interface must be implemented by the developer
As mentioned above, listeners are used to monitor changes in the life cycle of domain objects and changes in data sharing among domain objects. So what is a domain object?
Domain object
Definition
Within a certain range, objects that share data can be provided between servlet s.
classification
- ServletContext application: Acting on objects globally, during tomcat runs, it can provide shared data for all servlet s in the current project
- HTTPSession session: Session scoped object that provides shared data for the servlet participating in the session during a session
- HttpServletRequest request: Request scope object that provides shared data for all servlet s participating in this request during a request processing process, such as request forwarding
Monitor implementation steps
- Choose an appropriate listener interface to implement it according to the listener object.
- Listening Processing Method in Rewriting Listener Interface
- Register listeners in web.xml, through tomcat
Small case (monitoring the lifecycle of ServletContext)
Write a class to implement the ServletContextListener interface, that is, to monitor changes in the ServletContext lifecycle. Here's how to rewrite the initialization and destruction methods
@javax.servlet.annotation.WebListener() public class OneListener implements ServletContextListener { @Override // Called when application is initialized public void contextInitialized(ServletContextEvent servletContextEvent) { System.out.println("Global scoped objects are initialized"); } @Override // Called when application is destroyed public void contextDestroyed(ServletContextEvent servletContextEvent) { System.out.println("Global scope object destroyed"); } }
You can see a @javax.servlet.annotation.WebListener in the Listener above. (), this annotation is to declare that this class is a listener. If this annotation already exists, then you do not need to configure it in the following xml. If you do not have that annotation, you can configure it in the following way. Register listeners in web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--Listener registration, when our program starts tomcat It will help us create listener objects, which are created before the global scope is created.--> <listener> <listener-class>top.listener.OneListener</listener-class> </listener> </web-app>
Small case (listening for changes in ServletContext data)
As a case study, listening to ServletContext above is ServletContextAttributeListener If it's session-dependent, it's Session Attribute Listener.
If you look at Request, it's Request Attribute Listener.
As mentioned above, listeners are mainly used to do [changes in data shared by domain objects]. There are three main cases of data changes:
New Shared Data
application.setAttribute("key", 100);
Update shared data (update when key already exists)
application.setAttribute("key", 100);
Delete shared data
application.removeAttribute("key", 100);
Create a new class to implement the ServletContextAttributeListener interface
package top.one.listener; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; @javax.servlet.annotation.WebListener() public class TestListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("New additions to listening for shared data"); } @Override public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("Removal of listening shared data"); } @Override public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("Listen for updates to shared data"); } }
Because there is a @javax.servlet.annotation.WebListener on the above class () Annotations so you can no longer register listeners in web.xml
Write a servlet
package top.one.listener; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TestServlet extends HttpServlet { @Override public void init(ServletConfig config) throws ServletException { super.init(config); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = req.getServletContext(); servletContext.setAttribute("key", 100); servletContext.setAttribute("key", 200); servletContext.removeAttribute("key"); } }
Configuring servlet s in web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>testServletContext</servlet-name> <servlet-class>top.one.listener.TestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>testServletContext</servlet-name> <url-pattern>/first.do</url-pattern> </servlet-mapping> </web-app>
Start project access http://localhost:8080/ServletContext_war_exploded/first.do You can see the following effects:
Access address
The above access address ip: port and the first. do (which is configured in url-pattern) are all good to say. How did that ServletContext_war_exploded come from? Here is the default access path name when we deploy the project to tomcat: The prerequisite is that we have tomcat configured in the idea, and then click on the application Servers in the console.
There is a pen Icon on the left, where is the edit configuration. After clicking, the following picture appears:
Then select the project we want to deploy:
You can see that there is a path to the Application Context, where you can modify it yourself.
Application of Monitor
Steps for using jDBC (mysql version)
- Load the database driver (it seems that after 5:00 this step does not need to be written by ourselves, we have already registered in jar)
Class.forName("com.mysql.jdbc.Driver");
- Get the connection
The url here tells the jdbc program which database to connect to. The commonly used URLs of mysql and oracle are as follows:Connection conn = DriverManage.getConnection(url, username, password);
- mysql: jdbc:mysql://ip: port/database name If it's a local url, it might be jdbc: mysql://localhost:3306/database name
- oracle: jdbc:oracle:thin@ip Port: database name, if local url is jdbc:oracle:thin: @localhost 1521: Database name
- sql precompilation
Statement objects are not used here because Statement does not prevent sql injection problems.String sql = "select name, password from users where id=? "; PrepareStatement ps = conn.prepareStatement(sql);
- Execute sql statements
ps.setString(1, '1'); ps.executeQuery(); // There is no need to pass in sql
- Get results
ResultSet rs = ps.executeQuery(); while(rs.next()){ String name = rs.getString(2); // Here 2 indicates that the name field is the second column in the database. String name = rs.getString("name"); // It's also possible to get the value of the name field directly. }
- Close the connection The main ones are the closure of ResultSet, the closure of PrepareStatement and the closure of Connection.
Specific application
In the above example of jdbc connecting database, the most time-consuming operation of obtaining and closing connections is to use connection pool to solve frequent access and closing connections. That is to say, some connections are created at project startup, so that they can be obtained directly from the connection pool when they need to be used, rather than from the connection pool when they need to be used. It is much faster to create connections when you use them, but these connections always need to be created and destroyed at a certain time. It says that these connections are created when the project starts and closed when the project closes. How do you know when the project starts and closes? At this point, you need to use the ServletContextListener listener. Because the listener can monitor changes in the project life cycle, it can naturally know when the project starts and ends.