Servlet & JSP (V)

Source: Internet
Author: User

We have discussed the init () method in servlet & JSP (2), and mentioned that the init () method contains a parameter of the type servletconfig, the servlet container uses this parameter to pass configuration information to the servlet. Servlet uses the servletconfig object to obtain the initialization parameters provided in name-value pairs from the Web application configuration information. In addition, you can use the servletconfig object to obtain the servletcontext object describing the servlet runtime environment. With this object, the servlet can communicate with its servlet container. Now let's take a closer look at why the servletconfig parameter is used and how to use it.

For example, I want my email address to be displayed on a web page generated by Servlet, but my email may be changed, but I don't want to recompile my servlet code because of this, how can I change it? I want to configure my email address in the deployment description file (dd) instead of hardcoding it into the servlet class. That is, I do not want to do this:

PrintWriter out = response.getWriter();out.println("shan@email.com");

Hard-coded email addresses are not good, because if I want to change the email address, I need to re-compile the servlet class. This is very troublesome, so we can. XML) to make the following deployment:

<servlet><servlet-name>TestServlet</servlet-name><servlet-value>com.shan.web.TestServlet</servlet-value><init-param><param-name>email</param-name><param-value>shan@email.com</param-value></init-param></servlet>

Add the following statement to the servlet code:

out.println(getServletConfig().getInitParameter("email"));

The getservletconfig () method returns a servletconfig. The getinitparameter ("email") method returns the parameter value "email. When the container is initially a servlet, a unique servletconfig will be created for the servlet. The container reads servlet initialization parameters from DD, passes these parameters to servletconfig, and then passes servletconfig to the Init () method of servlet. Note: The getservletconfig () method cannot be called from the servlet constructor, because it is not a complete servlet until the container calls the init () method.

So what happens when the container initializes servlet parameters?

1) when the container creates a servlet, it reads the DD, including the servlet initialization parameter <init-param>.
2) The container creates a new servletconfig for this servlet.
3) create a string name/value pair for each servlet initialization parameter.
4) The container provides servletconfig with reference to the initialization parameters of name/value pairs.
5) The container creates a new instance of the servlet class.
6) The container calls the servlet Init () method and passes in the reference of servletconfig.

From this process, we can see that when the container creates a servlet, it reads DD and creates a name/value pair for servletconfig. Then, the container will no longer read the initialization parameters. Therefore, it is too clumsy to change the email address in the servlet lifecycle. But it is better than hard encoding. To change the email address, redeploy the application.

Can JSP get servlet initialization parameters?

Servletconfig is used for servlet configuration instead of jspconfig. Therefore, if you want other parts of the application to use the servlet initialization parameter information you configured in the DD, you need to use the servlet & JSP tasks (4) the request forwarding mechanism is described in. You only need to set an attribute in the request to receive the message from the JSP that forwarded the request.

String email = getServletConfig().getInitParameter("email");request.setAttribute("email",email);RequestDispatcher rd=request.getRequestDispatcher("/test.jsp");rd.fordward(request,response);

However, we may need to use this address throughout the application. One way is to let the servlet read the initialization parameters and save them so that other parts of the application can be used. However, in this way, we must know which servlet to run during application deployment, and if you change the application, everything will be screwed up. Therefore, this is not acceptable.

In view of this, we use context initialization parameters. It is similar to the servlet initialization parameter, except that the context initialization parameter is available for the entire web application rather than a servlet. Therefore, both Servlet and JSP can access context initialization parameters. We need to make the following changes in Web. xml:

<servlet><servlet-name>TestServlet</servlet-name><servlet-value>com.shan.web.TestServlet</servlet-value></servlet><context-param><param-name>email</param-name><param-value>shan@email.com</param-value></context-param>

Note: <context-param> is applicable to the entire web application, so it is not nested in <servlet>.

Add the following statement to the servlet code:

out.println(getServletContext().getInitParameter("email"));

Or

ServletContext context = getServletContext();out.println(context.getInitParameter("email"));

Note the differences between servlet initialization parameters and context initialization parameters. The entire web application has only one servletcontext, and all parts of the web application can access it. However, each servlet in the application has its own servletconfig. When deploying a web application, the container will create a servletcontext (Note: If your application is distributed across multiple servers, the Web application can actually have multiple servletcontext, A servletcontext does correspond to only one application, provided that the application is in one JVM .), This context is available for each Servlet and JSP in the Web application.

Speaking of this, what if we want the app initialization parameter to be a database datasource?

The context initialization parameter can only be string. After all, we cannot insert an object into the XML deployment description file. If the entire web application has a main method, you can add some code that runs before servlet or JSP. Although the servlet does not have the main method, there is a listener (listener ). What we want is to listen to an initialization event, so that we can get the context initialization parameters and run some code before the application serves the customer. However, which part of the application can be used as the listener? We don't want a servlet to do this kind of work. After all, its task is not this.

What we need is actually a servletcontextlistener. It can listen to two key events in the life of servletcontext: initialization (creation) and revocation. It can:

You are notified when the context is initialized (when the application is deployed.

  • Obtain the context initialization parameters from servletcontext.
  • Create a database connection using the initialization parameter lookup name
  • The database connection is used as a property so that all parts of the web application can be accessed.

You will be notified when the context is revoked (the application is deploy or terminated.

  • Close the database connection.

Instance, a simple servletcontextlistener

Because we do not want to create a database, we do not use the database connection example. Our instance will convert the string initialization parameter to an object-dog. The listener's task is to obtain the context initialization parameters (Tibetan mastiff, matsushi, Samo, Chinese Rural dog, etc.) for the dog breed, and then use this string to construct a dog object, the listener then saves the dog object to a servletcontex attribute for the servlet to get it. The key to the problem is that servlet can access a shared application object (DOG) without reading context parameters. Therefore, it does not matter whether the shared application object is a database link.

Create a listener class:

package com.shan.listen;import com.shan.model.Dog;import javax.servlet.*;public class MyServletContextListener implements ServletContextListener {public void contextInitialized(ServletContextEvent event) {ServletContext context = event.getServletContext();String dogBreed = context.getInitParameter("breed");Dog dog = new Dog(dogBreed);context.setAttribute("dog",dog);}public void contextDestroyed(ServletContextEvent event) {}}

Among them, the dog class code is as follows:

package com.shan.model;public class Dog {private String breed = null;public Dog(String breed) {this.breed = breed;}public String getBreed(){return breed;}}

Compile the servlet class with the following code:

Package COM. shan. web; import COM. shan. model. dog; import Java. io. *; import javax. servlet. *; import javax. servlet. HTTP. *; public class testlistenerservlet extends httpservlet {public void doget (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {response. setcontenttype ("text/html; charset = gb2312"); printwriter out = response. getwriter (); out. println ("A listener sets the context attribute test:"); out. println ("<br/>"); dog = (DOG) getservletcontext (). getattribute ("dog"); out. println ("dog breed:" + dog. getbreed (); out. close ();} public void dopost (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {doget (request, response );}}

Note: The forced conversion type (DOG) cannot be forgotten ).

Finally, write the deployment description file web. xml.

<? XML version = '1. 0' encoding = 'utf-8'?> <Web-app xmlns = "http://java.sun.com/xml/ns/javaee" xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: schemalocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version = "3.0" metadata-complete = "true"> <servlet-Name> testlistenerservlet </servlet-Name> <servlet-class> com. shan. web. testlistenerservlet </servlet-class> </servlet> <servlet-mapping> <servlet-Name> testlistenerservlet </servlet-Name> <URL-pattern>/listentest. DO </url-pattern> </servlet-mapping> <context-param> <param-Name> breed </param-Name> <param-value> Tibetan mastiff </param- value> </context-param> <listener-class> COM. shan. listen. myservletcontextlistener </listener-class> </listener> </Web-app>

Does the XML Element seem to indicate the type of the event to be listened? In fact, the container will check the class and pay attention to the listener interface (or multiple interfaces, One listener can implement multiple listener interfaces) to identify the types of events to listen.

The process for establishing a web application is the same as described earlier. The only change is that a new Java package COM. shan. listen is used to store the listener class. The last deployment is the same as the previous one.

However, we also need to execute the following statement to compile the above class (first switch to the project directory ):

javac -d classes src\com\shan\model\Dog.java
javac -classpath D:\apache-tomcat-7.0.33\lib\servlet-api.jar;classes -d classes src\com\shan\listen\MyServletContextListener.java
javac -classpath D:\apache-tomcat-7.0.33\lib\servlet-api.jar;classes -d .\classes src\com\shan\web\TestListenerServlet.java

Start tomcat to deploy the application. The test results are as follows:

Figure 1 instance running result

Let's discuss the entire scenario. It can be divided into the following steps:

1) The container reads the deployment description file of the application, including the <listen> and <context-param> elements.
2) The container creates a new servletcontext for the application, and all parts of the application share the context.
3) The container creates a string name/value pair for each context initialization parameter. It is assumed that there is only one parameter.
4) The container submits the reference of the name/value parameter to servletcontext.
5) The container creates a new instance of the myservletcontextlistener class.
6) The container calls the contextinitialized () method of the listener and passes in a new servletcontextevent. This event object has a servletcontext reference, so the event processing code can get context initialization parameters from the event context.
7) the listener sends a reference to the servletcontextevent to the servletcontext.
8) the listener sends the context initialization parameter "breed" to servletcontext ".
9) the listener uses initialization parameters to construct a new dog object.
10) the listener sets dog as an attribute in servletcontext.
11) create a new servlet for the container (that is, use the initialization parameter to create a new servletconfig, provide a reference to the servletconfig, and then call the servlet Init () method ).
12) the servlet gets a request and requests the attribute "dog" from the servletcontext ".
13) the servlet calls getbreed () on the dog and outputs the result to httpresponse.

In addition to the context listener interface, there are other listener interfaces.

Scenario Listener Interface Event Type
You want to know whether an attribute is added, deleted, or replaced in the context of a Web application. Javax. servlet. servletcontextattributelistener
Attributeadded
Attributeremoved
Attributereplaced
Servletcontextattributeevent
You want to know the number of concurrent users. That is to say, you want to track the active sessions Javax. servlet. http. httpsessionlistener
Sessioncreated
Sessiondestroyed
Httpsessionevent
Every time a request arrives, you want to know to create a log. Javax. servlet. servletrequestlistener
Requestinitialized
Requestdestroyed
Servletrequestevent
When do you want to add, delete, or replace a request attribute? Javax. servlet. servletrequestattributelistener
Attributeadded
Attributeremoved
Attributereplaced
Servletrequestattributeevent
You have an attribute class (the objects indicated by this class will be placed in an attribute), and you want this type of object to be bound to a session or be notified when the session is deleted. Javax. servlet. http. httpsessionbindinglistener
Valuebound
Valueunbound
Httpsessionbindingevent
When do you want to add, delete, or replace a session attribute? Javax. servlet. http. httpsessionattributelistener
Attributeadded
Attributeremoved
Attributereplaced
Httpsessionbindingevent (Note: The names here are inconsistent !)
You want to know whether a context is created or revoked Javax. servlet. servletcontextlistener
Contextinitialized
Contextdestroyed
Servletcontextevent
You have an attribute class and want to be notified when the session bound to this class object is migrated to another JVM. Javax. servlet. http. httpsessionactivationlistener
Sessiondidactivate
Sessionwillpassivate
Httpsessionevent (Note: The names here are inconsistent !)

Reprinted please indicate the source: http://blog.csdn.net/iAm333

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.