JAX-RS:用于基本 HTTP 身份验证的 REST 客户端
我需要使用 JAX-RS 的 Jersey 实现编写一个 REST 客户端,以访问与安全 EJB 配合使用的 RESTful Web 服务。我有一个从类 A
到 B
的 @OneToMany
关系。我正在使用 Glassfish 3.1.1 应用程序服务器。但是,当我运行我的休息客户端时,它会给出以下错误:
客户端错误:
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
是我的休息客户端,我在独立客户端应用程序中使用它来调用我的我已将 RESTful Web 服务实现为 EJB 会话 bean。
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 Web 服务,已作为 EJB Web 服务实现。
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
}
有人可以帮助我理解为什么会出现这些错误吗?
谢谢。
I need to write a REST client with Jersey implementation of JAX-RS to access my RESTful webservice that works with a secure EJB. I have a @OneToMany
relationship from class A
to B
. I am using Glassfish 3.1.1 application server. But when I run the my rest client it gives me following errors:
Error on the client side:
com.sun.jersey.api.client.UniformInterfaceException: GET http://localhost:8080/myapp/rest/a/all returned a response status of 500 Internal Server Error
Error on the server side:
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
is my rest client that I am using in a standalone client application to call my RESTful webservice that I have implemented as an EJB session bean.
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
is my REST webservice that has been implemented as an EJB webservice.
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
and B
are the domain objects used to hold the data returned from the server at the client side.
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
}
Could someone help me understand why am I getting these errors?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您在客户端遇到的第一个异常是由于服务器上出现错误并且服务器返回了意外响应(而不是资源响应,而是返回了带有 html 正文的错误响应)而引起的。
第二个问题是由 Jersey 对 JAXB RI 的 1.8 硬依赖引起的,这是错误引入的。因此,当您尝试使用 MOXy 时,它会失败。这已在 Jersey 1.9 和 1.9.1 中修复。因此,如果您想继续使用 MOXy,只需从更新中心将 GF 中的 Jersey 升级到最新版本即可开始工作。
The first exception you were getting on the client side is caused by the fact there was an error on the server and the server returned unexpected response (as instead of the resource response, it returned an error response with html body).
The second problem is caused by a Jersey's 1.8 hard dependency on JAXB RI, which got introduced by mistake. So, when you try using MOXy, it would fail. This is fixed in Jersey 1.9 and 1.9.1. So, if you want to continue using MOXy, just upgrade Jersey in GF from update center to the latest one and it should start working.
我使用 org.eclipse.persistence.moxy-2.3.jar 通过 Glassfish 3.1.1 使用的 JAXB RI 进行测试。我已经在类路径中的 jaxb.properties 文件中设置了
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
,并使用我的域对象进行测试MOXy,删除后解决了这个问题。因此,从类路径中删除 jaxb.properties 文件解决了问题。
问题是由以下行造成的:
I was using
org.eclipse.persistence.moxy-2.3.jar
to test it over JAXB RI used by Glassfish 3.1.1. I had setjavax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
injaxb.properties
file in the classpath with my domain objects to test MOXy, which after being removed solved the problem.So, removing the
jaxb.properties
file from classpath solved the problem.The problem was being created by the line: