2012-11-30 50 views
5

球衣:1.12 春:3.11 JDK:1.6.0_35 的Tomcat:6..0.33新澤西;:通過SpringServlet註冊注入ExceptionMapper實例

我試圖註冊被實例化的Jersey servlet外ExceptionMapper實例通過SpringServlet上下文中的Spring IoC容器,並且正在運行在Jersey servlet初始化期間,「組件類X的範圍必須是單例」異常。我現在無法發佈實際的代碼,所以我將給出實現的基本知識,以查看某人是否明顯突然出現某種情況,或者如果我可以指出某些文檔是我擁有的錯過。

的ExceptionMapper實例基本上如下:

// ... package definitions omitted ... 

@Provider 
@Singleton 
public class MyExceptionMapper 
    implements ExceptionMapper<MyException> 
{ 
    // ... injected attributes omitted ... 

    @Override 
    public Response toResponse(MyException exception) 
    { 
     // ... specific handling logic omitted ... 

     return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build(); 
    } 
} 

在applicationContext.xml中的豆的定義如下,獨居缺省範圍(並添加顯式說明符範圍似乎不改變行爲):

<bean id="myExceptionMapper" class="my.package.MyExceptionMapper" /> 

Spring上下文加載器監聽器和在web.xml SpringServlet配置基本上是樣板,並且servlet將加載,初始化,並與其他注入正常運行屬性,當豆defin MyExceptionMapper的ition被註釋掉了applicationContext.xml。但是,當bean定義出現在applicationContext.xml中,我得到消息記錄到的效果:我試圖把MyExceptionMapper在掃描包的層次結構由SpringServlet初始化過程中拿起

SpringProviderFactory - Registering Spring bean, myExpectionMapper, of type my.package.MyExceptionMapper as a provider class 
SpringProviderFactory - Registering Spring bean, myServiceController, of type my.package.MyServiceController as a root resource class 
... other root resource classes loading ... 
SpringServlet - Exception occurred when initialization 
java.lang.RuntimeException: The scope of the component class my.package.MyExceptionMapper must be a singleton 
    at som.sun.jersey.core.spi.component.ioc.IoCProviderFactory.wrap(...) 

,並在一個獨立的包層次結構,結果不會改變。

對此的任何幫助或指導將不勝感激。

+0

你有沒有仔細檢查您所使用的javax。在Spring中啓用injectSingleton和javax.inject註解? –

回答

1

在Spring 3.2.3和Jersey 2.3.1集成中遇到同樣的問題。

什麼爲我工作是兩個組合:

  1. 詮釋球衣@Provider@Service或使其明確單身的應用程序上下文XML

    @Service //implies a singleton-scope 
    @Provider 
    public class UnhandledExceptionMapper implements ExceptionMapper<Throwable> { 
    
        @Override 
        public Response toResponse(Throwable exception) { //... 
    
  2. 包含提供者類添加包我希望在MyApplication類中這樣做:

    public class MyApplication extends ResourceConfig { 
    public MyApplication() { 
        packages("com.mycompany.api.controller", "com.mycompany.api.jersey"); 
          //.... 
        } 
    } 
    
1

我有同樣的問題,但有一個MessageReaderWriterProvider類:

package my.provider.package; 
... 
@Provider 
@Consumes({MediaType.APPLICATION_JSON, "text/json"}) 
@Produces({MediaType.APPLICATION_JSON, "text/json"}) 
public class ReRwProvider extends AbstractMessageReaderWriterProvider<Object> { 
... 
} 

解決的辦法是添加這個類的包在新澤西州的SpringServlet一個init-param標籤在web.xml中:

<init-param> 
    <param-name>com.sun.jersey.config.property.packages</param-name> 
    <param-value>my.provider.package</param-value> 
</init-param> 

請注意,您不應該在Spring上下文中定義此bean。

4

ExceptionMapper s爲在那裏我做組件掃描結構下,而我只是用@Component春季註冊表和@Provider澤西島註解。

我的組件掃描只是看起來像:

<context:component-scan base-package="com.company.web"/> 

ExceptionMapper看起來很像你:

package com.mycompany.web.provider; 

import com.mycompany.exception.SpecialException; 
import com.mycompany.exception.Error; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 
import javax.ws.rs.ext.ExceptionMapper; 
import javax.ws.rs.ext.Provider; 

@Provider 
@Component 
public class SpecialExceptionMapper implements ExceptionMapper<SpecialException> { 

    @Autowired 
    private MessageSource messageSource; 

    @Override 
    public Response toResponse(SpecialException exception) { 

     Error error = new Error(); 


     error.errorMessage = messageSource.getMessage(exception.getResourceBundleKey(), exception.getArgs()); 

     return Response.status(Response.Status.BAD_REQUEST). 
       entity(error). 
       type(MediaType.APPLICATION_JSON). 
       build(); 
    } 
} 
4

明確添加範圍在Spring配置的伎倆對我來說:

<bean id="exceptionMapper" class="my.pkg.MyExceptionMapper" scope="singleton" /> 
+1

好吧,它的確有竅門,但這是什麼意思?默認情況下Spring不會將XML中定義的所有bean都視爲單例嗎?爲什麼我們需要明確指定這個? – saratbeesa

0

在我看來,ExceptionMapper必須配置爲「唱歌萊頓「與春天。如果你想使用註解配置,你必須注意,因爲球衣也有一個「@Singleton」註解(與彈簧解釋的javax.inject.Singleton的不同含義) 爲了避免混淆,我更喜歡使用spring @服務註釋,這意味着一個單身的範圍......所以:

import org.springframework.stereotype.Service; 

import javax.ws.rs.core.Response; 
import javax.ws.rs.ext.ExceptionMapper; 
import javax.ws.rs.ext.Provider; 

@Service //implies a singleton-scope 
@Provider 
public class UnhandledExceptionMapper implements ExceptionMapper<Throwable> { 

    @Override 
    public Response toResponse(Throwable exception) { 
     return Response.status(Response.Status.INTERNAL_SERVER_ERROR) 
       .entity(new ErrorBean(false, exception.getMessage(), null)) 
       .build(); 
    } 
} 
0

我也發現有時coustom ExceptionMapper不起作用,它並不總是工作或不工作。

所以我調試球衣的源代碼。

類:org.glassfish.jersey.server.ServerRuntime,基法:mapException

... 
final long timestamp = tracingLogger.timestamp(ServerTraceEvent.EXCEPTION_MAPPING); 
**ExceptionMapper mapper = runtime.exceptionMappers.findMapping(throwable);** 
if (mapper != null) { 
     request.getRequestEventBuilder().setExceptionMapper(mapper); 

... 如果映射爲空,coustom ExceptionMapper將無法正常工作。

類:org.glassfish.jersey.internal.ExceptionMapperFactory基法:ExceptionMapperFactory

異常映射器:(有兩個異常映射同一個例外:java.lang.Exception的)

org.glassfish.jersey .server.mvc.internal.ErrorTemplateExceptionMapper @ 6473fc2,類java.lang.Exception的

...

com.baidu.ssp.web.ws.exception.BaseExceptionMapper @ 7a84639c,類java.lang.Exception的

這是因爲在MvcFeature:

@覆蓋 公共布爾配置(最終FeatureContext上下文){ 最終配置配置= context.getConfiguration();

if (!config.isRegistered(ErrorTemplateExceptionMapper.class)) { 
    context.register(ErrorTemplateExceptionMapper.class); 
    context.register(new MvcBinder()); 

    return true; 
} 

return false; 

} 的ErrorTemplateExceptionMapper也被添加到ExceptionMapper。

,所以我我的自定義MapperException的泛型類型更改:ExceptionMapper到ExceptionMapper

可能是我的決心是不是適合你,主要的問題是ExceptionMapper