我在访问MySql数据库的服务器上实现REST API。使用JDBC / OpenJPA访问数据库。有几个对象模型使用OpenJPA注释(@ Id,@ Column等)和对象XML绑定注释(@XmlRootElement,@ XMLElement等)进行注释。我使用Jersey作为REST API。问题是,当尝试访问类似" myapp /.../ users / admin"我收到一条错误消息,指出{" myapp /.../ users / admin"读取数据库。但是当我重写" myapp /.../ users / admin"的功能时要创建一个新的Java class org.apache.openjpa.enhance.com$stod$models$User$pcsubclass, and Java type class com.stod.models.User, and MIME media type application/json was not found
对象(不先持久保存到数据库),一切都按预期工作。为什么?
以下是相关的代码段。
com.stod.models.User
:
User.class
@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.NONE)
@Entity(name = "USER")
public class User implements Base, Serializable {
private static final long serialVersionUID = 8015178615266549325L;
@Id
@Column(name = "USERNAME", nullable = false, length = 128, unique = true, updatable = false)
private String username;
@Column(name = "PASSWORDHASH", nullable = false, length = 128, unique = false, updatable = true)
private String passwordHash;
@OneToMany(mappedBy = "owner", cascade = { CascadeType.MERGE, CascadeType.PERSIST })
private Collection<Circle> circlesOwned;
@XmlElement
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@XmlTransient
public String getPasswordHash() {
return passwordHash;
}
public void setPasswordHash(String password) {
this.passwordHash = DigestUtils.sha256Hex(password);
}
@XmlElement
public Collection<Circle> getCirclesOwned() {
return circlesOwned;
}
public void setCirclesOwned(Collection<Circle> circlesOwned) {
this.circlesOwned = circlesOwned;
}
//...
}
:
Circle.class
@XmlRootElement(name = "circle")
@XmlAccessorType(XmlAccessType.NONE)
@Entity(name = "CIRCLE")
public class Circle implements Base, Serializable {
private static final long serialVersionUID = 4653602066511306690L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "CIRCLEID")
@XmlElement
private Integer id;
@Column(name = "NAME", nullable = false, length = 128, unique = false, updatable = true)
private String name;
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
@XmlInverseReference(mappedBy="circlesOwned")
private User owner;
}
:
Service.class
@Path("/service")
public class Service {
static HighLogicHelper lHelper = null;
static {
if (lHelper == null) {
try {
lHelper = new HighLogicHelper();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@GET
@Path("/hello")
@Produces("text/plain")
public String hello() {
return "Hello World";
}
@GET
@Path("/echo/{message}")
@Produces("text/plain")
public String echo(@PathParam("message") String message) {
return message + " is your message";
}
@GET
@Path("/users/{username}")
@Produces("application/json")
public User getUser(@PathParam("username") String username) {
User user = new User();
user.setUsername(username);
user = (User) lHelper.findUser(user); //lHelper finds the user by username and returns the persisted object off the database
User user2 = new User();
user2.setUsername(user.getUsername());
user2.setCirclesOwned(user.getCirclesOwned());
//NOTE! returning user2 works just fine (because user2 wasn't previously persisted?)
return user;
}
}
:
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"
id="WebApp_ID" version="3.0">
<display-name>com.vogella.jersey.first</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.stod.server</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
:
pom.xml
相关堆栈跟踪:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stod.server</groupId>
<artifactId>stod-server</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>stod-server</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.stod.models</groupId>
<artifactId>stod-models</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxrs</artifactId>
<version>2.0.0.GA</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId> <version>1.1.GA</version>
</dependency> -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.12</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>TomcatServer</server>
<path>/stod</path>
<update>true</update>
</configuration>
</plugin>
</plugins>
</build>
</project>
答案 0 :(得分:0)
Exception stacktrace说,没有MessageBodyWriter:
javax.ws.rs.WebApplicationException:com.sun.jersey.api.MessageException:Java类的消息体编写器org.apache.openjpa.enhance.com $ stod $ models $ User $ pcsubclass和Java类class com.stod.models.User,找不到MIME媒体类型application / json
,尤其不适用于org.apache.openjpa.enhance.com $ stod $ models $ User $ pcsubclass:
org.apache.openjpa.enhance.com $ stod $ models $ User $ pcsubclass,Java type class com.stod.models.User,找不到MIME媒体类型application / json
对我来说,看起来你的演员用户的运行时类型不匹配,并且jersey无法找到正确的类来创建新的实例。 (但我不是百分百肯定所以不要怪我;))
如果您从lHelper.findUser(user)
取回用户,请确保用户确实属于用户类型。看起来它是一个openjpa代理some-what,它不是XMLRootElement,因此代码不起作用......
不混合球衣版本,这是不行的:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17.1</version> <-----------------------------
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.12</version> <-------------------------------
<scope>runtime</scope>
</dependency>
然后,有更新的版本,想想你的升级球衣项目。目前新的2.13对我来说在生产中运行良好。
顺便说一下,你混合了XmlAccessorTypes。在我看来,使用像@XmlAccessorType(XmlAccessType.FIELD)
这样的单一类型更好(代码方式),在这种情况下只注释字段声明 - 但是nvm;)
希望这在某种程度上有所帮助/有美好的一天。