我剛開始學習JAX-RS,並試圖用JAX-RS書籍修改O'Reilly RESTful Java中的一些示例。我遇到了一個問題,當我試圖將XML文件發佈到我的JAX-RS服務之一時,出現空指針異常。我發佈的特定資源使用JPA將信息保存到德比數據庫。在閱讀其他幾個問題/迴應和教程後,我確信我的代碼是正確的,但也許我錯過了一些配置。看起來實體經理並沒有因爲某種原因被注入,即使我有適當的註釋。任何關於我的問題的意見將不勝感激。請參閱我的項目的以下摘錄,我認爲將是有益的:EntityManager爲空。在WAS-Liberty上使用JAX-RS和JPA
的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="jpa-example" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>java:comp/env/jdbc/DerbyConnection</jta-data-source>
<class>com.example.persistence.UserEntity</class>
<class>com.example.persistence.SearchEntity</class>
<properties>
<property name="openjpa.TransactionMode" value="managed"/>
<property name="openjpa.ConnectionFactoryMode" value="managed"/>
<property name="openjpa.LockTimeout" value="30000"/>
<property name="openjpa.jdbc.TransactionIsolation" value="read-committed"/>
<property name="openjpa.Log" value="TRACE"/>
<property name="openjpa.jdbc.UpdateManager" value="operation-order"/>
</properties>
</persistence-unit>
</persistence>
server.xml中
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>jsp-2.2</feature>
<feature>jdbc-4.0</feature>
<feature>jpa-2.0</feature>
<feature>localConnector-1.0</feature>
<feature>jaxrs-1.1</feature>
<feature>ejbLite-3.1</feature>
</featureManager>
<httpEndpoint host="localhost" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
<jdbcDriver id="derbyJDBCDriver">
<library name="DerbyLib">
<fileset dir="/Users/jackson/Documents/db-derby-10.10.1.1-bin/lib" includes="derby.jar"/>
</library>
</jdbcDriver>
<dataSource id="DerbyConnection" jdbcDriverRef="derbyJDBCDriver" jndiName="jdbc/DerbyConnection">
<properties.derby.embedded createDatabase="create" databaseName="example"/>
</dataSource>
<applicationMonitor updateTrigger="mbean"/>
<webApplication id="REST" location="REST.war" name="REST"/>
</server>
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>REST</display-name>
<servlet>
<description>
JAX-RS Tools Generated - Do not modify</description>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.services.RESTConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>
/rest/*</url-pattern>
</servlet-mapping>
<ejb-local-ref>
<ejb-ref-name>ejb/UserResource</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.example.services.UserResource</local>
<ejb-link>
com.example.services.UserResourceBean
</ejb-link>
</ejb-local-ref>
</web-app>
RESTConfig .java
package com.example.services;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class RESTConfig extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(HelloWorld.class);
classes.add(UserResourceBean.class);
return classes;
}
}
UserEntity.java
package com.example.persistence;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity(name = "User")
public class UserEntity {
private long id;
private String login;
private String password;
private String firstName;
private String lastName;
private String email;
private String role;
private String status;
@Id
@GeneratedValue
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Override
public String toString()
{
return "UserEntity {" +
"id=" + id +
", email='" + email + '\'' +
", password='" + password + '\'' +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", role='" + role + '\'' +
", status='" + status + '\'' +
'}';
}
}
UserResource.java
package com.example.services;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import com.example.domain.User;
import com.example.domain.Users;
@Path("/users")
public interface UserResource
{
@POST
@Consumes("application/xml")
Response createUser(User user, @Context UriInfo uriInfo);
@GET
@Produces("application/xml")
//@Formatted
Users getUsers(@QueryParam("start") int start,
@QueryParam("size") @DefaultValue("10") int size,
@QueryParam("firstName") String firstName,
@QueryParam("lastName") String lastName,
@Context UriInfo uriInfo);
@GET
@Path("{id}")
@Produces("application/xml")
User getUser(@PathParam("id") long id);
}
UserResourceBean.java
package com.example.services;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import com.example.domain.Link;
import com.example.domain.User;
import com.example.domain.Users;
import com.example.persistence.UserEntity;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
@Stateless
public class UserResourceBean implements UserResource
{
@PersistenceContext(unitName="jpa-example")
private EntityManager em;
public Response createUser(User user, UriInfo uriInfo)
{
UserEntity entity = new UserEntity();
domain2entity(entity, user);
System.out.println(entity);
em.persist(entity);
em.flush();
System.out.println("Created user " + entity.getId());
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Long.toString(entity.getId()));
return Response.created(builder.build()).build();
}
public User getUser(long id)
{
UserEntity user = em.getReference(UserEntity.class, id);
return entity2domain(user);
}
public static void domain2entity(UserEntity entity, User user)
{
entity.setId(user.getId());
entity.setLogin(user.getLogin());
entity.setPassword(user.getPassword());
entity.setFirstName(user.getFirstName());
entity.setLastName(user.getLastName());
entity.setEmail(user.getEmail());
entity.setRole(user.getRole());
entity.setStatus(user.getStatus());
}
public static User entity2domain(UserEntity entity)
{
User u = new User();
u.setId(entity.getId());
u.setLogin(entity.getLogin());
u.setPassword(entity.getPassword());
u.setFirstName(entity.getFirstName());
u.setLastName(entity.getLastName());
u.setEmail(entity.getEmail());
u.setRole(entity.getRole());
u.setStatus(entity.getStatus());
return u;
}
public Users getUsers(int start,
int size,
String firstName,
String lastName,
UriInfo uriInfo)
{
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.queryParam("start", "{start}");
builder.queryParam("size", "{size}");
ArrayList<User> list = new ArrayList<User>();
ArrayList<Link> links = new ArrayList<Link>();
Query query = null;
if (firstName != null && lastName != null)
{
query = em.createQuery("select u from Users u where u.firstName=:first and u.lastName=:last");
query.setParameter("first", firstName);
query.setParameter("last", lastName);
}
else if (lastName != null)
{
query = em.createQuery("select u from Users u where u.lastName=:last");
query.setParameter("last", lastName);
}
else
{
query = em.createQuery("select u from Users u");
}
List userEntities = query.setFirstResult(start)
.setMaxResults(size)
.getResultList();
for (Object obj : userEntities)
{
UserEntity entity = (UserEntity) obj;
list.add(entity2domain(entity));
}
// next link
// If the size returned is equal then assume there is a next
if (userEntities.size() == size)
{
int next = start + size;
URI nextUri = builder.clone().build(next, size);
Link nextLink = new Link("next", nextUri.toString(), "application/xml");
links.add(nextLink);
}
// previous link
if (start > 0)
{
int previous = start - size;
if (previous < 0) previous = 0;
URI previousUri = builder.clone().build(previous, size);
Link previousLink = new Link("previous", previousUri.toString(), "application/xml");
links.add(previousLink);
}
Users users = new Users();
users.setUsers(list);
users.setLinks(links);
return users;
}
}
這是其中NPE發生這最後一個文件。特別是在函數createUser中,下面的代碼將引發一個NPE:em.persist(entity);
您的server.xml中的內容也將是有益的,看看。 – Rick
我已經包含了server.xml文件。 – cjackson