在Osgi中使用Jersey在REST服务中使用application / json [英] Consume application/json in REST services using Jersey in Osgi

查看:116
本文介绍了在Osgi中使用Jersey在REST服务中使用application / json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Jersey在Osgi包中部署一些REST服务。这些服务的注释类似于

I'm deploying some REST services in an Osgi bundle using Jersey. The services are notated like

@POST
@Path("/adduser")
@Consumes(MediaType.APPLICATION_XML+","+MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_XML)
public Message addUser(User user) {
 ...
}

我遇到的第一个问题是该服务不接受我放入@Consumes符号的两种MIME类型但只是第一个。

The first problem I have is that the service doesn't accept both of the MIME types I put into the @Consumes notation but just the first one.

第二个也是最差的是当我尝试调用服务时收到以下异常。我可以@Consumes text / plain,我可以@Produces application / xml例如但是如果我尝试@Consumes应用程序/ json或application / xml服务器抛出异常。

The second and worst is that receive the following exeception when I try to call to the services. I can @Consumes text/plain and I can @Produces application/xml for example but if I try to @Consumes an application/json or application/xml the server throw the exception.

当我使用REST客户端或ajax调用使用格式良好的json或xml进行调用时抛出异常,如果服务只是接收text / plain或者没有收到任何对xml进行正确响应的客户端的响应,那么当我发送POJO但没有收到它们时,序列化器工作正常。

The exception is throwed when I make the call with a wellformed json or xml using a REST client or an ajax call, if the service just receive text/plain or doesnt receive anything the response to the client is made correctly in xml so the serializer is working ok when I send POJO's but not receiving them.

 javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.xml.bind.Unmarshaller.unmarshal(Ljavax/xml/transform/Source;)Ljava/lang/Object;" the class loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the current class, org/glassfish/jersey/message/internal/XmlRootElementJaxbProvider, and the class loader (instance of <bootloader>) for resolved class, javax/xml/bind/Unmarshaller, have different Class objects for the type ject; used in the signature
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:353)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
    at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:96)
    at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:79)
    at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:42)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:49)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
    at es.upm.cedint.gateway.api.corssupport.CORSFilter.doFilter(CORSFilter.java:164)
    at es.upm.cedint.gateway.api.corssupport.CORSFilter.doFilter(CORSFilter.java:246)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
    at es.upm.cedint.gateway.api.security.SecurityFilter.doFilter(SecurityFilter.java:87)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
    at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:48)
    at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:39)
    at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

Caused by: org.glassfish.jersey.server.ContainerException: java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.xml.bind.Unmarshaller.unmarshal(Ljavax/xml/transform/Source;)Ljava/lang/Object;" the class loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the current class, org/glassfish/jersey/message/internal/XmlRootElementJaxbProvider, and the class loader (instance of <bootloader>) for resolved class, javax/xml/bind/Unmarshaller, have different Class objects for the type ject; used in the signature
    at org.glassfish.jersey.servlet.internal.ResponseWriter.rethrow(ResponseWriter.java:230)
    at org.glassfish.jersey.servlet.internal.ResponseWriter.failure(ResponseWriter.java:212)
    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:401)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:243)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:322)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:211)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:979)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:344)
    ... 36 more

Caused by: java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.xml.bind.Unmarshaller.unmarshal(Ljavax/xml/transform/Source;)Ljava/lang/Object;" the class loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the current class, org/glassfish/jersey/message/internal/XmlRootElementJaxbProvider, and the class loader (instance of <bootloader>) for resolved class, javax/xml/bind/Unmarshaller, have different Class objects for the type ject; used in the signature
        at org.glassfish.jersey.message.internal.XmlRootElementJaxbProvider.readFrom(XmlRootElementJaxbProvider.java:140)
        at org.glassfish.jersey.message.internal.AbstractRootElementJaxbProvider.readFrom(AbstractRootElementJaxbProvider.java:122)
        at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:181)
        at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
        at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:72)
        at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
        at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:988)
        at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:833)
        at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:252)
        at org.glassfish.jersey.server.internal.inject.EntityParamValueFactoryProvider$EntityValueFactory.get(EntityParamValueFactoryProvider.java:96)
        at org.glassfish.jersey.server.internal.inject.AbstractHttpContextValueFactory.provide(AbstractHttpContextValueFactory.java:66)
        at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:195)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:94)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:353)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:343)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:237)
        ... 45 more

任何人知道什么可能是错的吗?

Anyone have any idea of what could be wrong?

PD:我想在序列化的User类的开头有@XMLRootElement,我使用的服务器是Jetty。

PD:I have @XMLRootElement at the begining of the User class that I want to serialize and the server I use is Jetty.

推荐答案

对于第一个问题,我认为你不应该有一个带有两个不同签名的函数。我的意思是,如果你想接受json或XML,那么它们是两个不同的函数,尽管从java的角度来看它们看起来是一样的。在你的情况下,我将创建这三个函数:

For the first question, I do not think you should have one function with two different signatures. I mean if you want to accept json or XML those are two different functions although they look the same from the java point of view. In your case I would create these three functions:

@POST
@Path("/adduser")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public Message addUserXML(User user) {
 return addUserInternal(user);
}

@POST
@Path("/adduser")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_XML)
public Message addUserJSon(User user) {
 return addUserInternal(user);
}

private Message addUserInternal(User user) {
  ...
}

第二个问题:Java 6中发生的最糟糕的事情之一(在我看来)是他们将JAXB和其他技术转移到JRE类路径中。我想你的一个捆绑包中也有JAXB。 Jersey和包含REST API的bundle连接到不同的包。其中一个连接到包含JAXB的bundle,而另一个连接到引导类路径(来自JDK的包)

As the second question: One of the worst thing that happened with Java 6 (in my opinion) is that they moved JAXB and other technologies into the JRE classpath. I guess you have also JAXB in one of your bundles. Jersey and the bundle that contains the REST API wire to different packages. One of them wires to the bundle that contains JAXB while the other wires to the boot classpath (package coming from JDK)

你可以有两个解决方案(至少)

You can have two solutions (at least)

第一个解决方案

通过配置OSGi从引导类路径中排除JAXB包环境。

You exclude the JAXB packages from the boot classpath by configuring your OSGi environment.

第二个解决方案

来自JDK的软件包版本为0.0.0_jdkversion 。来自捆绑包的JAXB包具有更好的更高版本,如2.1.1。您可以编辑Jersey的MANIFEST.MF和您的包以指向该版本的包。

The packages coming from JDK have the version 0.0.0_jdkversion. The JAXB package coming from the bundle has a nicer and higher version like 2.1.1. You can edit the MANIFEST.MF of Jersey and your bundle to point to that version of the package.

这篇关于在Osgi中使用Jersey在REST服务中使用application / json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆