![](/img/trans.png)
[英]Using Jersey to POST to service - “A message body writer … was not found”
[英]My REST API (using Jersey) cannot find a message body writer (for JSON) for a persisted entity (using OpenJPA).
我正在訪問MySql數據庫的服務器上實現REST API。 使用JDBC / OpenJPA訪問該數據庫。 有幾種對象模型都帶有OpenJPA批注(@ Id,@ Column等)和對象XML綁定批注(@ XmlRootElement,@ XmlElement等)。 我正在將Jersey用於REST API。 問題是,當嘗試訪問“ 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
有消息正文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
當“ 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
。 但是,當我重寫“ myapp /.../ users / admin”的函數以創建新的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>
相關堆棧跟蹤:
Oct 20, 2014 11:30:48 AM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive /var/lib/tomcat7/webapps/stod.war
Oct 20, 2014 11:30:50 AM org.apache.catalina.startup.TaglibUriRule body
INFO: TLD skipped. URI: urn:com:sun:jersey:api:view is already defined
Oct 20, 2014 11:30:51 AM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
com.stod.server
Oct 20, 2014 11:30:51 AM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class com.stod.server.Service
Oct 20, 2014 11:30:51 AM com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
Oct 20, 2014 11:30:51 AM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.17.1 02/28/2013 03:28 PM'
Oct 20, 2014 11:30:56 AM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: A message body writer for 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
Oct 20, 2014 11:30:56 AM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: The registered message body writers compatible with the MIME media type are:
application/json ->
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
com.sun.jersey.server.impl.template.ViewableMessageBodyWriter
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
Oct 20, 2014 11:30:56 AM com.sun.jersey.spi.container.ContainerResponse logException
SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for 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
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1479)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.sun.jersey.api.MessageException: A message body writer for 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
... 24 more
Exception stacktrace表示,沒有MessageBodyWriter:
javax.ws.rs.WebApplicationException:com.sun.jersey.api.MessageException:Java類org.apache.openjpa.enhance.com $ stod $ models $ User $ pcsubclass和Java類型類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類型類com.stod.models.User和MIME媒體類型application / json
對我來說,您的轉換用戶的運行時類型似乎不匹配,並且jersey無法找到正確的類來創建新實例。 ( 但是我不是100%肯定,所以不要怪我 ;)
如果您從lHelper.findUser(user)
找回了用戶,請確保該用戶確實屬於用戶類型。 看起來它有點像是一個openjpa代理,它不是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)
類的單一類型會更好(在代碼方面@XmlAccessorType(XmlAccessType.FIELD)
,在這種情況下,僅注釋字段聲明-但使用nvm;)
希望這對您有所幫助/祝您有個愉快的一天。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.