#web-services #rest #jersey #java-ee-6
#веб-службы #rest #джерси #java-ee-6
Вопрос:
Мне нужно написать REST-клиент с JAX-RS-реализацией Jersey для доступа к моему веб-сервису RESTful, который работает с безопасным EJB. У меня есть @OneToMany
отношение от класса A
к B
. Я использую сервер приложений Glassfish 3.1.1. Но когда я запускаю мой клиент rest, он выдает следующие ошибки:
Ошибка на стороне клиента:
com.sun.jersey.api.client.UniformInterfaceException: GET http://localhost:8080/myapp/rest/a/all returned a response status of 500 Internal Server Error
Ошибка на стороне сервера:
SEVERE: The response of the WebApplicationException cannot be utilized as the response is already committed. Re-throwing to the HTTP container
javax.ws.rs.WebApplicationException: javax.xml.bind.PropertyException: Unsupported Property
at com.sun.jersey.core.provider.jaxb.AbstractListElementProvider.writeTo(AbstractListElementProvider.java:183)
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:619)
MyRestClient
это мой клиент rest, который я использую в автономном клиентском приложении для вызова моего веб-сервиса RESTful, который я реализовал как компонент сеанса EJB.
MyRestClient.java
public class MyRestClient {
public static void main(String[] args) {
Client client = Client.create();
client.addFilter(new HTTPBasicAuthFilter("username", "password"));
WebResource resource = client.resource("http://localhost:8080/myapp/rest/a/all");
List<A> aList = resource.get(new GenericType<List<A>>() {});
for(A nextA: aList){
System.out.println(nextA.getTitle());
}
}
}
AResource
это мой веб-сервис REST, который был реализован как веб-сервис EJB.
AResource.java
@Stateless
@Path("/a")
public class AResource {
@EJB
private AService aService;
@GET
@Produces(MediaType.APPLICATION_XML)
@Path("/all")
public List<A> getAllA() {
return aService.getAllA();
}
}
A
и B
являются объектами домена, используемыми для хранения данных, возвращаемых с сервера на стороне клиента.
A.java
@XmlRootElement
public class A implements Serializable{
private List<B> bList = new ArrayList<B>();
public List<B> getBList() {
return bList;
}
//remaining code
}
B.java
@XmlRootElement
public class B implements Serializable {
private String text;
private A a;
@XmlTransient
public A getA() {
return a;
}
public void afterUnmarshal(Unmarshaller u, Object parent) {
this.a = (A) parent;
}
//remaining code
}
Может кто-нибудь помочь мне понять, почему я получаю эти ошибки?
Спасибо.
Ответ №1:
Первое исключение, которое вы получили на стороне клиента, вызвано тем фактом, что на сервере произошла ошибка, и сервер вернул неожиданный ответ (поскольку вместо ответа ресурса он вернул ответ с ошибкой с телом html).
Вторая проблема вызвана сильной зависимостью Майки 1.8 от JAXB RI, которая была введена по ошибке. Итак, когда вы пытаетесь использовать MOXy, это приведет к сбою. Это исправлено в Jersey 1.9 и 1.9.1. Итак, если вы хотите продолжать использовать MOXy, просто обновите Jersey в GF из центра обновлений до последней версии, и она должна начать работать.
Ответ №2:
Я использовал org.eclipse.persistence.moxy-2.3.jar
для тестирования его через JAXB RI, используемый Glassfish 3.1.1. Я установил javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
в jaxb.properties
файле classpath с объектами моего домена для тестирования MOXy, который после удаления решил проблему.
Итак, удаление jaxb.properties
файла из classpath решило проблему.
Проблема создавалась строкой:
List<A> aList = resource.get(new GenericType<List<A>>() {});