web-dev-qa-db-ja.com

重大:JavaクラスJava.util.ArrayListおよびMIMEメディアタイプapplication / jsonのメッセージ本文ライターが見つかりませんでした

RESTfulサービスをテストしており、実行すると例外が発生しますが、クラスパス(WEB-INF/lib)に次のjarがありますが、Mavenを使用しておらず、JDKバージョンは1.5です。この問題に関するその他の質問は、問題の解決には役立ちませんでした。

コードスニペット

@GET
@Produces("application/json")    
//@Produces({MediaType.APPLICATION_JSON}) tried this, didn't work either
public List<Emp> getEmployees() {        
    List<Emp> empList = myDAO.getAllEmployees();
    log.info("size   " + empList.size());
    return empList;
}

@XmlRootElement
public class Emp {
......

web.xml

<servlet>
    <servlet-name>Jersey Web Application</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>test.employees</param-value>
    </init-param>
    <init-param>
        <param-name>com.Sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>

 <servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

jarのリスト

jersey-server-1.2.jar
jersey-core-1.2.jar
jsr311-api-1.1.jar
asm-3.1.jar
jaxb-api-2.0.jar
jaxb-impl-2.0.jar
jackson-xc-1.2.0.jar
jackson-jaxrs-1.2.0.jar
jackson-mapper-asl-1.2.0.jar
jackson-core-asl-1.2.0.jar
jettison-1.2.jar
jersey-client-1.2.jar
jersey-servlet-1.10.jar
jersey-json-1.8.jar

例外スタック

 SEVERE: A message body writer for Java class Java.util.ArrayList,
 and Java type Java.util.List<test.Emp>, 
 and MIME media type application/json was not found
Nov 21, 2013 11:47:26 AM com.Sun.jersey.spi.container.ContainerResponse traceException
SEVERE: Mapped exception to response: 500 (Internal Server Error)

javax.ws.rs.WebApplicationException
    at javax.ws.rs.WebApplicationException.<init>(WebApplicationException.Java:97)
    at javax.ws.rs.WebApplicationException.<init>(WebApplicationException.Java:55)
    at com.Sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.Java:267)
    at com.Sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.Java:1035)
    at com.Sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.Java:947)
    at com.Sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.Java:939)
    at com.Sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.Java:399)
    at com.Sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.Java:478)
    at com.Sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.Java:663)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:856)
    at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.Java:719)
    at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.Java:376)
    at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.Java:870)
    at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.Java:451)
    at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.Java:218)
    at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.Java:119)
    at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.Java:112)
    at Oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.Java:260)
    at Oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.Java:230)
    at Oracle.oc4j.network.ServerSocketAcceptHandler.access$800(ServerSocketAcceptHandler.Java:33)
    at Oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.Java:831)
    at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.Java:303)
    at Java.lang.Thread.run(Thread.Java:595)

この問題を解決するにはどうすればよいですか?

15
Jåcob

プロジェクトに複数のジャージーバージョンがないことを確認してください。指定したリストから、3つの異なるバージョン(1.2、1.10、1.8)のモジュールがあります。一部のモジュールでは、Jerseyはモジュールのバージョンがコアのバージョンと同じであることを確認します。そうでない場合、モジュールのプロバイダー(MessageBodyReaders、MessageBodyWritersなど)はランタイムに登録されません。これはセットアップの問題になる可能性があります-json vs core(1.8 vs 1.2)。

7
Michal Gajdos

問題は、結果を返そうとする方法にあります。私も他の人がこのようにサービス層コードを書くのを見たことがありますが、Jerseyはそれをきれいに行う方法を提供し、JSON、XML、HTML出力をサポートします@ Produces注釈。これが私がすることです:

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.Response;

@GET
@Produces( MediaType.APPLICATION_JSON )
public Response getEmployees()
{        
    List< Emp >                  matched;
    GenericEntity< List< Emp > > entity;

    matched = myDAO.getAllEmployees();
    entity  = new GenericEntity< List< Emp > >( matched ) { };

    return Response.ok( entity ).build();
}

次のJerseyライブラリを使用しています。

  • jersey-core-1.8.jar
  • jersey-json-1.8.jar
  • jersey-server-1.8.jar
17
Russ Bateman

XmlList<Emp>または@XmlRootElementクラス定義でJava.util.Listを識別できないため、応答JAXBJava.util.ArrayListとして定義できません。

理想的には、子要素のコレクションに対して1つの親/ルート要素が必要です。

以下のようにEmployeesオブジェクトのコレクションを含むEmpとしてもう1つのクラスを作成し、試してください。

@GET
@Produces("application/json")    
public Employees getEmployees() {        
    List<Emp> empList = myDAO.getAllEmployees();
    log.info("size   " + empList.size());
    Employees employees = new Employees();
    employees.setEmployeeList(empList);

    return employees;
}

@XmlRootElement(name = "Employees")
public class Employees {

    List<Emp> employeeList;

    //setters and getters goes here
}

@XmlRootElement()
class Emp {
   //fields here
}

このアプローチを試してください、それは動作します。

8
omega

これをpom.xmlに追加します。私の問題を解決しました。

        <dependency>
        <groupId>com.Sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.18.1</version>
    </dependency>
    <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>0.99</version>
    </dependency>
6
Michiel

出力として渡すクラスで@XmlRootElement(name = "yourclass")を指定します。これにより、この例外が発生したときに問題が解決しました。

3

ジャージのservlet containerで、次のようにパラメータを宣言する必要があります。

'com.Sun.jersey.api.json.POJOMappingFeature' like this: 
 <servlet>
    <servlet-name>myServices</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>services</param-value>
    </init-param>
    <init-param>
        <param-name>com.Sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
1
Maiga

同じ問題がありました。

事は、注釈@XmlRootElementでXMLに変換する方法を知っていますが、JSONに変換する方法を知りません。

したがって、xmlの同じ注釈(つまり@XmlRootElement)ですべてをJSONに変換するには

jersey-media-moxy-<whatever version>.jar

またはMavenユーザーの場合

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
</dependency>

引数なしのコンストラクターも必要

1
padippist

あなたのpojoを@XmlRootElementでマークしていない場合、pojoクラスがJAXBindingを行わない可能性がありますクロスチェック

1
Niraj singh