JAX-RS:用于基本 HTTP 身份验证的 REST 客户端

发布于 2024-12-11 11:36:22 字数 5454 浏览 0 评论 0原文

我需要使用 JAX-RS 的 Jersey 实现编写一个 REST 客户端,以访问与安全 EJB 配合使用的 RESTful Web 服务。我有一个从类 AB@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();
    }
}

AB 是客户端用来保存服务器返回的数据的域对象。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三人与歌 2024-12-18 11:36:22

您在客户端遇到的第一个异常是由于服务器上出现错误并且服务器返回了意外响应(而不是资源响应,而是返回了带有 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.

海的爱人是光 2024-12-18 11:36:22

我使用 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 文件解决了问题。

问题是由以下行造成的:

List<A> aList = resource.get(new GenericType<List<A>>() {});

I was using org.eclipse.persistence.moxy-2.3.jar to test it over JAXB RI used by Glassfish 3.1.1. I had set javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory in jaxb.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:

List<A> aList = resource.get(new GenericType<List<A>>() {});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文