2016-10-14 5 views
2

Servlet 3.xコンテナのJerseyサーブレットコンテナ(2.x)の記述子なしをjavax.servlet.Filterとして実行する方法はありますか?私は、ジャージーのサーブレットコンテナがjavaxのように実行するように設定されたときに、プロパティをのみ適用されJavadocのサーブレット3.xコンテナの記述子なしジャージサーブレットコンテナ

に応じ

を私のサービスと一緒に静的なリソースを提供する必要があるため、フィルタとして実行したときのみ動作しているjersey.config.servlet.filter.forwardOn404またはjersey.config.servlet.filter.staticContentRegexを使用する必要があります.servlet.Filter。そうでない場合、このプロパティは無視されます。私はweb.xml完全

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
    version="3.1"> 
    <display-name>My-Webservice</display-name> 

    <filter> 
     <filter-name>Jersey Filter</filter-name> 
     <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class> 
     <init-param> 
      <param-name>javax.ws.rs.Application</param-name> 
      <param-value>com.foo.webservices.MyApplication</param-value> 
     </init-param> 
    </filter> 
</web-app> 

を取り除くとApplicationクラス

@ApplicationPath(value = "/") 
public class MyApplication extends ResourceConfig 
{  
    public MyApplication() 
    { 
     packages("com.foo.webservices.services"); 
     property(ServletProperties.FILTER_FORWARD_ON_404, true); 
    } 
} 

公式ドキュメント(https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet.3が)何を述べていない私のカスタムですべてを持って取得したいのですが

残念ながらフィルターについて。

答えて

2

でも可能ですが、いくつかの設定プロパティを設定するだけで簡単にはできません。それが実際にどのように機能するかについて少し理解すれば助けになるでしょう。サーブレット3.xでは、サーブレットを動的にロードするために実装できるServletContainerInitializerが導入されました(詳細はhereを参照)。 Jerseyには、それが使用する実装があります。しかし、JAX-RSの後には、アプリケーションをサーブレットとしてロードする必要があります。だからジャージーはこれを回避する方法はありません。

私たち自身でServletContainerInitializerと書くこともできますし、ジャージーズを利用することもできます。ジャージーにはSerletContainerProviderがあります。私たちはサーブレットフィルタを自分で登録する必要があります。私達は私達の実装を持っていたら、実装がこの

@Override 
public void preInit(ServletContext context, Set<Class<?>> classes) throws ServletException { 
    final Class<? extends Application> applicationCls = getApplicationClass(classes); 
    if (applicationCls != null) { 
     final ApplicationPath appPath = applicationCls.getAnnotation(ApplicationPath.class); 
     if (appPath == null) { 
      LOGGER.warning("Application class is not annotated with ApplicationPath"); 
      return; 
     } 
     final String mapping = createMappingPath(appPath); 
     addFilter(context, applicationCls, classes, mapping); 
     // to stop Jersey servlet initializer from trying to register another servlet 
     classes.remove(applicationCls); 
    } 
} 

private static void addFilter(ServletContext context, Class<? extends Application> cls, 
           Set<Class<?>> classes, String mapping) { 
    final ResourceConfig resourceConfig = ResourceConfig.forApplicationClass(cls, classes); 
    final ServletContainer filter = new ServletContainer(resourceConfig); 
    final FilterRegistration.Dynamic registration = context.addFilter(cls.getName(), filter); 
    registration.addMappingForUrlPatterns(null, true, mapping); 
    registration.setAsyncSupported(true); 
} 

ようになります、私たちはクラスパスのルートにあるべきファイル

META-INF/services/org.glassfish.jersey.servlet.internal.spi.ServletContainerProvider 

を作成する必要があります。そのファイルの内容は、実装の完全修飾名でなければなりません。

あなたはあなたに感謝し、このGitHub Repo

+0

グレート答えに完全な例を見ることができます。アプリケーションクラスとして 'org.glassfish.jersey.server.ResourceConfig $ RuntimeConfig'を誤って識別したので、もう一度getApplicationClassメソッドに別のチェックを追加しなければなりませんでした。 'break'ステートメントの周りに' if(applicationCls!= null && applicationCls.getAnnotation(ApplicationPath.class)!= null) 'を追加しました。 – lazlev