2011-10-31 82 views
0

我有一個自定義的InjectionProvider,它從SecurityContext中檢索User對象並使其可用。自定義ResourceFilter執行HTTP基本身份驗證,創建SecurityContext並使用Principal來填充它。這是基於this suggestionJersey:注入在資源方法中工作,但不能用於EJB屬性

當我從一個資源的方法訪問它,它按預期工作:

@Stateless 
@Path("foo") 
public class FooResource { 

    @GET 
    @ResourceFilters(value = {UserAuthenticationFilter.class}) 
    public Response get(@Context User user) { 
    return Response.ok().entity(user).build(); 
    } 
} 

然而,當我嘗試注入的對象作爲一個屬性/字段添加到EJB,異常拋出,即使我可以在日誌中看到,InjectionProvider被調用:

@Stateless 
@Path("foo") 
public class FooResource { 

    @Context 
    private User user; 

    @GET 
    @ResourceFilters(value = {UserAuthenticationFilter.class}) 
    public Response get() { 
    return Response.ok().entity(user).build(); 
    } 
} 

唯一的例外是奇怪:

 
[#|2011-10-31T13:35:47.691+0000|WARNING|glassfish3.1.1|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=18;_ThreadName=Thread-3;|StandardWrapperValve[Gateway Servlet]: PWC1406: Servlet.service() for servlet Gateway Servlet threw exception 
javax.ejb.CreateException: Could not create stateless EJB 
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:534) 
    at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:95) 
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:724) 
    at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:247) 
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:449) 
    at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2528) 
    at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1895) 
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212) 
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88) 
    at $Proxy166.get(Unknown Source) 
.... 
Caused by: com.sun.jersey.spi.inject.Errors$ErrorMessagesException 
    at com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170) 
    at com.sun.jersey.spi.inject.Errors.postProcess(Errors.java:136) 
    at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:199) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl$ComponentProcessorFactoryImpl.get(WebApplicationImpl.java:499) 
    at com.sun.jersey.server.impl.ejb.EJBInjectionInterceptor.get(EJBInjectionInterceptor.java:104) 
    at com.sun.jersey.server.impl.ejb.EJBInjectionInterceptor.init(EJBInjectionInterceptor.java:71) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCallback(SystemInterceptorProxy.java:133) 
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.init(SystemInterceptorProxy.java:120) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at com.sun.ejb.containers.interceptors.CallbackInterceptor.intercept(InterceptorManager.java:964) 
    at com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(CallbackChainImpl.java:65) 
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:393) 
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:376) 
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:526) 
    ... 55 more 

我在做什麼錯?

編輯:我只注意到拋出異常之前,錯誤報告在server.log:

 
[#|2011-10-31T15:33:01.854+0000|SEVERE|glassfish3.1.1|com.sun.jersey.spi.inject.Errors|_ThreadID=18;_ThreadName=Thread-3;|The following errors and warnings have been detected with resource and/or provider classes: 
    SEVERE: Missing dependency for field: private com.skalio.bonusapp.core.User com.skalio.bonusapp.gateway.FooResource.user|#] 

回答

0

這是由於範圍不匹配。您正試圖將一個請求範圍的東西注入到一個沒有請求作用域的bean中。這是行不通的。

+0

好吧,我明白了。資源本身不是請求範圍,但方法調用顯然是。謝謝。還有其他方法嗎?或者它會在每個(相關)方法調用中注入用戶是否是一種很好的模式? – Hank

+1

平原資源是請求範圍的 - 但無狀態EJB資源不是。你可以嘗試的一個想法是使User對象成爲一個單例(實現單例注入提供者),它利用ThreadLocals爲給定上下文提供它的屬性的正確值。或者你可以使用帶有getUser()方法的UserInfo對象,它返回給定線程的正確用戶(使用ThreadLocals),並且你會注入它。您可以使用ContainerRequestFilter爲給定線程和ContainerResponseFilter設置該對象的值,以在請求處理完成後進行清理。 –