Implement your own interceptor

Source: Internet
Author: User

In the previous article, we introduced the principle of struts2 Interceptor. In this article, we will learn how to compile our own interceptor.

1. Implementation of interceptor

It is very easy to implement an interceptor. In fact, an interceptor is a common class, but this class must implement the com. opensymphony. xwork2.interceptor. interceptor interface. The interceptor interface has the following three methods:

Publicinterfaceinterceptorextendsserializable
{
Voiddestroy ();
Voidinit ();
Stringintercept (actioninvocationinvocation) throwsexception;
}

The init and destroy methods are executed only once when the interceptor loads and releases (both processed by struts2 itself. The intercept method is called every time it is accessed. When struts2 calls an interceptor, each interceptor class has only one object instance, and all actions that reference this interceptor share the object instance of this interceptor class. Therefore, if you use class variables in the class implementing the interceptor interface, pay attention to the synchronization problem.

Next we will implement a simple interceptor, which specifies a method in the interceptor class through the request parameter action, and call this method (we can use this Interceptor to pre-process a specific action ). If the method does not exist or the action parameter does not exist, execute the following code. URL:

Http: // localhost: 8080/struts2/test/Interceptor. Action? Action = test

After accessing the URL above, the interceptor will call the test method in the Interceptor. If this method does not exist, the invocation will be called. invoke method. The invoke method and Servlet filter call filterchain. the dofilter method is similar. If there are other interceptors behind the current interceptor, The invoke method is to call the intercept method of the later interceptor. Otherwise, invoke calls the execute method (or other execution methods) of the Action class ).

Next we will first implement an actioninterceptor of the parent class of the interceptor. This class mainly implements the function of calling methods based on the value of the action parameter. The Code is as follows:
Packageinterceptor;

importcom.opensymphony.xwork2.ActionInvocation;
importcom.opensymphony.xwork2.interceptor.Interceptor;
importjavax.servlet.http.*;
importorg.apache.struts2.*;
publicclassActionInterceptorimplementsInterceptor
{
  protectedfinalStringINVOKE="##invoke";
 
  publicvoiddestroy()
  {
    System.out.println("destroy");
  }
  publicvoidinit()
  {
    System.out.println("init");
  }
  publicStringintercept(ActionInvocationinvocation)throwsException
  {  
    HttpServletRequestrequest=ServletActionContext.getRequest();
    Stringaction=request.getParameter("action");
    System.out.println(this.hashCode());
    if(action!=null)
    {
      try
      {
        java.lang.reflect.Methodmethod=this.getClass().getMethod(action);
        Stringresult=(String)method.invoke(this);
        if(result!=null)
        {
          if(!result.equals(INVOKE))
            returnresult;
        }
        else
          returnnull;
      }
      catch(Exceptione)
      {
      }
    }
    returninvocation.invoke();
  }
}

From the intercept method in the code above, we can see that after calling the method specified by action, we can determine the return value. There are three possible scenarios:

1. If the returned value is null, return NULL is executed.

2. If the returned value is invoke, run return invockation. Invoke ().

3. In other cases, execute return result. Result indicates the return value of the specified method, as shown in the code above.

After the above interceptor parent class is implemented, any interceptor inherited from the actioninterceptor class can automatically call its own corresponding method based on the value of the action parameter. Next we will implement an interceptor class with two action Methods: Test and print. The Code is as follows:

Packageinterceptor;

importjavax.servlet.http.HttpServletResponse;
importorg.apache.struts2.ServletActionContext;
publicclassMultiMethodInterceptorextendsActionInterceptor
{
  publicStringtest()throwsException
  {
    HttpServletResponseresponse=ServletActionContext.getResponse();
    response.getWriter().println("invoketest");
    returnthis.INVOKE;
  }
  publicStringprint()throwsException
  {
    HttpServletResponseresponse=ServletActionContext.getResponse();
    response.getWriter().println("invokeprint");
    returnnull;
  }
}

The test method returns invoke. Therefore, after executing this method, struts2 will then call the intercept method of another interceptor or the execute method of the action class. After the print method is executed, it returns NULL instead of calling other methods. When the following URL is accessed, the execute method of the action will not be executed:

Http: // localhost: 8080/struts2/test/DDD. Action? Action = print

The following code implements an action class:

Packageaction;

importorg.apache.struts2.*;
importcom.opensymphony.xwork2.ActionSupport;
publicclassInterceptorActionextendsActionSupport
{
  publicStringabcd()throwsException
  {
    ServletActionContext.getResponse().getWriter()
        .println("invokeabcd");
    returnnull;
  }
}

In this action class, there is only one ABCD method. In fact, this method is equivalent to the execute method. The method attribute of the action is set to ABCD below. The following code defines interceptor classes and actions in struts. xml:

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
  "-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.0//EN"
  "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
  <packagename="demo"extends="struts-default"namespace="/test">
    <interceptors>
      <interceptorname="method"class="interceptor.MultiMethodInterceptor"/>
        <interceptor-stackname="methodStack">
          <interceptor-refname="method"/>
          <interceptor-refname="defaultStack"/>
        </interceptor-stack>
    </interceptors>
    <actionname="interceptor"class="action.InterceptorAction"method="abcd">
      <interceptor-refname="methodStack"/>
    </action>
  </package>
</struts>

When configuring the above methodstack interceptor, it is best to reference defaultstack later. Otherwise, many functions provided by the interceptor will be lost.

OK. Visit the following URL:

Http: // localhost: 8080/struts2/test/DDD. Action? Action = test

The following string will appear in the browser:

Invoke Test

Invoke ABCD

And if you access http: // localhost: 8080/struts2/test/DDD. Action? Action = print, only the following strings will appear:

Invoke print

We can see that the ABCD method is not called when accessing this URL. If the value of the action is specified, only the ABCD method is called, for example, http: // localhost: 8080/struts2/test/DDD. Action? Action = aaa, only invoke ABCD is output.

Ii. interceptor Parameters

When using many built-in interceptors of struts2, we will find that many interceptors contain parameters, of course. We can add the same parameters to our own interceptor. Two parameters are commonly used. These two parameters are includemethods and excludemethods. includemethods specifies the execution method of the action class to be called by the Interceptor (execute by default). That is to say, the method specified in includemethods is called by struts2, while excludemethods is the opposite. The execution method specified in this parameter is not called by struts2. Multiple methods are separated by commas. In struts2, an abstract class is provided to process these two parameters. This class is as follows:

com.opensymphony.xwork2.interceptor.MethodFilterInterceptor

If any interceptor class that inherits this class will automatically process the includemethods and excludemethods parameters, as shown in the following interceptor class:

Packageinterceptor;

importcom.opensymphony.xwork2.ActionInvocation;
importcom.opensymphony.xwork2.interceptor.*;
publicclassMyFilterInterceptorextendsMethodFilterInterceptor
{
  privateStringname;
  publicStringgetName()
  {
    returnname;
  }
  publicvoidsetName(Stringname)
  {
    this.name=name;
  }
  @Override
  protectedStringdoIntercept(ActionInvocationinvocation)throwsException
  {
    System.out.println("doIntercept");
    System.out.println(name);
    returninvocation.invoke();
  }
}】

The subclass of methodfilterinterceptor must implement the dointercept method (equivalent to the intercept method of interceptor), as shown in the code above. The code above also has a name attribute set to read the name attribute of the interceptor, as shown in the following configuration code:

<? Xmlversion = "1.0" encoding = "UTF-8"?>
<! Doctypestrutspublic
"-// Apachesoftwarefoundation // dtdstrutsconfiguration2.0 // en"
Http://struts.apache.org/dtds/struts-2.0.dtd>
<Struts>
<Packagename = "Demo" extends = "struts-Default" namespace = "/test">
<Interceptors>
<Interceptorname = "method" class = "Interceptor. multimethodinterceptor"/>
<Interceptorname = "filter"
Class = "Interceptor. myfilterinterceptor">
<Paramname = "includemethods"> ABCD </param>
<Paramname = "name"> China </param>
</Interceptor>
<Interceptor-stackname = "methodstack">
<Interceptor-refname = "method"/>
<Interceptor-refname = "filter"/>
<Interceptor-refname = "defaultstack"/>
</Interceptor-stack>
</Interceptors>
<Actionname = "Interceptor" class = "Action. interceptexception" method = "ABCD">
<Interceptor-refname = "methodstack"/>
</Action>
</Package>
</Struts>

Access http: // localhost: 8080/struts2/test/DDD. Action again? Action = test, struts2 will call the dointercept method of myfilterinterceptor to output the name attribute value. If you remove the ABCD from the above includemethods parameter value, the ABCD method of the action class will not be executed.

Collected on:

http://tech.ddvip.com/2009-01/1232099428106076_7.html

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.