java 无法将 Bean 类注入 Restfull WebService (JAX-RS)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16914671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cant inject Bean class into Restfull WebService (JAX-RS)
提问by user2377971
I'm trying to save data acquired by Rest web service to database using hibernate/persistence. In one of my web modules i implemented that service. Database ejb connector is placed in EJB module. They are parts of EAR application. Every time when i call pb.addDevice() im getting java.lang.NullPointerException when puting proper url with params in browser(worked till i wanted to save it to Database). Can't find what is wrong with it. I'm using jboss 6.1.0 Final.
我正在尝试使用休眠/持久性将 Rest Web 服务获取的数据保存到数据库中。在我的一个 Web 模块中,我实现了该服务。数据库 ejb 连接器放置在 EJB 模块中。它们是 EAR 应用程序的一部分。每次当我调用 pb.addDevice() 时,我都会在浏览器中放置带有参数的正确 url 时得到 java.lang.NullPointerException(一直工作到我想将其保存到数据库)。找不到它有什么问题。我正在使用 jboss 6.1.0 Final。
tried answer of Dependency injection in restful WS
and after following it step by step im alse getting nullpointer also
并且在一步一步跟随它之后我也得到了空指针
PS. when i changed from
附注。当我从
@EJB
PersistenceBean pb;
to
到
PersistenceBean pb = new PersistenceBean();
i got null pointer on EntityManager em = emf.createEntityManager();
我在 EntityManager 上得到了空指针 em = emf.createEntityManager();
code:
代码:
@Stateless
@Path("/RestService")
public class RestPush {
@EJB
PersistenceBean pb;
@GET
@Path("/RegisterDevice")
public void registerDevice(
@QueryParam("deviceId") String deviceId){
Device d = new Device(true);
d.setId = deviceId;
pb.addDevice(d);
}
}
and EJB class:
和 EJB 类:
@Stateless(mappedName = "PersistenceBean")
public class PersistenceBean {
@PersistenceUnit(unitName = "PersistentUnitName")
EntityManagerFactory emf;
private void persist(Object o, EntityManager entityManager) {
try {
entityManager.persist(o);
} catch (Exception e) {
logger.severe("Error writing to DB: " + e);
logger.severe("" + e.fillInStackTrace());
}
}
public void addDevice(Device d) {
try {
EntityManager em = emf.createEntityManager();
if (persist(device, em)) {
logger.info("Device with id : " + device.getId()
+ " has been added ");
} else {
logger.info("Failed to add device with id: " + device.getId());
} catch (Exception e) {
logger.severe("PersistenceBean: Could not save device.");
e.printStackTrace();
}
}
upadate:
更新:
EAR
--EarContent
--META-INF
--application.xml
EJB
--package in ejbModule
--PersistenceBean
--Device
--META-INF
--ejb-jar.xml
--MANIFEST.MF
--persistence.xml
--beans.xml
Web
--package in webModule
--Rest (auto generated class while creating Webservice)
--RestPush
--WebContent
--META-INF
--MANIFEST.MF
--WEB-INF
--web.xml
--beans.xml
stack trace:
堆栈跟踪:
`10:23:28,629 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/RestWeb].[Resteasy]] Servlet.service() for servlet Resteasy threw exception: org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
at
Caused by: java.lang.NullPointerException
at package.RestPush.registerDevice(RestPush.java:68) [:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_27]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [:1.6.0_27]
采纳答案by Carlo Pellegrini
The @EJB
annotation is not supposed to work for all objects.
该@EJB
注释是不应该工作的所有对象。
For this to work you need to use CDI, so substitute the @EJB
with @Inject
and your bean will be correctly injected.
为此,您需要使用 CDI,因此替换@EJB
with@Inject
并且您的 bean 将被正确注入。
See also: Inject an EJB into JAX-RS (RESTful service)
另请参阅:将 EJB 注入 JAX-RS(RESTful 服务)
EDIT:
编辑:
Also be sure to add beans.xml
to every jar/war archive containing classes you want to inject or be injected. It goes into META-INF
for jars and WEB-INF
for wars.
还要确保添加beans.xml
到每个包含要注入或被注入的类的 jar/war 存档中。它META-INF
用于罐子和WEB-INF
War。
Your REST application class packaget.Rest
should extend javax.ws.rs.core.Application
as in:
您的 REST 应用程序类packaget.Rest
应该扩展javax.ws.rs.core.Application
为:
@ApplicationPath("/root-path")
public class Rest extends Application
{
}
And according to the documentation hereon JBoss 6.1 REST and CDI should work out of the box. If you specify the org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher and the org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap you are probably messing up the RestEasy/CDI classloading.
根据这里的文档,JBoss 6.1 REST 和 CDI 应该是开箱即用的。如果你指定 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher 和 org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap 你可能会搞砸 RestEasy/CDI 类加载。
So your web.xml
should look as:
所以你web.xml
应该看起来像:
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee java.sun.com/xml/ns/javaee/…">
</web-app>
Anyway, I pushed a working example on github
无论如何,我在github上推送了一个工作示例
回答by Roland
You should add /src/main/resources/META-INF/beans.xml
. This will enable injection.
你应该添加/src/main/resources/META-INF/beans.xml
. 这将启用注入。
回答by user1913596
I has similar issue, for me the problem was creating my RESTful bean on my own with constructor, which was dumb while using EJBs and @EJB injection:
我有类似的问题,对我来说问题是我自己用构造函数创建我的 RESTful bean,这在使用 EJB 和 @EJB 注入时很愚蠢:
PROBLEM:
问题:
@ApplicationPath("/")
public class RestApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
public RestApplication() {
singletons.add(new RestService());
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
SOLUTION:
解决方案:
@ApplicationPath("/")
public class RestApplication extends Application {
}
Hope it might save sb's time.
希望它可以节省某人的时间。