问题描述
我正在使用JEE7使用JAX-RS构建示例客户端服务器.我正在使用Wildfly 10.1
I'm building a sample client-server with JAX-RS using JEE7. I'm using Wildfly 10.1
我在此视频中关注了该家伙.这是在应用程序服务器上运行的战争代码:
I followed the guy in this video. Here is the code of the war that runs on the application server:
boundary
程序包包含服务
package pl.devcrowd.virtual.business.chickens.boundary;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Inject;
import pl.devcrowd.virtual.business.chickens.controls.ChickenStore;
import pl.devcrowd.virtual.business.chickens.entity.Chicken;
@Stateless
public class ChickenService {
@Inject
ChickenStore cs;
public List<Chicken> getAllChickens() {
return this.cs.all();
}
public void save(Chicken chicken) {
this.cs.save(chicken);
}
}
和资源
package pl.devcrowd.virtual.business.chickens.boundary;
import java.util.List;
import javax.inject.Inject;
import javax.json.JsonObject;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import pl.devcrowd.virtual.business.chickens.entity.Chicken;
@Path("chickens")
public class ChickensResource {
@Inject
ChickenService cs;
@GET
public List<Chicken> chickens() {
return cs.getAllChickens();
}
@POST
public void save(JsonObject chicken) {
String name = chicken.getString("name");
int age = chicken.getInt("age");
cs.save(new Chicken(name, age));
}
}
control
程序包中包含该商店,在该示例中,该商店大部分没有用处
control
package contains the store which is mostly useless in this example
package pl.devcrowd.virtual.business.chickens.controls;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import pl.devcrowd.virtual.business.chickens.entity.Chicken;
public class ChickenStore {
@PersistenceContext
EntityManager em;
public void save(Chicken chicken) {
em.merge(chicken);
}
public List<Chicken> all() {
return this.em
.createNamedQuery("all", Chicken.class)
.getResultList();
}
}
entity
软件包包含以下实体:
entity
package contains the entity:
package pl.devcrowd.virtual.business.chickens.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
@Entity
@NamedQuery(name="all", query = "SELECT c FROM Chicken C")
public class Chicken {
@Id
@GeneratedValue
private long id;
private String name;
private int age;
public Chicken() {}
public Chicken(String name, int age) {
this.name = name;
this.age = age;
}
}
父包包含我实现的Jax-RS应用程序类,我希望正确:
The parent package contains the Jax-RS application class which I implemented, I hope correctly:
package pl.devcrowd.virtual.business;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import pl.devcrowd.virtual.business.chickens.boundary.ChickensResource;
/**
* Configures a JAX-RS endpoint. Delete this class, if you are not exposing
* JAX-RS resources in your application.
*
* @author airhacks.com
*/
@ApplicationPath("resources")
public class JAXRSConfiguration extends Application {
public Set<Class<?>> getClasses() {
return new HashSet<Class<?>>(Arrays.asList(ChickensResource.class));
}
}
现在我正在尝试执行这样的GET请求
Now i'm trying to do a GET request like this
RestClient get = RestClient.create().method("GET")
.host("http://localhost:8080/DevCrowd")
.path("resources/chickens");
GluonObservableList<Chicken> sample = DataProvider.retrieveList(
get.createListDataReader(Chicken.class));
System.out.println(sample);
鸡肉在哪里
public class Chicken {
private String name;
private int age;
public Chicken(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
我得到了错误:
05:59:17,019 ERROR [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-3) RESTEASY002005: Failed executing GET /chickens: org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure: Could not find MessageBodyWriter for response object of type: java.util.ArrayList of media type: text/html
at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:66)
at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:473)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:422)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:209)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:221)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
我在做什么错了?
推荐答案
据我所见,客户端要求使用mediatype text/html.但是对象映射器不知道如何为arraylist编写html.您希望xml或json使用哪种格式?
As far as I see the client calls for mediatype text/html. But the objectmapper does not know how to write html for an arraylist.What kind of format do you expect xml or json?
@Path("chickens")
public class ChickensResource {
@Inject
ChickenService cs;
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Chicken> chickens() {
return cs.getAllChickens();
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public void save(JsonObject chicken) {
String name = chicken.getString("name");
int age = chicken.getInt("age");
cs.save(new Chicken(name, age));
}
}
另一种解决方案是在请求中设置正确的请求内容类型:GET标头:
An other solution would be to set the right requested Content type in the Request:GET Header:
Accept: application/json
POST标头:
Accept: application/json
Content-Type: application/json
Accept标头说明了响应应采用的格式.Content-Type标头说明了请求有效负载的格式.
The Accept header says in which format the response should be.The Content-Type header says which format the request payload has.
内容类型:
HTML --> text/html
JSON --> application/json
XML --> application/xml
我认为《邮政》也有同样的问题.现在,我们告诉这些方法,它们使用json作为输入数据,并返回json作为输出数据(产生).
edit: I think the Post has the same issue. We now told the methods that they consume json as input data and return json as output data (produces).
但是这些数据确实在请求中设置了吗?可以请您发布您如何构建帖子.
But are those data really set in the request. can you please post how you construct the post.
要匹配这些方法,请求中必须有这两个标头:Accept: application/json
指出客户期望的格式.这应该与设置输出格式的服务中的@Produces
相匹配.Content-Type: application/json
这是我认为缺少的内容,它说POST负载是哪种格式,并且应该与服务器输入@Consumes
To match those methods there need to be those two headers in the request:Accept: application/json
says which format the client expects.This should match the @Produces
in the service which sets the output format.Content-Type: application/json
this is the one I think is missing says in which format the POST payload is and this should match the server input @Consumes
这篇关于GET请求因JAX-RS而失败:找不到类型为java.util.Array的响应对象的MessageBodyWriter,媒体类型为text/html的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!