GET请求因JAX-RS而失败:找不到类型为java.util.Array的响应对象的MessageBodyWriter,媒体类型为text/html [英] GET request fails with JAX-RS: Could not find MessageBodyWriter for response object of type: java.util.ArrayList of media type: text/html

查看:100
本文介绍了GET请求因JAX-RS而失败:找不到类型为java.util.Array的响应对象的MessageBodyWriter,媒体类型为text/html的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆