New features for Servlet 3.0 Overview
Servlet 3.0 is a member of the Java EE 6 specification system, which is published along with the Java EE 6 specification. This release, based on the previous version (Servlet 2.5), provides several new features to simplify the development and deployment of WEB applications. The introduction of several of these features is very exciting for developers, as well as a piece of praise from the Java community:
- Asynchronous processing support: With this feature, the servlet thread no longer needs to block until the business has finished processing before it can output a response, and finally ends the servlet thread. After a request is received, the Servlet thread can delegate the time-consuming operation to another thread to complete itself and return to the container without generating a response. This will significantly reduce server resource usage and increase concurrent processing speed for more time-consuming business processes.
- New annotation Support: This version adds several annotations to simplify the declaration of the Servlet, filter, and Listener (Listener), which makes the Web. XML deployment profile no longer required from that version.
- Pluggable support: Developers who are familiar with STRUTS2 will be sure to remember their integration with the various common frameworks, including Spring, through plug-ins. The plug-in is encapsulated into a JAR package and placed under the classpath, which can be loaded automatically by the STRUTS2 runtime. Now Servlet 3.0 provides a similar feature that allows developers to easily extend the functionality of existing WEB applications in a plug-in way without having to modify their existing applications.
Below we will explain the new features, and through the following learning, readers will be able to clearly understand the changes in Servlet 3.0, and the smooth use of it for daily development work.
Asynchronous processing support
Before Servlet 3.0, the main workflow for a common servlet was as follows: first, after the servlet receives the request, it may need to preprocess the data that the request carries, and then invoke some methods of the business interface to complete the business process; The Servlet thread ends by submitting a response based on the result of the processing. The second step of the business process is usually the most time-consuming, mainly in the database operations, as well as other cross-network calls, and so on, in this process, the Servlet thread has been in a blocking state until the business method execution is complete. In the process of dealing with the business, the Servlet resources are always occupied and not released, which can cause performance bottlenecks for large, concurrent applications. In this respect, a private solution was used previously to end the Servlet thread prematurely and release resources in a timely manner.
Servlet 3.0 has done pioneering work on this issue, and now by using the asynchronous processing support of Servlet 3.0, the previous servlet processing process can be tuned to the following procedure: First, after the servlet receives the request, It is possible to pre-preprocess the requested data first, and then the servlet thread forwards the request to an asynchronous thread to perform the business processing, and the thread itself returns to the container, where the servlet has not generated the response data, and after the asynchronous thread has finished processing the business, The response data can be generated directly (the asynchronous thread has a reference to the ServletRequest and Servletresponse objects), or the request continues to be forwarded to the other Servlet. As a result, the Servlet thread is no longer stuck in a blocking state waiting for the processing of the business logic, but instead starts the asynchronous thread and can return immediately.
Asynchronous processing attributes can be applied to both servlet and filter components, because the asynchronous processing of the working mode and the normal mode of operation are fundamentally different, so by default, servlets and filters do not turn on the asynchronous processing feature, if you want to use the attribute, You must enable it in the following way:
- For scenarios where servlets and filters are configured using traditional deployment profiles (Web. xml), servlet 3.0 adds <async-supported> sub-labels for <servlet> and <filter> tags The default value of this label is false, to enable asynchronous processing support, set it to true. In the case of a Servlet, the configuration is as follows:
<servlet> <servlet-name>DemoServlet</servlet-name> <servlet-class> Footmark.servlet.Demo servlet</servlet-class> <async-supported>true</async-supported> < /servlet>
- For a servlet or filter configuration using the @WebServlet and @WebFilter provided by Servlet 3.0, both annotations provide the Asyncsupported property, which evaluates to False by default, to enable asynchronous processing support, only You need to set this property to True. Take @WebFilter as an example, configured as follows:
@WebFilter (urlpatterns = "/demo",asyncsupported = True) public class Demofilter implements filter{...}
A simple example of a Servlet that simulates asynchronous processing is as follows:
@WebServlet (urlpatterns = "/demo", asyncsupported = true) public class Asyncdemoservlet extends HttpServlet {@Override public void Doget (HttpServletRequest req, HttpServletResponse resp) throws IOException, Servletexception {RE Sp.setcontenttype ("Text/html;charset=utf-8"); PrintWriter out = Resp.getwriter (); Out.println ("Time to enter servlet:" + new Date () + "."); Out.flush (); Executes a business call in a child thread, and is responsible for outputting the response, the main thread exits Asynccontext CTX = Req.startasync (); New Thread (New Executor (CTX)). Start (); Out.println ("Time to end servlet:" + new Date () + "."); Out.flush (); }}public class Executor implements Runnable {private Asynccontext CTX = null; Public Executor (Asynccontext ctx) {this.ctx = CTX; public void Run () {try {//wait 10 seconds to simulate the execution of the business method Thread.Sleep (10000); PrintWriter out = Ctx.getresponse (). Getwriter (); OUT.PRINTLN ("Business process completed:" + new Date () + "."); Out.flush (); Ctx.complete (); } catch (Exception e) {e.printstacktrace (); } }}
In addition, Servlet 3.0 provides a listener for asynchronous processing, expressed using the Asynclistener interface. It can monitor the following four types of events:
- When the asynchronous thread starts, call the Asynclistener Onstartasync (AsyncEvent event) method;
- When an asynchronous thread is faulted, call the Asynclistener OnError (AsyncEvent event) method;
- Asynchronous thread execution timed out, call Asynclistener's OnTimeOut (AsyncEvent event) method;
- When the asynchronous execution is complete, call the Asynclistener OnComplete (AsyncEvent event) method;
To register a asynclistener, simply pass the prepared Asynclistener object to the AddListener () method of the Asynccontext object, as follows:
Asynccontext CTX = Req.startasync (); Ctx.addlistener (New Asynclistener () {public void OnComplete (AsyncEvent asyncevent) throws IOException { // Do some cleanup work or other } ...});
New annotation Support
Deployment profile for Servlet 3.0 The top-level label for Web. XML <web-app> has a Metadata-complete property that specifies whether the current deployment profile is complete. If set to true, the container will only rely on the deployment profile at deployment time, ignoring all annotations (also skipping web-fragment.xml scans, i.e. disabling pluggable support, see the following for pluggable support); If you do not configure this property, or set it to False, annotation support (and pluggable support) is enabled.
@WebServlet
@WebServlet is used to declare a class as a servlet, which will be handled by the container at deployment time, and the container will deploy the appropriate class as a servlet based on the specific property configuration. The note has some of the common properties given in the following table (all of which are optional), but Vlaue or urlpatterns are usually required and cannot coexist, and if specified at the same time, the value of value is usually ignored:
Table 1. @WebServlet List of main attributes
Property name |
type |
Description |
Name |
String |
Specifies the Name property of the Servlet, equivalent to <servlet-name>. If not explicitly specified, the value of the Servlet is the fully qualified name of the class. |
Value |
String[] |
This property is equivalent to the Urlpatterns property. Two attributes cannot be used at the same time. |
Urlpatterns |
String[] |
Specifies the URL-matching pattern for a set of Servlets. Equivalent to <url-pattern> tag. |
Loadonstartup |
Int |
Specifies the order in which the Servlet is loaded, equivalent to the <load-on-startup> tag. |
InitParams |
Webinitparam[] |
Specifies a set of Servlet initialization parameters, equivalent to the <init-param> tag. |
asyncsupported |
Boolean |
Declares whether the Servlet supports asynchronous operation patterns, equivalent to <async-supported> tags. |
Description |
String |
The Servlet's descriptive information is equivalent to the <description> tag. |
DisplayName |
String |
The display name of the Servlet, usually used in conjunction with the tool, is equivalent to the <display-name> tag. |
The following is a simple example:
@WebServlet (Urlpatterns = {"/simple"}, asyncsupported = True, Loadonstartup =-1, name = "Simpleservlet", DisplayName = "s S ", InitParams = {@WebInitParam (name =" Username ", value =" Tom ")}) public class Simpleservlet extends httpservlet{...}
With this configuration, you do not have to configure the appropriate <servlet> and <servlet-mapping> elements in Web. XML, and the container publishes the class as a servlet at deployment time, based on the specified properties. Its equivalent web. XML configuration form is as follows:
<servlet> <display-name>ss</display-name> <servlet-name>simpleservlet</ servlet-name> <servlet-class>footmark.servlet.SimpleServlet</servlet-class> < load-on-startup>-1</load-on-startup> <async-supported>true</async-supported> < init-param> <param-name>username</param-name> <param-value>tom</param-value > </init-param></servlet><servlet-mapping> <servlet-name>simpleservlet</ Servlet-name> <url-pattern>/simple</url-pattern></servlet-mapping>
@WebInitParam
This annotation is usually not used alone, but is used in conjunction with @WebServlet or @WebFilter. Its purpose is to specify initialization parameters for the Servlet or filter, which is equivalent to the <init-param> sub-tags of <servlet> and <filter> in Web. Xml. @WebInitParam have some common properties that are given in the following table:
Table 2. Common Properties for @WebInitParam
Property name |
type |
is optional |
Description |
Name |
String |
Whether |
Specifies the name of the parameter, equivalent to <param-name>. |
Value |
String |
Whether |
Specifies the value of the parameter, equivalent to <param-value>. |
Description |
String |
Is |
A description of the parameter is equivalent to <description>. |
@WebFilter
@WebFilter is used to declare a class as a filter that will be handled by the container at deployment time, and the container will deploy the appropriate class as a filter based on the specific property configuration. The note has some of the common properties given in the following table (all the properties below are optional, but value, Urlpatterns, Servletnames must contain at least one, and value and urlpatterns cannot coexist, and if specified at the same time, it is generally ignored Value):
Table 3. Common Properties for @WebFilter
Property name |
type |
Description |
FilterName |
String |
Specify the Name property of the filter, equivalent to <filter-name> |
Value |
String[] |
This property is equivalent to the Urlpatterns property. But both should not be used at the same time. |
Urlpatterns |
String[] |
Specifies the URL-matching pattern for a set of filters. Equivalent to <url-pattern> tag. |
Servletnames |
String[] |
Specifies which servlets the filter will be applied to. The value is the value of the name attribute in the @WebServlet, or the value of <servlet-name> in Web. Xml. |
Dispatchertypes |
Dispatchertype |
Specifies the forwarding mode of the filter. Specific values include: ASYNC, ERROR, FORWARD, INCLUDE, REQUEST. |
InitParams |
Webinitparam[] |
Specifies a set of filter initialization parameters, equivalent to the <init-param> tag. |
asyncsupported |
Boolean |
Declares whether the filter supports asynchronous operation mode, equivalent to the <async-supported> tag. |
Description |
String |
The description information of the filter is equivalent to the <description> tag. |
DisplayName |
String |
The filter's display name, usually used with the tool, is equivalent to the <display-name> tag. |
The following is a simple example:
@WebFilter (Servletnames = {"Simpleservlet"},filtername= "Simplefilter") public class Lessthansixfilter implements Filter{...}
With this configuration, you do not have to configure the appropriate <filter> and <filter-mapping> elements in Web. XML, and the container publishes the class as a filter at deployment time, based on the specified properties. Its equivalent in Web. XML is configured in the following form:
<filter> <filter-name>SimpleFilter</filter-name> <filter-class>xxx</ filter-class> </filter> <filter-mapping> <filter-name>SimpleFilter</filter-name> <servlet-name>SimpleServlet</servlet-name> </filter-mapping>
@WebListener
This annotation is used to declare a class as a listener, and the class that is @WebListener labeled must implement at least one of the following interfaces:
- Servletcontextlistener
- Servletcontextattributelistener
- Servletrequestlistener
- Servletrequestattributelistener
- Httpsessionlistener
- Httpsessionattributelistener
This annotation is very simple to use and its properties are as follows:
Table 4. Common Properties for @WebListener
Property name |
type |
is optional |
Description |
Value |
String |
Is |
The description information for the listener. |
A simple example is as follows:
@WebListener ("This was only a demo listener") public class SimpleListener implements servletcontextlistener{...}
In this case, you do not need to configure the <listener> tag in Web. Xml. It is equivalent to the configuration form in Web. Xml as follows:
<listener> <listener-class>footmark.servlet.SimpleListener</listener-class> </ Listener>
@MultipartConfig
This note is primarily intended to assist in the support provided by HttpServletRequest in Servlet 3.0 for uploading files. The note is labeled above the servlet to indicate that the MIME type of the request that the servlet wishes to process is multipart/form-data. In addition, it provides several properties for simplifying the processing of uploaded files. Specific as follows:
Table 5. Common Properties for @MultipartConfig
Property name |
type |
is optional |
Description |
Filesizethreshold |
Int |
Is |
When the amount of data is greater than this value, the content is written to the file. |
Location |
String |
Is |
Store the generated file address. |
MaxFileSize |
Long |
Is |
Maximum number of files allowed to upload. The default value is-1, which means there is no limit. |
Maxrequestsize |
Long |
Is |
The maximum number of requests for the Multipart/form-data, the default value is-1, which means there is no limit. |
Pluggable support
If the new annotation support for version 3.0 is to simplify the declaration of the servlet/filter/listener, so that web. xml becomes optional, the new pluggable (pluggability) support increases the flexibility of the Servlet configuration to the next level. Developers familiar with Struts2 know that STRUTS2 provides support for various development frameworks, including Spring, in the form of plug-ins, and developers can even develop plug-ins for Struts2 themselves, and the Servlet's pluggable support is based on this idea. With this feature, we can now extend the new functionality without modifying the existing WEB application, simply by placing the JAR package in a certain format into the Web-inf/lib directory, with no additional configuration required.
Servlet 3.0 introduces a Web-fragment.xml deployment profile called a "Web module deployment Descriptor Fragment" that must be stored in the Meta-inf directory of the JAR file, which can contain everything that can be defined in XML. The JAR package is usually placed in the Web-inf/lib directory, except that all the resources used by the module, including class files, configuration files, etc., only need to be able to be loaded by the container ClassLoader chain, such as the classes directory.
Now, there are three ways to add a servlet configuration to a Web application (filters, listeners, and servlets are all equivalent, so here's a servlet configuration example that filters and listeners have a very similar feature):
- Write a class that inherits from HttpServlet, places the class in the corresponding package structure under the classes directory, modifies Web. XML, and adds a Servlet declaration to it. This is the most primitive way;
- writes a class that inherits from HttpServlet, and uses @WebServlet annotations on that class to declare the class as a Servlet, placing the class in the corresponding package structure in the classes directory without modifying the Web. xml file.
- writes a class that inherits from HttpServlet, hits the class into a jar package, and places a Web-fragment.xml file under the Meta-inf directory of the jar package that declares the corresponding Servlet configuration. An example of the Web-fragment.xml file is as follows:
<?xml version= "1.0" encoding= "UTF-8"? ><web-fragment Xmlns=http://java.sun.com/xml/ns/javaee Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" version= "3.0" xsi:schemalocation= "http://java.sun.com /xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd " metadata-complete=" true "> <servlet> <servlet-name>fragment</servlet-name> <servlet-class> footmark.servlet.fragmentservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>fragment</servlet-name> <url-pattern>/fragment</url-pattern> </servlet-mapping></web-fragment>
As can be seen from the above example, the principal configuration of Web-fragment.xml and Web. XML is exactly the same as the Web. XML except that the XSD reference to the header declaration is different.
Because multiple Web-fragment.xml declaration files can appear in a WEB application, plus an XML file, the load order issue becomes a problem that has to be faced. The Servlet specification's expert group has taken this into account at design time and defined the rules for loading order.
The web-fragment.xml contains two optional top-level labels,<name> and <ordering>, and if you want to specify an explicit load order for the current file, you typically need to use both tags,<name> Primarily used to identify the current file, <ordering> is used to specify the order of precedence. A simple example is as follows:
<web-fragment...> <name>FragmentA</name> <ordering> <after> < name>fragmentb</name> <name>FragmentC</name> </after> <before> <others/> </before> </ordering> ...</web-fragment>
As shown above, the value of the <name> tag is usually referenced by other web-fragment.xml files in the defined order, which is not normally used in the current file, and it plays a role in identifying the current file.
Within the <ordering> tag, we can define the relative position of the current Web-fragment.xml file with other files, mainly through <ordering> <after> and <before > sub-tags to achieve. Within these two sub-labels you can specify the corresponding file by <name> tag. Like what:
<after> <name>FragmentB</name> <name>FragmentC</name> </after>
The above fragment indicates that the current file must be parsed after FRAGMENTB and FRAGMENTC. <before> is used in this same way, which means that the current file must be earlier than the Web-fragment.xml file listed in the <before> tab.
In addition to listing the files compared through <name> in <after> and <begin>, the Servlet provides a simplified label <others/>. It represents all other web-fragment.xml files except the current file. The label's priority is lower than the relative position relationship that is explicitly specified with <name>.
Performance enhancements for ServletContext
In addition to the new features above, the functionality of the ServletContext object has been enhanced in the new version. The object now supports dynamically deploying Servlets, filters, listeners at run time, as well as adding URL mappings for servlets and filters. In the case of Servlets, the filter is similar to the listener. ServletContext adds the following methods for dynamically configuring Servlets:
ServletRegistration.Dynamic addServlet(String servletName,Class<? extends Servlet> servletClass)
ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
ServletRegistration.Dynamic addServlet(String servletName, String className)
- <t extends servlet> T createservlet (class<t> clazz)
- Servletregistration getservletregistration (String servletname)
- Map<string, huh? Extends Servletregistration> getservletregistrations ()
The first three methods are the same, only the parameter types are different; Servlets created with the Createservlet () method typically require some custom configuration and then use the Addservlet () method to dynamically register it as a service-ready Servlet. The two getservletregistration () methods are primarily used to dynamically add mapping information to Servlets, which is equivalent to using <servlet-mapping> in Web. XML (or Web-fragment.xml) Tag adds mapping information to the existing Servlet.
The above ServletContext new method is either called in the Servletcontextlistener contexinitialized method, or in the Servletcontainerinitializer Called in the Onstartup () method.
Servletcontainerinitializer is also a new interface for Servlet 3.0, which uses the Jar service API (Jar Services API) at startup to discover Servletcontainerinitializer's real Now class, and the container web-inf/lib the classes in the JAR package to the Onstartup () method of the class, we usually need to use @HandlesTypes annotations on the implementation class to specify the class that you want to process, filtering out the unwanted onstartup () The class to process.
HttpServletRequest Support for file uploads
Previously, the process of uploading files was always a headache for developers, because the Servlet itself did not provide direct support, needed to be implemented using a third-party framework, and was not easy to use. Now that's history, Servlet 3.0 has provided this functionality, and it's very simple to use. To do this, HttpServletRequest provides two methods to parse the uploaded file from the request:
- Part GetPart (String name)
- Collection<part> GetParts ()
The former is used to get the file given name in the request, which is used to get all the files. Each file is represented by a Javax.servlet.http.Part object. This interface provides an easy way to process files, such as write (), delete (), and so on. At this point, combining httpservletrequest and part to save the uploaded file becomes very simple, as follows:
Part photo = Request.getpart ("photo"); Photo.write ("/tmp/photo.jpg"); You can simplify two lines of code to Request.getpart ("Photo"). Write ("/tmp/photo.jpg") line.
In addition, developers can work with the aforementioned @MultipartConfig annotations to make some customizations to the upload operation, such as restricting the size of the uploaded file, and saving the path of the file. The usage is very simple, so we don't repeat it here.
It is important to note that if the requested MIME type is not multipart/form-data, you cannot use the two methods above, or you will throw an exception.
Summarize
The many new features of Servlet 3.0 make servlet development easier, especially with the advent of asynchronous processing features and pluggable support, which will have a profound impact on the existing MVC framework. While we don't usually write control-layer code on our own, perhaps in the next version of Struts, you can actually feel the real changes that these new features bring.
Servlet3.0 Annotated New Notes (reproduced by IBM)