Получение "MessageBodyWriter не найден для типа media = application/json", пытающегося отправить объект JSON через веб-службу JAX-RS
Я пытаюсь отправить объект JSON через веб-службу JAX-RS.
Мой файл web.xml:
<servlet>
<description>JAX-RS Tools Generated - Do not modify</description>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>it.notifire</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>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>/jaxrs/*</url-pattern>
</servlet-mapping>
Класс, который моделирует объект, который я хочу отправить:
public class GPSCoordinate {
private float latitudine;
private float longitudine;
public float getLatitudine() {
return latitudine;
}
public void setLatitudine(float latitudine) {
this.latitudine = latitudine;
}
public float getLongitudine() {
return longitudine;
}
public void setLongitudine(float longitudine) {
this.longitudine = longitudine;
}
}
Ресурс корневого класса:
@Path("position")
public class Position {
@Context
private UriInfo context;
@GET
@Produces(MediaType.APPLICATION_JSON)
public GPSCoordinate getHTML() {
GPSCoordinate coord = new GPSCoordinate();
coord.setLatitudine(90.45f);
coord.setLongitudine(34.56f);
return coord;
}
}
Теперь, когда я пытаюсь получить доступ к службе, я указываю свой браузер на следующую ссылку
http://localhost:8080/Notifire/jaxrs/position
и я получаю следующую ошибку:
message org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter не найден для типа носителя = application/json
В моей папке WEB-INF/lib у меня есть последняя версия jersey JAX-RS (jaxrs-ri-2.5.jar) и архив jersey-json.jar.
Любая помощь будет высоко оценена.
Ответы
Ответ 1
Попробуйте добавить Genson в свой путь к классам, он автоматически включит поддержку JSON.
Genson - это библиотека привязки данных и потоковой передачи для json и java/ scala. Он реализует точки расширения MessageBodyReader/Writer JAX-RS, позволяя трикотажно автоматически определять Genson и использовать его для разбора/записи Json.
Вы можете найти дополнительную информацию о интеграции Gensons с JaxRS (трикотаж и cie).
Ответ 2
Джерси поддерживает функции "autodiscoverable", а поддержка JSON - одна из них. Чтобы включить его, вам нужно добавить совместимую библиотеку к вашему пути, в соответствии с документами
Однако, хотя рекомендуемая библиотека jersey-media-json-processing
не была распознана в моем случае по какой-либо причине, jersey-media-moxy
имеет:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.15</version>
</dependency>
2.15 была последней версией на момент написания. Перейдите на страницу maven central artifact, чтобы найти текущую версию.
Ответ 3
Вот как я решил проблему.
Используется Джексон. Добавлены эти банки
![enter image description here]()
Добавил этот класс в мой проект. Ключевые строки кода отмечены ВАЖНО.
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; <-- IMPORTANT
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
//@javax.ws.rs.ApplicationPath("webresources")
public class MyApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
//addRestResourceClasses(resources);
//resources.add(MultiPartFeature.class);
//resources.add(JettisonFeature.class);
return resources;
}
@Override
public Set<Object> getSingletons() {
final Set<Object> instances = new HashSet<Object>();
instances.add(new JacksonJsonProvider()); <--------- IMPORTANT
return instances;
}
/**
* Do not modify addRestResourceClasses() method.
* It is automatically populated with
* all resources defined in the project.
* If required, comment out calling this method in getClasses().
*/
private void addRestResourceClasses(Set<Class<?>> resources) {
//resources.add(org.glassfish.jersey.media.multipart.MultiPartProperties.Feature.MultiPartContextResolver.class);
//resources.add(org.glassfish.jersey.media.multipart.MultiPartProperties.Feature.MultiPartContextResolver.class);
}
}
Ответ 4
Моя первопричина несколько отличалась. Я потратил некоторое время на отладку исходного кода Джерси, и оказалось, что он не смог построить JAXBContext
из-за отсутствия стандартного конструктора в моем классе JAXB. Это происходит во время поиска подходящего MessageBodyWriter, но исключение не обрабатывается.
Вот соответствующий фрагмент кода (MOXyJsonProvider: 324):
try {
Set<Class<?>> domainClasses = getDomainClasses(genericType);
return getJAXBContext(domainClasses, annotations, mediaType, null);
} catch(JAXBException e) {
return null;
}
Итак, если у вас есть зависимость Moxy JSON от POM, дважды проверьте, что ваши классы JAXB действительны.
Версии, которые я использую: Jersey 2.19, Moxy 2.6.0.
Ответ 5
Зарегистрируйте класс JacksonJsonProvier с конфигурацией клиента, а затем создайте объект Client, это сработало для меня. Ниже приведен код.
ClientConfig config = new ClientConfig();
config.register(JacksonJsonProvider.class);
Client client = ClientBuilder.newClient(config);
Ответ 6
Перейдите к https://jersey.java.net/documentation/2.5.1/user-guide.html#json
Вам необходимо заполнить свой класс... JAXB нуждается в этом, например:
@XmlRootElement
public class MyJaxbBean {
@XmlElement(name="king")
public String name;
@XmlTransient
public int age;
// several lines removed
}
Ответ 7
Это сработало для меня, добавив все необходимые Jackson Jars.
Добавлены эти банки
- jackson-annotations-2.8.7.jar,
- ДЖЕКСОНА-ядро-2.8.7.jar
- ДЖЕКСОНА-DataBind-2.8.7.jar
- джексон-jaxrs база-2.8.7.jar
- ДЖЕКСОНА-jaxrs-JSON-провайдера 2.8.3.jar
- ДЖЕКСОНА-модуль-JAXB-аннотаций-2.8.7.jar