SEVERE: писатель тела сообщения для Java-класса java.util.ArrayList и MIME-приложение типа мультимедиа /json не найдено
Я тестирую службы RESTful, и когда я выполняю, я получаю исключения, хотя у меня есть следующие jars в моем пути к классу (WEB-INF/lib), я не использую 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>
Список фляг
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)
Как я могу решить эту проблему?
Ответы
Ответ 1
Убедитесь, что у вас нет нескольких версий Джерси в вашем проекте. Из списка, который вы указали, имеются модули из 3 разных версий (1.2, 1.10, 1.8). Для некоторых модулей Джерси проверяет, что версия модуля совпадает с версией ядра. Если это не так, поставщики модуля (такие как MessageBodyReaders, MessageBodyWriters) не регистрируются во время выполнения. Это может быть проблемой в вашей настройке - json vs core (1.8 vs 1.2).
Ответ 2
Проблема может заключаться в том, как вы пытаетесь вернуть свой результат. Я видел, как другие тоже пишут код своего уровня сервиса, но Джерси предоставляет способ сделать это чисто, и он будет поддерживать вывод 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();
}
Я использую следующие библиотеки Джерси:
- джерси-ядро-1.8.jar
- джерси-JSON-1.8.jar
- джерси-сервер 1.8.jar
Ответ 3
Вы не можете определить ответ Xml
как List<Emp>
, так как JAXB
не может идентифицировать @XmlRootElement
по определению класса java.util.List
или java.util.ArrayList
.
В идеале у вас должен быть один родительский/корневой элемент для вашей коллекции дочерних элементов.
Создайте еще один класс как Employees
, чтобы содержать объекты Emp
, как показано ниже, и попробуйте его.
@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
}
Попробуйте этот подход, он будет работать.
Ответ 4
Добавьте это в свой 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>
Ответ 5
Задание @XmlRootElement(name = "yourclass")
класса, который вы хотите передать в качестве вывода. Это решило проблему для меня, когда я получаю это исключение.
Ответ 6
У меня была та же проблема.
Дело в том, что он знает, как преобразовать его в xml с аннотацией @XmlRootElement
, но он не знает, как преобразовать его в JSON.
Итак, чтобы преобразовать все в JSON с той же аннотацией xml (т.е. @XmlRootElement
), мы можем добавить
jersey-media-moxy-<whatever version>.jar
или для пользователей maven
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
Также он должен иметь конструктор без аргументов
Ответ 7
Вы должны объявить в servlet container
jersey параметр как следующий:
'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>