所以我已经了解到spring和jax-ws的集成并不是一件容易的事情。我想将一个 spring bean 注入 jax-ws 服务,但由于某种原因,我在部署过程中遇到了异常:
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.IllegalArgumentException: javax.servlet.ServletException: com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class: class org.springframework.web.context.ContextLoaderListener|#]
这是我的 jax-ws 配置:
<wss:binding url="/ws/users">
<wss:service>
<ws:service bean="#usersWs"/>
</wss:service>
</wss:binding>
<bean id="usersWs" class="love.service.endpoint.implementations.UserServiceImpl" />
这是我的服务:
@WebService
public class UserServiceImpl implements UserService{
@EJB
private DBManager dbmanager;
@Override
@WebMethod
public boolean addUser(String name, String password, String email) {
return false;
}
@Override
@WebMethod
public boolean isUsernameAvailable(String username) {
return dbmanager.isLoginAvailable(username);
}
@Override
@WebMethod
public boolean isEmailAvailable(String email) {
return dbmanager.isEmailAvailable(email);
}
}
最后是我的 bean 配置:
<bean id="dbmanager" class="love.commons.database.DBManager" scope="request">
<aop:scoped-proxy/>
</bean>
我还尝试将 bean 注入到一些控制器中,然后它工作得很好。如果我用@Autowired 替换@EJB,应用程序会启动,但服务仍然无法工作。当我尝试向它发送消息时,我唯一的回复如下:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>Error creating bean with name 'scopedTarget.dbmanager': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>