繁体   English   中英

找不到响应 object 类型的 MessageBodyWriter:java.util.ArrayList 媒体类型:text/html - 在 Resteasy 中

[英]Could not find MessageBodyWriter for response object of type: java.util.ArrayList of media type: text/html - in Resteasy

我正在开发RESTEasy示例。 在此示例中,我使用所有最新的依赖项并部署 om tomcat 8.x 版本。 我可以成功部署应用程序,但是当我启动 url: http://localhost:8080/RESTfulExample/rest/restwebservice/list时,我看到出现以下错误。 请指导这里出了什么问题。

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:466)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:415)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:202)
    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:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

目前我开发的代码供参考:pom.xml

<repositories>
        <repository>
            <id>JBoss repository</id>
            <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
        </repository>
    </repositories>

    <properties>
        <java.version>1.8</java.version>
        <resteasy-jaxrs-version>3.0.16.Final</resteasy-jaxrs-version>
        <junit.version>4.12</junit.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>${resteasy-jaxrs-version}</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-servlet-initializer</artifactId>
            <version>${resteasy-jaxrs-version}</version>
        </dependency>

        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.11</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- Project Build -->
    <build>
        <finalName>RESTfulExample</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

学生.java

@XmlRootElement
public class Student {

    private int student_id;
    private String student_name;
    private String student_rollnumber;
    // setters and getters
}

RESTEasyService.java

@ApplicationPath("/rest")
public class RESTEasyService extends Application{

}

RESTWebServiceJavaExample.java

@Path("/restwebservice")
public class RESTWebServiceJavaExample {
    private TreeMap<Integer, Student> webserviceMap= new TreeMap<>();

    public RESTWebServiceJavaExample(){

        Student student = new Student();
        student.setStudent_name("Ricky");
        student.setStudent_rollnumber("AOHP451");

        addStudent(student);

        student = new Student();
        student.setStudent_name("Mayer");
        student.setStudent_rollnumber("DKLP987");
        addStudent(student);

    }

    @GET
    @Path("list")
    public List<Student> getStudents() {
        List<Student> students = new ArrayList<Student>();
        students.addAll(webserviceMap.values());
        return students;
    }

    @POST
    @Path("add")
    @Produces("text/plain")
    @Consumes("application/xml")
    public void addStudent(Student student_param) {
        int id = webserviceMap.size();
        student_param.setStudent_id(id);
        webserviceMap.put(id, student_param);
    }
}

web.xml:

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Restful Web Application</display-name>

</web-app>

(对于那些发现问题的人,使用 quarkus)

使用此设置例程:

mvn io.quarkus:quarkus-maven-plugin:0.16.1:create     -DprojectGroupId=com.sample     -DprojectArtifactId=hello-quarkus     -DclassName="com.sample.DemoEndpoint"     -Dpath="/persons"

为了解决这里描述的问题,我不得不添加这个依赖项。

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>

这是我添加上述依赖项后的完整 pom.xml。 同样,下面 99% 的 pom.xml 来自上面的 mvn 命令。

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sample</groupId>
  <artifactId>hello-quarkus</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <surefire-plugin.version>2.22.0</surefire-plugin.version>
    <quarkus.version>0.16.1</quarkus.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-bom</artifactId>
        <version>${quarkus.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>


    <!-- ADDED MAGIC HERE -->
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jsonb</artifactId>
    </dependency>




    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemProperties>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          </systemProperties>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>native-image</goal>
                </goals>
                <configuration>
                  <enableHttpUrlHandler>true</enableHttpUrlHandler>
                </configuration>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemProperties>
                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                  </systemProperties>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>

现在我能够解决这个问题。 我需要在pom.xml添加以下依赖项:

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxb-provider</artifactId>
    <version>3.0.16.Final</version>
</dependency>

并且 1) 我应该在方法签名上使用@Produces(MediaType.APPLICATION_XML)来获得以下响应。

<collection>
    <student>
        <student_id>0</student_id>
        <student_name>Ricky</student_name>
        <student_rollnumber>AOHP451</student_rollnumber>
    </student>
    <student>
        <student_id>1</student_id>
        <student_name>Mayer</student_name>
        <student_rollnumber>DKLP987</student_rollnumber>
    </student>
</collection>
  1. 如果您想使用@Produces(MediaType.TEXT_PLAIN)那么代码将为您提供以下看起来没有用的输出。

    [com.mkyong.rest.Student@4d5fd75e, com.mkyong.rest.Student@7715574d]

所以使用 1) 解决方案。

尝试添加特定版本的序列化程序

    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jackson-provider</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)

添加这些注释解决了我的问题。

对我来说,这是关于尝试将数组序列化为 XML。 如果你愿意,它需要一个像这样的电影包装类:

@XmlRootElement(name = "movies")
@XmlAccessorType(XmlAccessType.FIELD)
public class Movies
{
    @XmlElement(name = "movie")
    private List<Movie> movies;

    public List<Movie> getMovies() {
        return movies;
    }

    public void setMovies(List<Movie> movies) {
        this.movies = movies;
    }
}

这样它就可以在根对象下被序列化。

更清楚一点,对于初学者。 添加

@XmlRootElement(name = "yourClassLowerCased")在你班级的开头,比如

package org.dlss.entities;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;


@Entity //The class will be a javax.persistence Entity (could be stored in a DB)
@Table(name = "person", schema = "public", catalog = "<databaseName>") //Table name
@XmlRootElement(name = "person")
public class PersonEntity {


    @Id //Following field will be the id of the table
    @GeneratedValue(strategy = GenerationType.IDENTITY) //Will be autoincremented when generated for type SERIAL into postgresql
    private Integer id;

其他人提供的解决方案完全正常。

我只想补充一点,它们为什么有效?

RESTEasy 是一个 JBoss / Red Hat 项目,它提供了各种框架来帮助您构建 RESTful Web 服务和 RESTful Java 应用程序。 它没有绑定来从 JSON 转换 Java 类,反之亦然。

这里有像 JSON-B 和 Jackson 这样的库,它们有助于在 Java 类和 JSON 之间进行转换。

来自 Json-B 文档:

JSON-B 是一个标准绑定层,用于在 Java 对象和 JSON 消息之间进行转换。 它定义了一种默认映射算法,用于将现有 Java 类转换为 JSON,同时使开发人员能够通过使用 Java 注释自定义映射过程。

对于任何未来的读者,除了公认的解决方案外,请确保使用 javax jaxb 而不是 jakarta 的解决方案,与一个而不是另一个一起工作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM