此内容没有您所选择的语言版本。
15.8. RESTEasy Interceptors
15.8.1. Intercept JAX-RS Invocations
RESTEasy can intercept JAX-RS invocations and route them through listener-like objects called interceptors. This topic covers descriptions of the four types of interceptors.
Example 15.3. MessageBodyReader/Writer Interceptors
@Provider
, as well as either @ServerInterceptor
or @ClientInterceptor
so that RESTEasy knows whether or not to add them to the interceptor list.
MessageBodyReader.readFrom()
or MessageBodyWriter.writeTo()
. They can be used to wrap the Output or Input streams.
public interface MessageBodyReaderInterceptor { Object read(MessageBodyReaderContext context) throws IOException, WebApplicationException; } public interface MessageBodyWriterInterceptor { void write(MessageBodyWriterContext context) throws IOException, WebApplicationException; }
MessageBodyReaderContext.proceed()
or MessageBodyWriterContext.proceed()
is called in order to go to the next interceptor or, if there are no more interceptors to invoke, the readFrom()
or writeTo()
method of the MessageBodyReader or MessageBodyWriter. This wrapping allows objects to be modified before they get to the Reader or Writer, and then cleaned up after proceed()
returns.
@Provider @ServerInterceptor public class MyHeaderDecorator implements MessageBodyWriterInterceptor { public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException { context.getHeaders().add("My-Header", "custom"); context.proceed(); } }
Example 15.4. PreProcessInterceptor
public interface PreProcessInterceptor { ServerResponse preProcess(HttpRequest request, ResourceMethod method) throws Failure, WebApplicationException; }
preProcess()
method returns a ServerResponse then the underlying JAX-RS method will not get invoked, and the runtime will process the response and return to the client. If the preProcess()
method does not return a ServerResponse, the underlying JAX-RS method will be invoked.
Example 15.5. PostProcessInterceptors
public interface PostProcessInterceptor { void postProcess(ServerResponse response); }
Example 15.6. ClientExecutionInterceptors
@ClientInterceptor
and @Provider
. These interceptors run after the MessageBodyWriter, and after the ClientRequest has been built on the client side.
public interface ClientExecutionInterceptor { ClientResponse execute(ClientExecutionContext ctx) throws Exception; } public interface ClientExecutionContext { ClientRequest getRequest(); ClientResponse proceed() throws Exception; }
15.8.2. Bind an Interceptor to a JAX-RS Method
All registered interceptors are invoked for every request by default. The AcceptedByMethod
interface can be implemented to fine tune this behavior.
Example 15.7. Binding Interceptors Example
accept()
method for interceptors that implement the AcceptedByMethod
interface. If the method returns true, the interceptor will be added to the JAX-RS method's call chain; otherwise it will be ignored for that method.
accept()
determines if the @GET annotation is present on the JAX-RS method. If it is, the interceptor will be applied to the method's call chain.
@Provider @ServerInterceptor public class MyHeaderDecorator implements MessageBodyWriterInterceptor, AcceptedByMethod { public boolean accept(Class declaring, Method method) { return method.isAnnotationPresent(GET.class); } public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException { context.getHeaders().add("My-Header", "custom"); context.proceed(); } }
15.8.3. Register an Interceptor
This topic covers how to register a RESTEasy JAX-RS interceptor in an application.
Procedure 15.3. Register an Interceptor
- To register an interceptor, list it in the
web.xml
file under theresteasy.providers
context-param, or return it as a class or as an object in theApplication.getClasses()
orApplication.getSingletons()
method.
Example 15.8. Registering an interceptor by listing it in the web.xml file
:
<context-param> <param-name>resteasy.providers</param-name> <param-value>my.app.CustomInterceptor</paramvalue> </context-param>
Example 15.9. Registering an interceptor using the Application.getClasses() method:
package org.jboss.resteasy.example; import javax.ws.rs.core.Application; import java.util.HashSet; import java.util.Set; public class MyApp extends Application { public java.util.Set<java.lang.Class<?>> getClasses() { Set<Class<?>> resources = new HashSet<Class<?>>(); resources.add(MyResource.class); resources.add(MyProvider.class); return resources; } }
Example 15.10. Registering an interceptor using the Application.getSingletons() method:
package org.jboss.resteasy.example; import javax.ws.rs.core.Application; import java.util.HashSet; import java.util.Set; public class MyApp extends Application { protected Set<Object> singletons = new HashSet<Object>(); public PubSubApplication() { singletons.add(new MyResource()); singletons.add(new MyProvider()); } @Override public Set<Object> getSingletons() { return singletons; } }
15.8.4. Interceptor Precedence Families
15.8.4.1. About Interceptor Precedence Families
Interceptors can be sensitive to the order they are invoked. RESTEasy groups interceptors in families to make ordering them simpler. This reference topic covers the built-in interceptor precedence families and the interceptors associated with each.
- SECURITY
- SECURITY interceptors are usually PreProcessInterceptors. They are invoked first because as little as possible should be done before the invocation is authorized.
- HEADER_DECORATOR
- HEADER_DECORATOR interceptors add headers to a response or an outgoing request. They follow the security interceptors as the added headers may affect the behavior of other interceptor families.
- ENCODER
- ENCODER interceptors change the OutputStream. For example, the GZIP interceptor creates a GZIPOutputStream to wrap the real OutputStream for compression.
- REDIRECT
- REDIRECT interceptors are usually used in PreProcessInterceptors, as they may reroute the request and totally bypass the JAX-RS method.
- DECODER
- DECODER interceptors wrap the InputStream. For example, the GZIP interceptor decoder wraps the InputStream in a GzipInputStream instance.
org.jboss.resteasy.annotations.interception
package: @DecoredPrecedence
, @EncoderPrecedence
, @HeaderDecoratorPrecedence
, @RedirectPrecedence
, @SecurityPrecedence
. Use these instead of the @Precedence
annotation. For more information, refer Section 15.4, “RESTEasy Defined Annotations”.
15.8.4.2. Define a Custom Interceptor Precedence Family
Custom precedence families can be created and registered in the web.xml
file. This topic covers examples of the context params available for defining interceptor precedence families.
Example 15.11. resteasy.append.interceptor.precedence
resteasy.append.interceptor.precedence
context param appends the new precedence family to the default precedence family list.
<context-param> <param-name>resteasy.append.interceptor.precedence</param-name> <param-value>CUSTOM_PRECEDENCE_FAMILY</param-value> </context-param>
Example 15.12. resteasy.interceptor.before.precedence
resteasy.interceptor.before.precedence
context param defines the default precedence family that the custom family is executed before. The parameter value takes the form DEFAULT_PRECEDENCE_FAMILY/CUSTOM_PRECEDENCE_FAMILY, delimited by a ':'.
<context-param> <param-name>resteasy.interceptor.before.precedence</param-name> <param-value>DEFAULT_PRECEDENCE_FAMILY : CUSTOM_PRECEDENCE_FAMILY</param-value> </context-param>
Example 15.13. resteasy.interceptor.after.precedence
resteasy.interceptor.after.precedence
context param defines the default precedence family that the custom family is executed after. The parameter value takes the form DEFAULT_PRECEDENCE_FAMILY/CUSTOM_PRECEDENCE_FAMILY, delimited by a :
.
<context-param> <param-name>resteasy.interceptor.after.precedence</param-name> <param-value>DEFAULT_PRECEDENCE_FAMILY : CUSTOM_PRECEDENCE_FAMILY</param-value> </context-param>