Servlet–listener, Filter, Decorator

Source: Internet
Author: User

listener-Listener
Listener provides a complete set of event classes and listener interfaces for event-driven programming in the Java Web. The Listener Listener event source is divided into servletcontext/httpsession/servletrequest three levels:

ServletContext level

HttpSession level

ServletRequest level

Registered
The listener can only be created by implementing the relevant interface, but it will only be discovered by the container if it is registered with the servlet container, in order to drive the listener to execute when an event occurs. There are two ways to register listener: Annotations and deployment descriptors.

    1. @WebListener
      In Servlet 3.0, @weblistener annotations are provided:
@WebListenerpublic class ListenerClass implements ServletContextListener {    // ...}
    1. Deployment descriptor
      <listener><listener-class>com.fq.web.listener.ListenerClass</listener-class></listener>

      Note: Because Httpsessionbindinglistener/httpsessionactivationlistener is directly bound to the JavaBean, instead of binding to a domain object such as a session, it can be registered differently.
      Example
      Loading the spring container
      Contextloaderlistener
      public class Contextloaderlistener extends Contextloader implements Servletcontextlistener {

public ContextLoaderListener(WebApplicationContext context) {        super(context);}/** * Initialize the root web application context. */@Overridepublic void contextInitialized(ServletContextEvent event) {        initWebApplicationContext(event.getServletContext());}/** * Close the root web application context. */@Overridepublic void contextDestroyed(ServletContextEvent event) {        closeWebApplicationContext(event.getServletContext());        ContextCleanupListener.cleanupAttributes(event.getServletContext());}}

Xml

<listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>

Statistics HTTP Request time consuming
Monitor ServletRequest creation/destruction events to calculate HTTP processing time-consuming

/** * @author jifang. * @since 2016/5/4 15:17. */@WebListenerpublic class PerforationStatListener implements ServletRequestListener {    private static final Logger LOGGER = Logger.getLogger("PerforationStatListener");    private static final String START = "Start";    public void requestInitialized(ServletRequestEvent sre) {        ServletRequest request = sre.getServletRequest();        request.setAttribute(START, System.nanoTime());    }    public void requestDestroyed(ServletRequestEvent sre) {        HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();        long start = (Long)request.getAttribute(START);        long ms = (System.nanoTime() - start)/1000;        String uri = request.getRequestURI();        LOGGER.info(String.format("time token to execute %s : %s ms", uri, ms));    }}

Httpsessionbindinglistener
When JavaBean implements the Httpsessionbindinglistener interface, it can perceive that this class of objects is added/removed from the session event:

Listener ""

public class Product implements Serializable, Httpsessionbindinglistener {

private int id;private String name;private String description;private double price;public Product(int id, String name, String description, double price) {    this.id = id;    this.name = name;    this.description = description;    this.price = price;}// ...public void valueBound(HttpSessionBindingEvent event) {    System.out.println("bound...");}public void valueUnbound(HttpSessionBindingEvent event) {    System.out.println("un_bound...");}

}

servlet> private static final String FLAG = "FLAG";> > @Override > protected void doget (HttpServletRequest req Uest, HttpServletResponse response) throws Servletexception, IOException {> Boolean flag = (Boolean) getservletcont Ext (). getattribute (flag);> if (flag = = NULL | |!flag) {> request.getsession (). SetAttribute ("Product", NE W Product (8, "Crystal bracelet", "Vunsun color natural Crystal bracelet female", 278.00));> Getservletcontext (). SetAttribute (FLAG, True);>} els E {> request.getsession (). RemoveAttribute ("Product");> Getservletcontext (). SetAttribute (FLAG,!flag) ;>}>}**httpsessionactivationlistener** to save memory, the servlet container can migrate or serialize session properties. Generally, when memory is low, Relatively less-accessed objects can be serialized to an alternate storage device (passivation), and the container will then deserialize the object from the persisted storage device into memory (activation) when the session needs to be reused. Httpsessionactivationlistener is used to perceive object passivation/Activation events: for passivation/Activation, the object is actually to serialize/ Deserialization is shuttling between memory and persistent storage devices. Therefore, the implementation of the Httpsessionactivationlistener interface JavaBean also requires the implementation of the serializable interface. Configure passivation time in Conf/context.xml > <Context>> <WatchedResource>web-inf/web.xml</watchedresource>> > <manager classname= " Org.apache.catalina.session.PersistentManager "maxidleswap=" 1 ">> <store classname=" Org.apache.catalina.s Ession. Filestore "directory=" Sessions "/>> </Manager>> </Context>JavaBean> public class Product Imple ments Serializable, Httpsessionactivationlistener {> > private int id;> private String name;> pri Vate String description;> private Double price;> >//...> > public void sessionwillpassivate (Httpsessionevent se) {> System.out.println ("Passivate ...");>}> > public void sessiondidactivate (httpsessionevent SE) {> System.out.println ("Activate ...");>}>} When product is added to the session for a minute without access, the object is serialized to disk and called SESSIONWILLP Assivate () method, when the object is used again, the servlet container automatically activates the session and calls the Sessiondidactivate () method. **filter-filter **filter refers to the interception request, An object that can be processed for servletrequest/servletresponse. Because it can be configured to intercept one or more resources,This can be used to deal with issues such as login/Plus (solution)/session check/Picture adaptation. There are filter/filterchain/filterconfig three interfaces commonly used in filter:! [] (http://i2.51cto.com/images/blog/201810/21/0a3a846aef609e074525eea0bbf4e57d.png?x-oss-process=image/ watermark,size_16,text_qduxq1rp5y2a5a6i,color_ffffff,t_100,g_se,x_10,y_10,shadow_90,type_zmfuz3pozw5nagvpdgk=) Filters must implement the filter interface, and when the application starts, the servlet container automatically invokes the Filters init () method, and the Destroy () method is called automatically when the service terminates. The Dofilter () method is called each time the resource associated with the filter resource is requested; Because Dofilter () can access Servletrequest/servletresponse, you can add properties to the request, or add a response header to response, or even decorate the request/response/ Replace them and change their behavior (see below). [] (http://i2.51cto.com/images/blog/201810/21/18a6b0b34055be3d6eaeadf4bccc62c9.png?x-oss-process=image/ watermark,size_16,text_qduxq1rp5y2a5a6i,color_ffffff,t_100,g_se,x_10,y_10,shadow_90,type_zmfuz3pozw5nagvpdgk=) There is only one dofilter () method in Filterchain that can throw the next filter in the call chain or the resource itself is called. If no Filterchain dofilter () method is called in the filter's Dofilter (), The processing of the program will stop here and no further requests will be processed. Example: Filter solves get/post encoding problems

/**

  • @author Jifang.
  • @since 2016/5/2 11:55.
    */
    public class Charsetencodingfilter implements Filter {

    private static final String Ignore_uri = "Ignore_uri";

    private static final String Uri_separator = ",";

    Private set<string> Ignoreuris = new hashset<string> ();

    public void init (Filterconfig config) throws servletexception {
    String Originaluris = Config.getinitparameter (Ignore_uri);
    if (Originaluris! = null) {
    string[] URIs = Originaluris.split (Uri_separator);
    for (String Uri:uris) {
    This.ignoreUris.add (URI);
    }
    }
    }

    public void Destroy () {
    }

    public void DoFilter (ServletRequest req, Servletresponse resp, Filterchain chain) throws Servletexception, IOException {
    HttpServletRequest request = (httpservletrequest) req;
    String uri = Request.getrequesturi ();
    if (!ignoreuris.contains (URI)) {
    if (Request.getmethod (). Equals ("GET")) {
    Request = new Encodingrequest (request);
    } else {
    Request.setcharacterencoding ("UTF-8");
    }
    }
    Chain.dofilter (Request, RESP);
    }

    Private static final class Encodingrequest extends Httpservletrequestwrapper {

    public EncodingRequest(HttpServletRequest request) {    super(request);}@Overridepublic String getParameter(String name) {    String value = super.getParameter(name);    if (value != null) {        try {            value = new String(value.getBytes("ISO-8859-1"), "UTF-8");        } catch (UnsupportedEncodingException e) {            throw new RuntimeException(e);        }    }    return value;}

    }
    }
    Note: httpservletrequestwrapper introduction See decorator-Decorator part.

Registration/Configuration
After you have written the filter, you need to register it and configure the filter with the following objectives:

Determine the target resource to intercept the filter;
The startup initial value passed to the Init () method;
Name the filter.
Xml

<filter>    <filter-name>CharsetEncodingFilter</filter-name>    <filter-class>com.fq.web.filter.CharsetEncodingFilter</filter-class>    <init-param>        <param-name>ignore_uri</param-name>        <param-value>/new_servlet.do,/hello_http_servlet.do</param-value>    </init-param></filter><filter-mapping>    <filter-name>CharsetEncodingFilter</filter-name>    <url-pattern>/*</url-pattern></filter-mapping>

You can also use @webfilter annotations, which are configured in a simple and similar way to the deployment descriptor, so don't repeat
.
Filterconfig
The Filter/filterchain two interfaces are described earlier, the Filterconfig interface is described below, the most common method is Getinitparameter (), get the initialization parameters of the filter, To complete the more granular filtering rules. But he also provides the following practical methods:


Interception mode
There are four ways to intercept filters: Request/forward/include/error

Request: (default) Execute direct access to target resource (address bar direct access/form submission/hyperlink/redirect, etc. as long as the target resource path is visible in the Address bar, request)
FORWARD: Forward Access Execution (FORWARD () method in RequestDispatcher)
Include: Include Access Execution (include () method in RequestDispatcher)
Error: When the target resource is configured as medium in Web. XML, and an exception occurs, the filter is executed when it is forwarded to the target resource.

<filter>    <filter-name>CharsetEncodingFilter</filter-name>    <filter-class>com.fq.web.filter.CharsetEncodingFilter</filter-class>    <init-param>        <param-name>ignore_path</param-name>        <param-value>/new_servlet.do</param-value>    </init-param></filter><filter-mapping>    <filter-name>CharsetEncodingFilter</filter-name>    <url-pattern>/*</url-pattern>    <dispatcher>REQUEST</dispatcher>    <dispatcher>INCLUDE</dispatcher></filter-mapping>

decorator-Decorator
There are 4 wrapper classes in the servlet servletrequestwrapper/servletresponsewrapper/httpservletrequestwrapper/ Httpservletresponsewrapper, which can be used to change the behavior of Servlet request/response, these wrapper classes follow the adorner pattern (Decorator).

Because they provide a default implementation for each of the request/response in the wrapped package, by inheriting them, simply overwrite the method you want to modify. No need to implement the original servletrequest/servletresponse/... Each method of an interface.

Instance-page static
Httpservletrequestwrapper has been used to solve the get code, we use Httpservletresponsewrapper to implement the page static.

Page static is when the dynamically generated pages (jsp/servlet/velocity, etc.) are saved to the server on the first visit, and then the same request is made, the dynamic page is no longer executed, and the user responds directly to the static page that has been generated.

Filter & Decorator

/** * @author Jifang. * @since 2016/5/7 9:40.    */public class Pagestaticizefilter implements Filter {private static final String Html_path_map = "Html_path_map";    private static final String static_pages = "/static_pages/";    Private ServletContext context; public void init (Filterconfig filterconfig) throws servletexception {This.context = Filterconfig.getservletcontext        ();    This.context.setAttribute (Html_path_map, New hashmap<string, string> ()); public void Destroy () {} @SuppressWarnings (' All ') public void DoFilter (ServletRequest req, servletresponse RESP, Filterchain chain) throws IOException, servletexception {httpservletrequest request = (HttpServletRequest) r        eq        HttpServletResponse response = (httpservletresponse) resp;        map<string, string> Htmlpathmap = (map<string, string>) Context.getattribute (HTML_PATH_MAP);        String HTMLName = Request.getservletpath (). Replace ("/", "_") + ". html"; String Htmlpath = Htmlpathmap.get (HTMLName);            Static page not yet generated if (Htmlpath = = null) {Htmlpath = Context.getrealpath (static_pages) + "/" + HTMLName;            Htmlpathmap.put (HTMLName, Htmlpath);            Pagestaticizeresponse sresponse = new Pagestaticizeresponse (response, Htmlpath);            Chain.dofilter (Request, sresponse);        Sresponse.close ();        } String Redirectpath = Context.getcontextpath () + static_pages + htmlname;    Response.sendredirect (Redirectpath); } private static Final class Pagestaticizeresponse extends Httpservletresponsewrapper {private PrintWriter writ        Er Public Pagestaticizeresponse (httpservletresponse response, String path) throws FileNotFoundException,            unsupportedencodingexception {super (response);        writer = new PrintWriter (path, "UTF-8");        } @Override public PrintWriter getwriter () throws IOException {return this.writer; } public void Close () {this.writer.close (); }    }}

Registered

<filter>    <filter-name>PageStaticzeFilter</filter-name>    <filter-class>com.fq.web.filter.PageStaticizeFilter</filter-class></filter><filter-mapping>    <filter-name>PageStaticzeFilter</filter-name>    <url-pattern>*.jsp</url-pattern></filter-mapping>

Note: Here is just to provide a static idea of the page, because the code is to servlet-path granularity to generate static pages, the granularity is thicker, the details will certainly be overlooked (but the granularity of too much will lead to the generation of HTML pages too many), so this code is for reference only, not for the actual project ( For the JSP page blocked by this filter, refer to the previous blog's shopping Cart case).

Servlet–listener, Filter, Decorator

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.