Я новичок в создании приложений API для отдыха. Здесь я пытался сделать простой метод, возвращающий ответ xml объекта модели Message
Вот моя сеть. xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.rest.messenger.service</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>
У меня есть класс обслуживания который возвращает жестко запрограммированный список объектов Message
.
package com.rest.messenger.service;
import java.util.ArrayList;
import java.util.List;
import com.rest.messenger.model.Message;
public class MessageService {
public List<Message> getAllMessages(){
Message m1 = new Message(1L, "message1", "mt");
Message m2 = new Message( 2L, "message 2", "pt");
List<Message> messages = new ArrayList<Message>();
messages.add(m1);
messages.add(m2);
return messages;
}
}
Объект Message
определяется следующим образом (здесь я использовал аннотацию @XmlRootElement
, чтобы позволить jaxb преобразовать это в xml, как Я хотел, чтобы ресурс xml возвращал ответ):
package com.rest.messenger.model;
import java.util.Date;
import jakarta.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Message {
private long id;
private String message;
private String author;
private Date created;
public Message() {
}
public Message(long id, String message, String author) {
super();
this.id = id;
this.message = message;
this.author = author;
this.created = new Date();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
}
Я сопоставил входящий GET
запрос с ресурсом следующим образом:
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/messages")
public class MessageResource {
public MessageService messageService = new MessageService();
@GET
@Produces(MediaType.APPLICATION_XML)
public List<Message> getMessages() {
return messageService.getAllMessages();
}
}
Теперь, когда я запускаю это и попытаться получить доступ к ресурсу по URL-адресу http://localhost:8080/messenger.service/webapi/messages
Я получаю следующую внутреннюю ошибку сервера:
May 06, 2020 1:28:14 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Jersey Web Application] in context with path [/messenger.service] threw exception [java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at jakarta.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:114)
at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:254)
at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:240)
at jakarta.xml.bind.ContextFinder.find(ContextFinder.java:375)
at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
at org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getStoredJaxbContext(AbstractJaxbProvider.java:288)
at org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getJAXBContext(AbstractJaxbProvider.java:273)
at org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getMarshaller(AbstractJaxbProvider.java:240)
at org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getMarshaller(AbstractJaxbProvider.java:207)
at org.glassfish.jersey.jaxb.internal.AbstractCollectionJaxbProvider.writeTo(AbstractCollectionJaxbProvider.java:243)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:242)
В учебнике, которому я следовал, использовался javax, и я считаю, что теперь он перенесен на Джакарта. Не уверен, имеет ли это отношение к @XmlRootElement. Я также добавил зависимости в pom.xml
, как это было предложено: jersey return 500 при попытке вернуть XML
Я использовал модификаторы для полей объекта модели должен быть частным, как было предложено. (используемый по умолчанию тип доступа XML jaxb может работать с частными полями)
Кто-нибудь может предложить это?