2013-02-06 2 views
7

Spring과 Jersey를 모두 사용하는 Servlet 3.0 웹 앱이 있습니다. 현재 web.xml에서 필터로 구성된 SpringServlet과 @Path@Component이라는 주석이 달린 리소스 클래스를 사용하여 설정했습니다. 다음은 web.xml 코드입니다.annotation만을 사용하여 Spring에서 Jersey를 구성하는 방법

<filter> 
    <filter-name>jersey-serlvet</filter-name> 
    <filter-class> 
     com.sun.jersey.spi.spring.container.servlet.SpringServlet 
    </filter-class> 
    <init-param> 
     <param-name> 
      com.sun.jersey.config.property.packages 
     </param-name> 
     <param-value>com.foo;com.bar</param-value> 
    </init-param> 
    <init-param> 
     <param-name>com.sun.jersey.config.feature.FilterForwardOn404</param-name> 
     <param-value>true</param-value> 
    </init-param> 
</filter> 

<filter-mapping> 
    <filter-name>jersey-serlvet</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

이 설정은 작동하지만이 설정은 주석이있는 경우에만 적용됩니다. no web.xml config. 첫 번째 시도는 위의 SpringServlet 구성을 제거하고 Application을 확장하는 클래스를 만드는 것입니다. 다음은 그의 조각입니다 :

@ApplicationPath("/*") 
public class MyApplication extends PackagesResourceConfig { 

    public MyApplication() { 
     super("com.foo;com.bar"); 

     HashMap<String, Object> settings = new HashMap<String, Object>(1); 
     settings.put(ServletContainer.FEATURE_FILTER_FORWARD_ON_404, true); 
     this.setPropertiesAndFeatures(settings); 
    } 
} 

이는 JAX-RS 자원이 등록되어 내가 해당 URL에 그들을 칠 수 있다는 점에서 작동은하지만 시도하고 이것이하게 ... 자신의를 autowire 속성을 사용할 때 그들은 NullPointerExceptions를 던져 왜냐하면 저는 자원이 Jersey에 의해로드되고 있고 Spring 관리 bean이 아니므로 autowiring이 없기 때문입니다.

주위를 둘러싼 검색에도 불구하고 저지 (Jersey) 리소스를 주석이있는 스프링 빈으로로드하는 방법을 찾을 수 없습니다. 그런 방법이 있습니까? 리소스를 수동으로 Spring 컨텍스트를 가져오고 도움을 줄 수있는 DI 호출 코드를 작성하고 싶지는 않습니다.

annotations-only가 작동하지 않을 경우, 검사 할 패키지 목록 대신로드 할 Application 클래스를 지정할 수 있으면 web.xml에 필터 설정으로 살 수 있습니다. 패키지 목록을 없애고 Application 클래스 인스턴스를 지정하면 내용에 만족하게 될 것입니다.

분명히 누군가가 나를 위해 확실한 답을 얻은다면 좋겠지 만, 다른 포인터 나 시도 할만한 것들에 대한 조언이나 힌트에 감사 할 것입니다.

덕분에, 매트

답변

1

나는 나의 이상적인 결과를 얻을 수 없었다 그러나 나는 약간의 진전을 할 수 있었다, 그래서 다른 사람을 도움이 나는 경우에 여기에 게시합니다. 스프링 서블릿을 사용하여 애플리케이션 클래스를 지정함으로써 web.xml에서 패키지 목록을 제거 할 수있었습니다. 필요한

은 web.xml 변경 (필터 매핑이 표시되지 않습니다하지만 여전히 필요합니다) 초기화 PARAMS에 있습니다

<filter> 
    <filter-name>jersey-serlvet</filter-name> 
    <filter-class> 
     com.sun.jersey.spi.spring.container.servlet.SpringServlet 
    </filter-class> 
    <init-param> 
     <param-name>javax.ws.rs.Application</param-name> <!-- Specify application class here --> 
     <param-value>com.foo.MyApplication</param-value> 
    </init-param> 
</filter> 

그리고 응용 프로그램 클래스에 나는 내가라는 방식을 변경했다 약간 슈퍼 생성자 : 아직도

public MyApplication() { 
    super("com.foo", "com.bar"); // Pass in packages as separate params 

    HashMap<String, Object> settings = new HashMap<String, Object>(1); 
    settings.put(ServletContainer.FEATURE_FILTER_FORWARD_ON_404, true); 
    this.setPropertiesAndFeatures(settings); 
} 

정확히 내가 뭘 후했지만 적어도이 자바 코드에 내가 숨길려고 나를 위해 중요하다 web.xml을, 밖으로 좀 더 설정을 가져옵니다 이 세부 사항.

1

두 가지 옵션이 마음을 사로 잡습니다.

  1. 아마도 자신의 클래스로 SpringServlet을 확장하고 적절한 서블릿 3.0 주석을 추가 할 수 있습니다.
  2. SpringServlet 클래스에서 Application 클래스로 전환하는 방법과 함께, Spring 빌드 타임이나로드 타임 바이트 코드 위빙을 활성화하여 자동로드가되지 않는 문제를 해결할 수 있습니다.이를 통해 Spring은 Spring에 의해 생성 된 객체가 아닌 어디서나 인스턴스화 된 객체를 삽입 할 수 있습니다. "Using AspectJ to dependency inject domain objects with Spring"을 참조하십시오.
1

우선 서블릿 3.0 컨테이너에는 web.xml이 필요하지 않습니다.

그러나 뉴저지 2.0 당신이 주석 자원에 대한 전체 웹 응용 프로그램을 스캔하는 플래그를 설정할 수 있습니다

는 :

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<servlet> 
    <servlet-name>jersey</servlet-name> 
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 
    <init-param> 
     <param-name>jersey.config.servlet.provider.webapp</param-name> 
     <param-value>true</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
는 는이 단지를 포함하면 봄이 자동으로 활성화됩니다

:

다음
<dependency> 
     <groupId>org.glassfish.jersey.ext</groupId> 
     <artifactId>jersey-spring3</artifactId> 
     <version>2.3.1</version> 
    </dependency> 
+0

감사

// Specifies that there will be bean methods annotated with @Bean tag // and will be managed by Spring @Configuration // Equivalent to context:component-scan base-package="..." in the xml, states // where to find the beans controlled by Spring @ComponentScan(basePackages = "config.package") public class AppConfig { /** * Where will the project views be. * * @return ViewResolver como el XML */ @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); return viewResolver; } } 

최대 절전 모드 설정,하지만 난 저지 1 사용하고 있는데 내가 어떤 문제가 점점이없는 : config.package에서

public class WebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) { // Don't create the Listener that Jersey uses to create. // There can only be one linstener servletContext.setInitParameter("contextConfigLocation", "<NONE>"); AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); // Add app config packages context.setConfigLocation("config.package"); // Add listener to the context servletContext.addListener(new ContextLoaderListener(context)); // Replacing: // <servlet-name>ServletName</servlet-name> // <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> // <init-param> // <param-name>com.sun.jersey.config.property.packages</param-name> // <param-value>webservices.packages</param-value> // </init-param> // <load-on-startup>1</load-on-startup> AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext(); ServletRegistration.Dynamic appServlet = servletContext.addServlet("ServletName", new DispatcherServlet(dispatcherContext)); appServlet.setInitParameter("com.sun.jersey.config.property.packages", "org.sunnycake.aton.controller"); appServlet.setLoadOnStartup(1); appServlet.addMapping("/RootApp"); } } 

구성 클래스는 Jersey 리소스가로드되어 실행 중입니다. 문제는 제가 스프링에 의해 관리되기를 원해서 autowiring이되는 것입니다. – Doughnuts

+0

좋습니다. 그렇다면이 방법은 해결책이 아닙니다. 그러나 이것은 분명히 알 수 있습니다 : 이것은 스프링 자동 와이어 링을 가능하게합니다. – rustyx

2

입니다 Servlet 3.0, Spring, Jersey 1.8을 사용하는 애플리케이션의 일부이며 web.xml도 없다 :

public class WebAppInitializer implements WebApplicationInitializer { 

@Override 
public void onStartup(ServletContext servletContext) throws ServletException { 
    final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); 
    context.setConfigLocation("com.myapp.config"); 

    final FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("characterEncodingFilter", new CharacterEncodingFilter()); 
    characterEncodingFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); 
    characterEncodingFilter.setInitParameter("encoding", "UTF-8"); 
    characterEncodingFilter.setInitParameter("forceEncoding", "true"); 

    final FilterRegistration.Dynamic springSecurityFilterChain = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy()); 
    springSecurityFilterChain.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); 

    servletContext.addListener(new ContextLoaderListener(context)); 
    servletContext.setInitParameter("spring.profiles.default", "production"); 

    final SpringServlet servlet = new SpringServlet(); 

    final ServletRegistration.Dynamic appServlet = servletContext.addServlet("appServlet", servlet); 
    appServlet.setInitParameter("com.sun.jersey.config.property.packages", "com.myapp.api"); 
    appServlet.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters", "com.myapp.api.SizeLimitFilter"); 
    appServlet.setLoadOnStartup(1); 

    final Set<String> mappingConflicts = appServlet.addMapping("/api/*"); 

    if (!mappingConflicts.isEmpty()) { 
     throw new IllegalStateException("'appServlet' cannot be mapped to '/' under Tomcat versions <= 7.0.14"); 
    } 
} 

}

0

이전에 만든 프로젝트에서 SpringMVC를 사용하여 Jersey를 사용했습니다. 내 코드는 Spring's official documentation에 기반을 두었습니다. 답변에 대한

// Specifies that there will be bean methods annotated with @Bean tag 
// and will be managed by Spring 
@Configuration 
// Equivalent to Spring's tx in the xml 
@EnableTransactionManagement 

// Equivalent to context:component-scan base-package="..." in the xml, states 
// where to find the beans controlled by Spring 
@ComponentScan({"config.package"}) 

// Here it can be stated some Spring properties with a properties file 
@PropertySource(value = {"classpath:aplicacion.properties"}) 
public class HibernateConfig { 

    /** 
    * Inyected by Spring based on the .properties file in the 
    * \@PropertySource tag. 
    */ 
    @Autowired 
    private Environment environment; 

    /** 
    * Here it's created a Session Factory, equivalent to the Spring's config file one. 
    * 
    * @return Spring Session factory 
    */ 
    @Bean 
    public LocalSessionFactoryBean sessionFactory() { 
     LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 

     // Uses the datasource 
     sessionFactory.setDataSource(dataSource()); 

     // Indicates where are the POJOs (DTO) 
     sessionFactory.setPackagesToScan(new String[]{"dto.package"}); 
     // Se asignan las propiedades de Hibernate 
     sessionFactory.setHibernateProperties(hibernateProperties()); 

     return sessionFactory; 
    } 

    /** 
    * Propiedades de la base de datos (Según environment) 
    * 
    * @return Nuevo DataSource (Configuración de la base de datos) 
    */ 
    @Bean 
    public DataSource dataSource() { 
     DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName")); 
     dataSource.setUrl(environment.getRequiredProperty("jdbc.url")); 
     dataSource.setUsername(environment.getRequiredProperty("jdbc.username")); 
     dataSource.setPassword(environment.getRequiredProperty("jdbc.password")); 
     return dataSource; 
    } 

    /** 
    * Hibernate properties 
    * 
    * @return Properties set with the configuration 
    */ 
    private Properties hibernateProperties() { 
     Properties properties = new Properties(); 
     // Dialect (Mysql, postgresql, ...) 
     properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect")); 
     // Show SQL query 
     properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")); 
     properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql")); 
     return properties; 
    } 

    /** 
    * Inyected by sessionFactory 
    */ 
    @Bean 
    @Autowired 
    public HibernateTransactionManager transactionManager(SessionFactory s) { 
     HibernateTransactionManager txManager = new HibernateTransactionManager(); 
     txManager.setSessionFactory(s); 
     return txManager; 
    } 
} 
관련 문제