ContainerRequestContext

ContainerRequestContext

我是DropWizard框架和Jersey的新手。因此,我在这里可能要完成的工作可能完全偏离了轨道。

我遇到了一个问题,我通过预匹配的请求过滤器添加到我的请求标头中的参数没有到达我的AuthCredentials对象的自定义提供程序。我正在尝试为每个需要从标头参数进行身份验证的资源提供AuthCredentials对象。由于我要提供身份验证标头所依赖的一项服​​务尚未准备就绪,因此我自己通过在匹配前请求过滤器中添加它们来伪造它们。

这是我的代码

 @PreMatching
 @Provider
 class MyFilter implements ContainerRequestFilter{
   @Override
   public void filter(ContainerRequestContext requestContext) throws IOException {
        requestContext.getHeaders().add("param1", "value1");
   }
}


class MyAuthCredentialsFactory implements Factory<AuthCredentials>{
     @Inject
     public MyAuthCredentialsFactory(HttpServletRequest request){
          System.out.println("Param1 header value = " + request.getHeader("param1")); // <---This prints null
     }
}


我在拖放向导框架的应用程序的run方法中注册这些类,如下所示。

@Override
    public void run(ServerConfigType configuration,
                    Environment environment) {
        environment.jersey().register(new AbstractBinder() {
               @Override
               protected void configure() {
                  bindFactory(MyAuthCredentialsFactory.class).to(AuthCredentials.class).in(RequestScoped.class);
               }
    });
    environment.jersey().register(MyFilter.class);


我的资源使用这样的身份验证凭据

@Path("/pathtomyresource")
public class MyApi {
    @Inject AuthCredentials authCredentials;
}


我正在使用DropWizard 0.8.3和Jackson 2.5.3。

当我从标题打印param1的值时,我得到的是空值。我在调试器中查看了HttpServletRequest的标头名称,但没有在其中找到解释为什么该值为null的param1。我在互联网上对此进行了大量研究,发现它应该可以工作,但对我不起作用。在这一点上,我感到困惑,非常感谢您的帮助。

最佳答案

HttpServletRequestContainerRequestContext是不同的东西,在后者中设置内容不会导致将其放入前者中。您可以将ContainerRequestContext注入Factory中,然后从那里获取属性

 @Inject
 public MyAuthCredentialsFactory(ContainerRequestContext request){
 }


就我个人而言,当我需要访问请求上下文时,我要做的只是实现Factory而不是实现AbstractContainerRequestValueFactory,而是扩展了here。然后,您可以调用getContainerRequest()以获得ContainerRequest(实际上是相同的ContainerRequestContext

class MyAuthCredentialsFactory
        extends AbstractContainerRequestValueFactory<AuthCredentials> {
    @Override
    public AuthCrendials provide() {
        ContainerRequest request = getContainerRequest();
        String header = request.getHeaderString(...);
    }
}


另外,也可以不设置标题,而可以使用ContainerRequestContextsetProperty(key, value)上设置任意属性,然后在工厂中使用getProperty(key)进行设置即可。

09-28 00:08