java Resteasy 3.X PreProcessInterceptor 的正确替换是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17594910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the proper replacement of the Resteasy 3.X PreProcessInterceptor?
提问by Gilberto Torrezan
I'm building rest service using an authentication/authorization mechanism as described in this tutorial: http://howtodoinjava.com/2013/06/26/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/
我正在使用本教程中描述的身份验证/授权机制构建休息服务:http: //howtodoinjava.com/2013/06/26/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/
Basically it uses the PreProcessInterceptorinterface to scan the target method for annotations (from javax.annotation.securitypackage) which describe the required roles to access that method. As the the authenticator here is an interceptor, it can cancel the target method invocation, returning a 401 (unauthorized) if needed.
基本上它使用PreProcessInterceptor接口来扫描目标方法的注释(来自javax.annotation.security包),这些注释描述了访问该方法所需的角色。由于这里的authenticator是一个拦截器,它可以取消目标方法调用,如果需要,返回401(未授权)。
The problem here is that the interface org.jboss.resteasy.spi.interception.PreProcessInterceptor is deprecated in the current RestEasy version (3.0.1), and I'm having problems trying to implement the same behaviour with the standard JAX-RS interfaces.
这里的问题是接口 org.jboss.resteasy.spi.interception.PreProcessInterceptor 在当前的 RestEasy 版本(3.0.1)中被弃用,我在尝试使用标准 JAX-RS 接口实现相同的行为时遇到问题.
I'm using the javax.ws.rs.ext.ReaderInterceptor interface to intercept the call. But somehow the server never calls it: the interceptor is just ignored.
我正在使用 javax.ws.rs.ext.ReaderInterceptor 接口来拦截调用。但不知何故,服务器从不调用它:拦截器只是被忽略了。
I'm registering the interceptors/resources the same way as I did with the former PreProcessInterceptor, and using the same @Provider and @ServerInterceptor annotations:
我正在以与以前的 PreProcessInterceptor 相同的方式注册拦截器/资源,并使用相同的 @Provider 和 @ServerInterceptor 注释:
ServerApplication:
服务器应用:
public class ServerApplication extends javax.ws.rs.core.Application {
private final HashSet<Object> singletons = new LinkedHashSet<Object>();
public ServerApplication() {
singletons.add(new SecurityInterceptor());
singletons.add( ... ); //add each of my rest resources
}
@Override
public Set<Class<?>> getClasses() {
HashSet<Class<?>> set = new HashSet<Class<?>>();
return set;
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
SecurityInterceptor:
安全拦截器:
@Provider
@ServerInterceptor
public class SecurityInterceptor implements javax.ws.rs.ext.ReaderInterceptor {
@Override
public Object aroundReadFrom(ReaderInterceptorContext context){
//code that is never called... so lonely here...
}
}
Any insights about how can I solve this problem?
关于如何解决这个问题的任何见解?
Thank you.
谢谢你。
采纳答案by Carlo Pellegrini
RESTEasy 3.x.x conforms to the JAX-RS 2.0 specification.
RESTEasy 3.xx 符合 JAX-RS 2.0 规范。
What you are trying to do could be accomplished (maybe better) with:
您可以通过以下方式完成(也许更好):
@Provider
public class SecurityInterceptor
implements javax.ws.rs.container.ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext){
if (not_authenticated){ requestContext.abortWith(response)};
}
}
since the ReaderInterceptor
is invoked only if the underlying MessageBodyReader.readFrom
is called by the standard JAX-RS pipeline, not fromthe application code.
因为ReaderInterceptor
只有MessageBodyReader.readFrom
在标准 JAX-RS 管道调用底层时才会调用 ,而不是从应用程序代码调用。
The reason why your interceptor is not called, though, could be the @ServerInterceptor
annotation, which is a RESTEasy extension.
但是,没有调用拦截器的原因可能是 @ServerInterceptor
注释,它是 RESTEasy 扩展。
The spec states at §6.5.2 that a interceptor is globally registered, unless the @Provider
is annotated with a @NameBinding
annotation, but I don't know if RESTEasy
can handle a @ServerInterceptor
if it's not explicitly registered as shown in RestEASY Interceptor Not Being Called
规范在第 6.5.2 节指出拦截器是全局注册的,除非用@Provider
注释进行@NameBinding
注释,但我不知道是否RESTEasy
可以处理 a@ServerInterceptor
如果它没有显式注册,如RestEASY Interceptor Not Being Called 中所示
回答by mtpettyp
If you need to get access to the underlying java.lang.reflect.Method
(like you used to be able to get by implementing AcceptedByMethod
), you can do the following:
如果您需要访问底层java.lang.reflect.Method
(就像您过去能够通过实现 获得AcceptedByMethod
),您可以执行以下操作:
ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker)
requestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
Method method = methodInvoker.getMethod();
回答by Rich
I also wanted to get access to the underlying java.lang.reflect.Method
and tried mtpettyp's answer with Resteasy 3.0.8, but that was returning null on the getProperty call. I am also using Spring and resteasy-spring although I don't believe that should impact this at all.
我还想访问底层java.lang.reflect.Method
并尝试使用 Resteasy 3.0.8 的 mtpettyp 答案,但这在 getProperty 调用中返回 null。我也在使用 Spring 和 resteasy-spring,尽管我认为这根本不会影响到这一点。
If you run into my situation and are implementing a Post Matching ContainerRequestFilter
(you kind of have to if you were expecting to get the matched resource method anyway) then you can actually cast the ContainerRequestContext
to the implementation Resteasy has for the Post Match scenario. The PostMatchContainerRequestContexthas a reference to the ResourceMethodInvoker.
如果您遇到我的情况并且正在实施 Post Matching ContainerRequestFilter
(如果您无论如何都希望获得匹配的资源方法,则必须这样做),那么您实际上可以将ContainerRequestContext
转换为 Resteasy 为 Post Match 场景提供的实现。该PostMatchContainerRequestContext具有对ResourceMethodInvoker参考。
public void filter(ContainerRequestContext context) throws IOException {
PostMatchContainerRequestContext pmContext = (PostMatchContainerRequestContext) context;
Method method = pmContext.getResourceMethod().getMethod();
/* rest of code here */
}