2016-04-19 13 views
2

私はSpringBootアプリケーションのプロトタイプを作成しようとしています。私はGuice JAX-RSアプリケーションから来ているので、Spring MVCへの標準のJAX-RSアノテーションを好む。私はJettyを立ち上げて提供しました:RESTEasyとのスプリングブートの統合

@Configuration 
@Import({ResteasyBootstrap.class, SpringBeanProcessorServletAware.class, HttpServletDispatcher.class}) 
public class EmbeddedJetty { 
    @Bean 
    @Singleton 
    public EmbeddedServletContainerFactory servletContainer() { 
     JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(); 
     factory.setPort(9000); 
     factory.setSessionTimeout(10, TimeUnit.MINUTES); 
     return factory; 
    } 
} 

しかし、私はちょうどRESTEasyを正しく接続する方法を理解できません。それが使用されてしまう前に、それはベイルSpringBeanProcessorServletAware以上により、一見ServletContextServletContextAwareを介して注入されていません。

java.lang.NullPointerException: null 
    at org.jboss.resteasy.plugins.spring.SpringBeanProcessorServletAware.getRegistry(SpringBeanProcessorServletAware.java:30) 
    at org.jboss.resteasy.plugins.spring.SpringBeanProcessor.postProcessBeanFactory(SpringBeanProcessor.java:247) 
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:284) 
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:174) 
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:680) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:522) 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) 

私もSpringContextLoaderListenerを使用してみましたが、それは春ブートAnnotationConfigEmbeddedWebApplicationContextクラスと競合しているようです。

私はここで、スプリングブート1.3.3と春・フレームワーク4.3.0.rc1

+1

[このプロジェクト](https://github.com/wilkinsona/spring-boot-resteasy)をご覧ください。これはブート開発者の一人によるものです –

答えて

6

他の答えは、春の豆として、あなたのリソースを持っていないだろう、この自動設定は、それらを適切に統合します:

Configurationクラス:

@Configuration 
@ConditionalOnWebApplication 
public class RestEasyAutoConfigurer { 


    private Environment environment; 

    @Bean(name = "resteasyDispatcher") 
    public ServletRegistrationBean resteasyServletRegistration() { 
     ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HttpServletDispatcher(), getPrefix() 
       + "/*"); 
     registrationBean.setInitParameters(ImmutableMap.of("resteasy.servlet.mapping.prefix", "/rs/")); // set prefix here 
     registrationBean.setLoadOnStartup(1); 
     return registrationBean; 
    } 

    @Bean(destroyMethod = "cleanup") 
    public static RestEasySpringInitializer restEasySpringInitializer() { 
     return new RestEasySpringInitializer(); 
    }  

    @Bean 
    // use Spring Boot configured Jackson 
    public CustomResteasyJackson2Provider jackson2Provider(ObjectMapper mapper) { 
     return new CustomResteasyJackson2Provider(mapper); 
    } 

    public static class RestEasySpringInitializer 
      implements 
       ServletContextInitializer, 
       ApplicationContextAware, 
       BeanFactoryPostProcessor { 

     private ResteasyDeployment deployment; 

     private ConfigurableApplicationContext applicationContext; 

     private ConfigurableListableBeanFactory beanFactory; 

     public void cleanup() { 
      deployment.stop(); 
     } 

     @Override 
     public void onStartup(ServletContext servletContext) throws ServletException { 
      ListenerBootstrap config = new ListenerBootstrap(servletContext); 
      deployment = config.createDeployment(); 
      deployment.start(); 

      servletContext.setAttribute(ResteasyProviderFactory.class.getName(), deployment.getProviderFactory()); 
      servletContext.setAttribute(Dispatcher.class.getName(), deployment.getDispatcher()); 
      servletContext.setAttribute(Registry.class.getName(), deployment.getRegistry()); 

      SpringBeanProcessor processor = new SpringBeanProcessor(deployment.getDispatcher(), 
        deployment.getRegistry(), deployment.getProviderFactory()); 
      processor.postProcessBeanFactory(beanFactory); 
      applicationContext.addApplicationListener(processor); 
     } 

     @Override 
     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
      this.beanFactory = beanFactory; 
     } 

     @Override 
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
      this.applicationContext = (ConfigurableApplicationContext) applicationContext; 
     } 
    } 
} 

ジャクソンプロバイダ:

@Provider 
@Consumes({"application/*+json", "text/json"}) 
@Produces({"application/*+json", "text/json"}) 
public class CustomResteasyJackson2Provider extends ResteasyJackson2Provider { 
    private ObjectMapper mapper; 

    public CustomResteasyJackson2Provider(ObjectMapper mapper) { 
     this.mapper = mapper; 
    } 

    @Override 
    public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) { 
     return Optional.ofNullable(_mapperConfig.getConfiguredMapper()).orElse(mapper); 
    }  
} 

注:これは、Spring Boot 1.3.3/RESTEasy 3.0.16の有効な構成です。

+0

ちょうど記録のために、 "もう一つの答えは春の豆のようにあなたの資源を持っていません"、それは真実ではありません。私の答えにあるRESTEasy Spring Bootステーターは、JAX-RSアプリケーションのサブクラスを自動的に登録するだけでなく、すべてのリソースとプロバイダをSpring Beanとして自動的に登録することを含め、完全に機能します。 – Fabio

1

を使用していますが完全に動作する例です。

  1. まず、サンプルJAX-RSエンドポイント:

    @Path("/api") 
    public class SampleResource { 
        @GET 
        @Path("/sample") 
        @Produces(MediaType.APPLICATION_JSON) 
        public String getSample() { 
         return "Some JSON"; 
        } 
    } 
    
  2. 次に、すべてのエンドポイントをロードするJAX-RSの設定クラス。

    import javax.ws.rs.core.Application; 
    
    public class RestEasyConfig extends Application { 
        @Override 
        public Set<Class<?>> getClasses() { 
         Set<Class<?>> classes = new HashSet<>(); 
         classes.add(SampleRest.class); 
         return classes; 
        } 
    } 
    
  3. 最後に、Spring構成で、RESTEastフィルタを初期化し、その存在についての枠組みを知らせます。

    import org.springframework.boot.context.embedded.FilterRegistrationBean; 
    import org.jboss.resteasy.plugins.server.servlet.FilterDispatcher; 
    ... 
    
    @Bean 
    public FilterRegistrationBean filterRegistrationBean() { 
        Map<String, String> initParams = new HashMap<>(); 
        initParams.put("javax.ws.rs.Application", RestEasyConfig.class.getCanonicalName()); 
    
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(); 
        registrationBean.setFilter(new FilterDispatcher()); 
        registrationBean.setInitParameters(initParams); 
        return registrationBean; 
    } 
    

    エンドポイントが稼働している必要があります。クラスパスにFilterDispatcherクラスがない場合は、resteasy-jaxrsライブラリをビルド記述子に追加します。

+0

ありがとう!私はこれを試しましたが、Jeff Sの言うとおり、RESTEasyのリソースはSpringのライフサイクルの一部ではありません。 @PostConstructアノテーションは起動しません。 –

2

RESTEasy Spring Bootスターターを使用できます。

は、あなたの春のブートアプリケーションのPOMファイルには、以下のMavenの依存関係を追加しPOM依存

を追加:ここでは、あなたがそれを行う方法です。

<dependency> 
    <groupId>com.paypal.springboot</groupId> 
    <artifactId>resteasy-spring-boot-starter</artifactId> 
    <version>2.1.1-RELEASE</version> 
    <scope>runtime</scope> 
</dependency> 

登録JAX-RSアプリケーションクラス

だけのSpring BeanとしてあなたのJAX-RSのアプリケーションクラス(アプリケーションのサブクラス)を定義し、それが自動的に登録されます。以下の例を参照してください。詳細については、JAX-RSアプリケーションの登録方法How to use RESTEasy Spring Boot Starterを参照してください。

package com.test; 

import org.springframework.stereotype.Component; 
import javax.ws.rs.ApplicationPath; 
import javax.ws.rs.core.Application; 

@Component 
@ApplicationPath("/sample-app/") 
public class JaxrsApplication extends Application { 
} 

登録JAX-RSリソースとプロバイダ

ただのSpring Beanとしてそれらを定義し、それらを自動的に登録されます。 JAX-RSリソースはシングルトンである必要があり、JAX-RSリソースはシングルトンでなければならないことに注意してください。

Further information at the project GitHub page

関連する問題