JAX-RS + JBoss 7.1.1 + RESTEasy:使用 CDI 的 NullPointException
Posted
技术标签:
【中文标题】JAX-RS + JBoss 7.1.1 + RESTEasy:使用 CDI 的 NullPointException【英文标题】:JAX-RS + JBoss 7.1.1 + RESTEasy: NullPointException using CDI 【发布时间】:2013-11-21 16:28:21 【问题描述】:我正在开发 Java EE 6 解决方案,并试图找出依赖注入不起作用的根本原因...我的服务中的 NullPointerException(userDao 行):
REST 服务
@Path("rest")
public class UserRESTService
@EJB
UserDAO userDao;
@GET
@Produces(MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON)
@Path("type")
public String getJqGridData(@PathParam("type") String type)
System.out.println("type: " + type);
List<USUARIO> usuarios = userDao.findAll();
int pageSize = 10;
int pageNumber = ((int) usuarios.size()/pageSize)+1;
JqGridData<USUARIO> data = new JqGridData<USUARIO>(pageNumber, 1, usuarios.size(), usuarios);
System.out.println("Grid Data: " + data.getJsonString());
return data.getJsonString();
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>MyWeb</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.application.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.writeStateAtFormEnd</param-name>
<param-value>false</param-value>
</context-param>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>bch.com.br.service.rest.RESTEasySingleton</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
REST 单例
public class RESTEasySingleton extends Application
private Set<Object> singletons = new HashSet();
private Set<Class<?>> empty = new HashSet();
public RESTEasySingleton()
this.singletons.add(new UserRESTService());
public Set<Class<?>> getClasses()
return this.empty;
public Set<Object> getSingletons()
return this.singletons;
道
@Stateless
public class UserDAO extends BaseDAO<USUARIO>
@PersistenceContext(unitName="MyJPA")
private EntityManager em;
public UserDAO(Class<USUARIO> entityClass)
super(entityClass);
public UserDAO()
super(USUARIO.class);
@SuppressWarnings("unchecked")
public List<USUARIO> findAll()
Query q = getEntityManager().createQuery("SELECT e FROM " + USUARIO.class.getName() + " e");
List<USUARIO> list = (List<USUARIO>) q.getResultList();
return list;
@Override
protected EntityManager getEntityManager()
return em;
虽然,注入在另一个托管 bean 中工作正常...
@ManagedBean
@RequestScoped
@Named
public class UserBean
public UserBean()
// TODO Auto-generated constructor stub
private List<USUARIO> users = new ArrayList<USUARIO>();
private String name;
@Transient
@EJB
UserDAO userDao;
...
有什么想法吗?
【问题讨论】:
【参考方案1】:将@RequestScoped
添加到您的休息端点。我还将删除 web.xml 中对 resteasy bootstrap 的引用,因为您正在部署到不需要它的 EE6 容器(应用程序扩展就足够了)。
【讨论】:
【参考方案2】:我只是添加一个答案,因为我在同样的情况下苦苦挣扎,并且很长时间无法掌握它的诀窍。在上面的代码 sn-ps 中,虽然 John Ament 的上述建议是正确的 - 它没有解释为什么注入不起作用 - web.xml 和显式“RESTEasySingleton extends Application”初始化(应该是互斥的)在 CDI 上下文之外创建一个新的 RESTEasySingleton 实例 - 其他 ManagedBean 根本不知道 RESTEasySingleton,反之亦然。
正如 *** 上类似问题的其他答案所建议的那样,RESTEasySingleton 应该留空,让 CDI 容器发现它并在自己的上下文中初始化它。 (RequestScoped 是不必要的 - 实际上我在某处看到所有标有 @Path 注释的 RESTEasy 内容默认为 @RequestScoped)
但就我而言,这不是唯一的问题。 RESTEasySingleton 有一个注释 @ApplicationPath 应该告诉什么是 RESTEasy 端点的根上下文路径。不知何故,从那里的一些代码 sn-ps 中,我这样写:@ApplicationPath("/*") - 这一定是犯罪错误。将其更正为 @ApplicationPath("/") 就足以让我受到打击,但至少有点内容。
【讨论】:
以上是关于JAX-RS + JBoss 7.1.1 + RESTEasy:使用 CDI 的 NullPointException的主要内容,如果未能解决你的问题,请参考以下文章
JBoss RESTEasy 无法扫描 WEB-INF 以获取 JAX-RS 注释
对 Apache CXF 2.4 (JAX-RS 1.1) 的 CORS 支持
RESTEasy中的通用异常处理ExceptionMapper
如何在 jboss 7.1.1 中使用 liferay 6.1.2 中的 jboss 部署 structure.xml?