2016-09-19 60 views
0

我有一个Dropwizard 1.0.0应用程序,使用ContainerResponseFilter我希望看到一系列标题应用于每个资源 - 但我只看到它们应用于根级文档。Jersey ContainerResponseFilter不适用于所有响应

过滤器类:

package com.uk.jacob.filters; 

import javax.ws.rs.container.ContainerRequestContext; 
import javax.ws.rs.container.ContainerResponseContext; 
import javax.ws.rs.container.ContainerResponseFilter; 
import javax.ws.rs.core.MultivaluedMap; 
import java.io.IOException; 

public class SecurityFilter implements ContainerResponseFilter { 

    @Override 
    public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws IOException { 
     MultivaluedMap<String, Object> headers = containerResponseContext.getHeaders(); 

     headers.add("strict-transport-security", "max-age=31536000"); 
     headers.add("x-content-type-options", "nosniff"); 
     headers.add("x-frame-options", "SAMEORIGIN"); 
     headers.add("x-xss-protection", "1; mode=block"); 
    } 
} 

应用类:

package com.uk.jacob; 

import com.uk.jacob.filters.SecurityFilter; 
import com.uk.jacob.resources.HomepageResource; 
import io.dropwizard.Application; 
import io.dropwizard.assets.AssetsBundle; 
import io.dropwizard.client.HttpClientBuilder; 
import io.dropwizard.setup.Bootstrap; 
import io.dropwizard.setup.Environment; 
import io.dropwizard.views.ViewBundle; 
import org.apache.http.client.HttpClient; 

public class websiteApplication extends Application<websiteConfiguration> { 

    public static void main(final String[] args) throws Exception { 
     new websiteApplication().run(args); 
    } 

    @Override 
    public String getName() { 
     return "website"; 
    } 

    @Override 
    public void initialize(final Bootstrap<websiteConfiguration> bootstrap) { 
     bootstrap.addBundle(new ViewBundle<websiteConfiguration>()); 
     bootstrap.addBundle(new AssetsBundle("/public/", "/public")); 
    } 

    @Override 
    public void run(final websiteConfiguration configuration, final Environment environment) { 
     final HttpClient httpClient = new HttpClientBuilder(environment).using(configuration.getHttpClientConfiguration()).build(getName()); 

     environment.jersey().register(new SecurityFilter()); 
     environment.jersey().register(new HomepageResource(httpClient)); 
    } 

} 
+0

什么是根级别的文件?请添加不添加标题时的示例(加上您期望看到的内容)。从你提供的信息来看,这应该是正常的。 – pandaadb

+0

我运行了一个快速测试我的箱子1视图和资源和筛选器正确应用。 – pandaadb

+0

/index.html将工作 /image.png不会。这可能与AssetsBundle有关吗? –

回答

0

您的问题是AssetBundle。 AssetBundles是独立的servlet,它们不通过球衣生态系统。来源:

@Override 
public void run(Environment environment) { 
    LOGGER.info("Registering AssetBundle with name: {} for path {}", assetsName, uriPath + '*'); 
    environment.servlets().addServlet(assetsName, createServlet()).addMapping(uriPath + '*'); 
} 

这就是为什么您的过滤器不在资产资源上调用。解决这个问题的方法是编写一个额外的ServletFilter(旧样式),用于过滤资产请求并在其中添加标题。

还为了你的头添加到您的资产包,你必须使用一个普通Servlet过滤器,并与DW注册它:

这里是我的ServletFilter中的代码:

public class ServletRequestFilter implements Filter { 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 
     System.out.println("Asset filter"); 

     HttpServletResponse httpServletResponse = ((HttpServletResponse) response); 
     httpServletResponse.addHeader("ARTUR", "test"); 

     chain.doFilter(request, httpServletResponse); 
    } 

    @Override 
    public void destroy() { 
    } 

} 

这是再注册如下:

public class ViewApplication extends io.dropwizard.Application<Configuration>{ 

    @Override 
    public void run(Configuration configuration, Environment environment) throws Exception { 
     environment.jersey().register(ViewResource.class); 
     environment.jersey().register(HeaderResponseFilter.class); 
     environment.servlets().addFilter("Custom-Filter-Name", new ServletRequestFilter()).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/assets/*"); 
    } 

    @Override 
    public void initialize(Bootstrap<Configuration> bootstrap) { 
     super.initialize(bootstrap); 
     bootstrap.addBundle(new ViewBundle<>()); 
     bootstrap.addBundle(new AssetsBundle("/assets/", "/assets")); 
    } 

    public static void main(String[] args) throws Exception { 
     new ViewApplication().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test.yaml"); 
    } 

} 

注:我在/assets/注册为网址的资产包。在我的过滤器(仅过滤资产资源)的注册中也会注意到这一点。或者,你可以在所有通话中匹配它,并通过它过滤所有内容(这样你就可以摆脱我相信的球衣)。

最后的测试我的资源:

[email protected]:~/dev/repo/sandbox$ curl -v "http://localhost:9085/assets/test.txt" 
* Trying 127.0.0.1... 
* Connected to localhost (127.0.0.1) port 9085 (#0) 
> GET /assets/test.txt HTTP/1.1 
> Host: localhost:9085 
> User-Agent: curl/7.47.0 
> Accept: */* 
> 
< HTTP/1.1 200 OK 
< Date: Mon, 19 Sep 2016 15:07:13 GMT 
< ARTUR: test 
< Last-Modified: Mon, 19 Sep 2016 14:52:37 GMT 
< ETag: "0d1ae97d61a8900c99abddb8741febaf" 
< Content-Type: text/plain;charset=utf-8 
< Vary: Accept-Encoding 
< Content-Length: 11 
< 
asd 
asd 
* Connection #0 to host localhost left intact 

注意我的自定义页眉ARTUR: test

问候,

阿图尔