json端点的奇怪现象

json端点的奇怪现象

本文介绍了Weblogic 12.2.1.2 - 如何调整对象Serializer以使用Jackson 2和jaxrs启用应用程序/ json端点的奇怪现象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 在Weblogic JEE 7(版本12.2.1.2)上,我发现了解应用服务器与JAX-RS Web服务的启用和配置相关的行为非常奇怪。 我试图理解的第一点是一种我觉得无法解释的现象。 在我测试一个简单的jax-rs Web服务的示例应用程序中,最初只有组件: 组件(A) @ApplicationPath(rest)公共类RestApplication扩展Application { private static final Logger LOGGER = LoggerFactory.getLogger(RestApplication.class); //类加载 { LOGGER.info(Rest application static constructor invoked); } / ** *默认不是参数构造函数 * / public RestApplication(){ LOGGER.info(Rest应用程序默认构造函数被调用。); } } 适当启用基本上下文您可能希望在部署中使用的所有其他端点。 与Wildfly完全相同 - 100%。 所以关于这个组件没什么可说的。 然后我们输入沼泽,组件B,我们的休息端点。 在这个虚拟端点上有几个虚拟api,我们只关注最简单的api。 @Path (/ exampleRestEndpoint) @Consumes({application / json,text / html}) @Produces({application / json}) public class ExampleRestEndpoint { private static final Logger LOGGER = LoggerFactory.getLogger(ExampleRestEndpoint.class); @PostConstruct public void postConstruct(){ LOGGER.info(Rest Endpoint construct。); } @GET @Path(/ ping) public BasicJsonResponseDto< String> ping(){即时日期= Instant.now(); 返回新的BasicJsonResponseDto< String>(Ping-service已成功调用。+ date.toString()); } } 我将在稍后详细介绍DTO课程底部。 这里已经有了讨论点。 我的第一个讨论点是类顶部的元数据注释,声明为此我们想要将端点传递回客户端application / json。 但是在我第一次写这个注释时,我实际上没有添加任何这样的anotation。 所以在我的第一次实现时,应用程序服务器正在回复我的回复。 第二步,当我添加注释表明其余端点要撤销applicaiton / json时,weblogic停止呈现任何抱怨以下内容的响应: SEVERE:找不到媒体类型= application / json的MessageBodyWriter, type = class com.jersey.jaxb.Todo,genericType = class com.jersey.jaxb。 Todo。 在wildfly上进行相同的实验,终点工作立刻没有什么大麻烦。 以下堆栈溢出线程让我得到了一个有效的答案: 测试序列化REST JAXRS weblogic会抱怨它知道能够重新编写这个mime类型的知识体作者这一事实令我感到惊讶,因为任何JEE 7容器应该能够开箱即用...但是确定! 在我的pom上为示例应用程序我抽取了以下依赖项进行战争,在Web-inf / lib。 < dependency> < groupId> com.fasterxml.jackson.jaxrs< / groupId> < artifactId> jackson-jaxrs-json-provider< / artifactId> < version> 2.8.6< / version> < / dependency> < dependency> < groupId> com.fasterxml.jackson.module< / groupId> < artifactId> jackson-module-jaxb-annotations< / artifactId> < version> 2.8.6< / version> < / dependency> 问题解决了。 其余的Web服务重新开始工作。 在chrome上,我可以完美地控制http响应元数据。 现在很有趣,当我部署相同的应用程序并带走杰克逊提供程序库时,休息端点继续工作没有任何问题。 实际上,我不能再在我的环境中重现weblogic投诉,即我没有给他任何知道如何处理application / json回复的正文作者。 有没有人知道是否提供application / json的基本休息服务,其中示例应用程序不捆绑jackson库而jus使用jee7 apis,如果weblogic预计记录我引用的错误。 有没有人有任何类型的oncept /解释,因为当我拿走依赖关系时,事情就像人们通常从一开始就预料到的那样......但是在被迫谷歌之后并没有像人们期望的那样没有身体作家问题的解决方案? 我真的没有这方面的解释... 现在第二点是在/ ping上使用返回对象的类我引用的API。 最初,该endpoing API返回纯粹的String。 ping消息没有被包装在任何类型的对象中。 当然结果对象不是真正的JSON对象返回对象只是一些任意的字符串值。 所以这当然是个问题对于休息客户端,期望反序列化有效的json而不是获取对象或数组,在管道上获得纯原始数据。 因此然后,我做了一个实验,在支持dto对象下抽取像String和Integer这样的原始类型。 这是实现。 实现对于下一个问题很重要。 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,include = As.PROPERTY,property =class) public class BasicJsonResponseDto< T>实现Serializable { T值; public BasicJsonResponseDto(){ super(); } public BasicJsonResponseDto(T value){ super(); this.value = value; } public T getValue(){返回值; } public void setValue(T value){ this.value = value; } @Override public String toString(){ returnBasicJsonResponseDto [value =+ value +]; } } 对于眼睛更锐利,它会立即显而易见当通过类这样的类传递到端点的响应对象时,反序列化逻辑根本不是一项微不足道的任务。 这个基本类型Integer / String的包装器对象在那里有点毒。 也就是说,我们将ping字符串输入的值T对于反序列化引擎没有帮助,无法确定预期读出的对象。 因此,从技术上讲,ping服务对于客户端代码来说并不是微不足道。 据说,我现在在Weblogic上有两种截然不同的行为和野蝇。 并且必须与每个使用的序列化技术直接相关。 当在weblogic上执行ping服务时,现在,响应对象我得到的形式是: {value:{type:string,value:Ping-服务调用成功。 2017-08-12T09:08:45.455Z}} 所以你看到的是ObjectMapper weblogic正在使用,我肯定没有配置,默认情况下,在T值上输入额外的元数据,即将其声明为字符串。 (a)这非常可爱,没有我的要求,但在客户端我需要创建一个反序列化的ObjectMapper,可以解释相同的对象medata。 最有可能有一组足够的注释,例如@JsonInfo和@JsonSubtype,我可以添加到T值字段以使反序列化在客户端工作,但就DTO对象而言,我是写了我没有要求任何这样的元数据出去。 (b)如果你知道杰克逊,你还会注意到对象缺少信息同样。 即,我没有看到class =full.qualified.name到我的对象。 但是我已经确保通过将此注释抽入课堂中,请求将此元数据发送到响应json上。 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,include = As.PROPERTY,property =class) 所以我的问题是:(1)weblogic用什么库来序列化我的json (2)他们有什么默认配置(3)我我的pom.xml中引入了jackson-jaxrs-json-provider依赖项,最初使我的端点工作。 我查看了这个库的源代码,它看起来像这个库试图负责json响应的呈现。 它有一个CDI @Provide @Consumes( / )生成( / ),如果我启用调试器,我可以在部署期间看到杰克逊 - jaxrs-json-provider被调用。 我在weblogic中看不到的是这个类的ObjectMapper被调用。 如果我不能覆盖现在负责的任何默认行为。 是否有人理解这种行为。 有没有办法把野兽放在皮带上并控制情况? 或者我是否必须将代码简化为如此程度,即我的String包装对象被命名为StringWrappedDto并且值字段被trvia化为String值。我希望不会,但是现在我正在努力这个。 现在,我们切换到Wildfly 10.1.0。在Wildfly 10.1.0上,根据我的预期,我的体验正在变得更加明显。 / p> (a)如果只使用我提供的RestApplication和Endpoint部署WAR。开箱即用。没有麻烦,没有无法呈现application / json的消息。您将开始工作而不控制任何配置。 (b)如果您举例想要覆盖Json的呈现行为,你可以定义自己的ObjectMapper提供者。 Eg public class ObjectMapperContextResolver implements ContextResolver< ObjectMapper> { 私有最终ObjectMapper映射器; publ ic ObjectMapperContextResolver(){ mapper = new ObjectMapper(); mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); } @Override public ObjectMapper getContext(Class<?> type){ return mapper; } } 这个人在这里,如果你调试它,你可以看到每次调用Ping服务时都会调用它。 因此,如果您需要这样的控制级别,您可以负责json响应的序列化。 最后,在wildfly上,JSON响应我得到的是我所期望的,如下面的引用所示: {class:entrypoint.rest.BasicJsonResponse,value :Ping-service 成功调用.2017-08-12T16:42:13.788Z} 我有尝试在杰克逊2的几乎所有类别中设置断点,这涉及数据的序列化,并且几乎没有任何东西在weblogic上被击中。 所以我很确定,wlserver / modules中的某些内容正在被使用。 任何人都知道如何强制将j​​ackson2声明为对战争的依赖用于serializaton并杀死现在正在发生的任何默认行为? - 它现在开始清楚渲染中发生了什么。 我已将以下单元测试作为实验编写: @Test public void serializeJerseyTest()抛出JsonProcessingException,JAXBException { //(a)将被编组到json BasicJsonResponseDto< String> objectToSerialize = new BasicJsonResponseDto< String>(Ping-service已成功调用。+ Instant.now()。toString()); //(b)设置jaxbcontext Map< String,Object> properties = new HashMap< String,Object>(3); JAXBContext jc = JAXBContext.newInstance(BasicStringJsonResponseDto.class); //(c)Marshall系统输出 Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true); marshaller.setProperty(eclipselink.media-type,application / json); marshaller.setProperty(eclipselink.media-type,application / json); marshaller.marshal(objectToSerialize,System.out); } 单元测试的输出看起来很熟悉...... {value:{type:string,value :Ping服务成功调用.2017-08-12T19:33:05.834Z} Oracle正在使用Moxy制作json ... 现在的问题是,如何让它改为使用jackson2? 我是确定有办法。可以在jersey文档中找到,我相信默认情况下会想要使用Moxy。 为了将来的参考,我现在将发布调试堆栈跟踪说话量。 我试图调试的所有代码都无法找到原因,因为我一直试图在杰克逊上设置断点,而实施时一直是jersey + moxy。 所以这就是答案。 我来到这个堆栈跟踪是世界上最荒谬的原因。 开箱即用的Moxy不能反序化它为这个Web服务生成的JSON对象。 有谁能理解这个? 那个moxy在POJO上序列化了我som json,但是unmarshall无法正确地解组值字段? 所以这里是堆栈跟踪: 守护程序线程[[ACTIVE] ExecuteThread:'4'表示队列:' weblogic.kernel.Default(self-tuning)'](Suspended(entrypoint.rest.ObjectAdapter第51行的断点)) entrypoint.rest.ObjectAdapter.marshal(java.lang.Object)行:51 entrypoint.rest.ObjectAdapter.marshal(java.lang.Object)行:1 org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter.convertObjectValueToDataValue(java.lang.Object,org.eclipse.persistence.sessions .Session,org.eclipse.persistence.oxm.XMLMarshaller)line:178 org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping.convertObjectValueToDataValue(java.lang.Object,org.eclipse.persistence.sessions.Session, org.eclipse.persistence.oxm.XMLMarshaller)line:652 org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping.convertObjectValueToDataValue(java.lang.Object,org.eclipse.persistence.core.sessions.CoreSession,org .eclipse.persistence.in ternal.oxm.Marshaller)line:1 org.eclipse.persistence.internal.oxm.XMLAnyObjectMappingNodeValue.marshalSingleValue(org.eclipse.persistence.internal.oxm.XPathFragment,org.eclipse.persistence.internal.oxm.record .MarshalRecord,java.lang.Object,java.lang.Object,org.eclipse.persistence.internal.core.sessions.CoreAbstractSession,org.eclipse.persistence.internal.oxm.NamespaceResolver,org.eclipse.persistence.internal.oxm .record.MarshalContext)line:72 org.eclipse.persistence.internal.oxm.XMLAnyObjectMappingNodeValue.marshal(org.eclipse.persistence.internal.oxm.XPathFragment,org.eclipse.persistence.internal.oxm.record。 MarshalRecord,java.lang.Object,org.eclipse.persistence.internal.core.sessions.CoreAbstractSession,org.eclipse.persistence.internal.oxm.NamespaceResolver,org.eclipse.persistence.internal.oxm.record.MarshalContext)行: 65 org.eclipse.persistence.internal.oxm.XMLAnyObjectMappingNodeValue(org.eclipse.persistence.internal.oxm.NodeValue ).marshal(org.eclipse.persistence.internal.oxm.XPathFragment,org.eclipse.persistence.internal.oxm.record.MarshalRecord,java.lang.Object,org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.NamespaceResolver,org.eclipse.persistence.internal.oxm.record.MarshalContext,org.eclipse.persistence.internal.oxm.XPathFragment)line:102 org.eclipse.persistence .internal.oxm.record.ObjectMarshalContext.marshal(org.eclipse.persistence.internal.oxm.NodeValue,org.eclipse.persistence.internal.oxm.XPathFragment,org.eclipse.persistence.internal.oxm.record.MarshalRecord,java .lang.Object,org.eclipse.persistence.internal.core.sessions.CoreAbstractSession,org.eclipse.persistence.internal.oxm.NamespaceResolver,org.eclipse.persistence.internal.oxm.XPathFragment)行:59 org.eclipse.persistence.internal.oxm.XPathNode.marshal(org.eclipse.persistence.internal.oxm.record.MarshalRecord,java.lang.Object,org.eclipse.persistence。 internal.core.sessions.CoreAbstractSession,org.eclipse.persistence.internal.oxm.NamespaceResolver,org.eclipse.persistence.internal.oxm.Marshaller,org.eclipse.persistence.internal.oxm.record.MarshalContext,org.eclipse。 persistence.internal.oxm.XPathFragment)line:443 org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(org.eclipse.persistence.internal.oxm.record.XMLRecord,java.lang.Object,org .eclipse.persistence.internal.core.sessions.CoreAbstractSession,org.eclipse.persistence.internal.oxm.Marshaller,org.eclipse.persistence.internal.oxm.XPathFragment)line:243 org.eclipse.persistence。 internal.oxm.TreeObjectBuilder.buildRow(org.eclipse.persistence.internal.oxm.record.XMLRecord,java.lang.Object,org.eclipse.persistence.internal.core.sessions.CoreAbstractSession,org.eclipse.persistence.internal。 oxm.XMLMarshaller,org.eclipse.persistence.internal.oxm.XPathFragment)line:118 org.eclipse.persistence.internal.oxm.TreeObjectBuilder.bui ldRow(org.eclipse.persistence.internal.oxm.record.XMLRecord,java.lang.Object,org.eclipse.persistence.internal.core.sessions.CoreAbstractSession,org.eclipse.persistence.internal.oxm.Marshaller,org。 eclipse.persistence.internal.oxm.XPathFragment)行:1 org.eclipse.persistence.oxm.XMLMarshaller(org.eclipse.persistence.internal.oxm.XMLMarshaller< ABSTRACT_SESSION,CHARACTER_ESCAPE_HANDLER,CONTEXT,DESCRIPTOR,MARSHALLER_LISTENER,MEDIA_TYPE ,NAMESPACE_PREFIX_MAPPER,OBJECT_BUILDER,SESSION>)。marshal(java.lang.Object,org.eclipse.persistence.oxm.record.MarshalRecord,ABSTRACT_SESSION,DESCRIPTOR,boolean)line:766 org.eclipse.persistence.oxm。 XMLMarshaller(org.eclipse.persistence.internal.oxm.XMLMarshaller< ABSTRACT_SESSION,CHARACTER_ESCAPE_HANDLER,CONTEXT,DESCRIPTOR,MARSHALLER_LISTENER,MEDIA_TYPE,NAMESPACE_PREFIX_MAPPER,OBJECT_BUILDER,SESSION>)。marshalStreamOrWriter(java.lang.Object,org.eclipse.persistence.oxm。 record.MarshalRecord,ABSTRACT_SESSION,DESCRIPT OR,boolean)line:1147 org.eclipse.persistence.oxm.XMLMarshaller(org.eclipse.persistence.internal.oxm.XMLMarshaller< ABSTRACT_SESSION,CHARACTER_ESCAPE_HANDLER,CONTEXT,DESCRIPTOR,MARSHALLER_LISTENER,MEDIA_TYPE,NAMESPACE_PREFIX_MAPPER,OBJECT_BUILDER,SESSION> ;)。marshal(java.lang.Object,java.io.OutputStream,ABSTRACT_SESSION,DESCRIPTOR)行:934 org.eclipse.persistence.oxm.XMLMarshaller(org.eclipse.persistence.internal.oxm.XMLMarshaller< ABSTRACT_SESSION,CHARACTER_ESCAPE_HANDLER,CONTEXT,DESCRIPTOR,MARSHALLER_LISTENER,MEDIA_TYPE,NAMESPACE_PREFIX_MAPPER,OBJECT_BUILDER,SESSION>)。marshal(java.lang.Object,java.io.OutputStream)line:877 org.eclipse.persistence.jaxb.JAXBMarshaller .marshal(java.lang.Object,java.io.OutputStream)行:496 org.glassfish.jersey.moxy.json.internal.ConfigurableMoxyJsonProvider(org.eclipse.persistence.jaxb.rs.MOXyJsonProvider).writeTo (java.lang.Object,java.lang.Class<?> ;, java.lang.reflect.Type,java.la ng.annotation.Annotation [],javax.ws.rs.core.MediaType,javax.ws.rs.core.MultivaluedMap< java.lang.String,java.lang.Object>,java.io.OutputStream)line:957 org.glassfish.jersey.message.internal.WriterInterceptorExecutor $ TerminalWriterInterceptor.invokeWriteTo(javax.ws.rs.ext.WriterInterceptorContext,javax.ws.rs.ext.MessageBodyWriter)line:265 org.glassfish .jersey.message.internal.WriterInterceptorExecutor $ TerminalWriterInterceptor.aroundWriteTo(javax.ws.rs.ext.WriterInterceptorContext)行:250 org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed()行:162 org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(javax.ws.rs.ext.WriterInterceptorContext)行:106 org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed()行: 162 org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(javax.ws.rs.ext.WriterInterceptorContext)l ine:86 org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed()line:162 weblogic.jaxrs.server.internal.ChunkedOutputWriter.aroundWriteTo(javax.ws.rs.ext.WriterInterceptorContext )line:65 org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed()line:162 org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(java.lang.Object, java.lang.Class<?>,java.lang.reflect.Type,java.lang.annotation.Annotation [],javax.ws.rs.core.MediaType,javax.ws.rs.core.MultivaluedMap< java。 lang.String,java.lang.Object>,org.glassfish.jersey.internal.PropertiesDelegate,java.io.OutputStream,java.lang.Iterable< javax.ws.rs.ext.WriterInterceptor>)line:1130 org.glassfish.jersey.server.ServerRuntime $ Responder.writeResponse(org.glassfish.jersey.server.ContainerResponse)行:711 org.glassfish.jersey.server.ServerRuntime $ Responder.processResponse(org.glassfish。 jersey.server.ContainerRes ponse)line:444 org.glassfish.jersey.server.ServerRuntime $ Responder.process(org.glassfish.jersey.server.ContainerResponse)line:434 org.glassfish.jersey.server.ServerRuntime $ 2 .run()行:329 org.glassfish.jersey.internal.Errors $ 1.call()行:271 org.glassfish.jersey.internal.Errors $ 1.call()行:267 org.glassfish.jersey.internal.Errors.process(java.util.concurrent.Callable< T>,boolean)line:315 org.glassfish.jersey.internal.Errors.process(org.glassfish) .jersey.internal.util.Producer< T> ;, boolean)line:297 org.glassfish.jersey.internal.Errors.process(java.lang.Runnable)line:267 org.glassfish。 jersey.process.internal.RequestScope.runInScope(org.glassfish.jersey.process.internal.RequestScope $ Instance,java.lang.Runnable)行:317 org.glassfish.jersey.server.ServerRuntime.process(org .glassfish.jersey.server.ContainerRequest)行:305 org.glassfish.jersey.ser ver.ApplicationHandler.handle(org.glassfish.jersey.server.ContainerRequest)行:1154 org.glassfish.jersey.servlet.WebComponent.serviceImpl(java.net.URI,java.net.URI,javax.servlet) .http.HttpServletRequest,javax.servlet.http.HttpServletResponse)行:471 org.glassfish.jersey.servlet.WebComponent.service(java.net.URI,java.net.URI,javax.servlet.http。 HttpServletRequest,javax.servlet.http.HttpServletResponse)行:425 org.glassfish.jersey.servlet.ServletContainer.service(java.net.URI,java.net.URI,javax.servlet.http.HttpServletRequest,javax .servlet.http.HttpServletResponse)行:383 org.glassfish.jersey.servlet.ServletContainer.service(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)行:336 org .glassfish.jersey.servlet.ServletContainer.service(javax.servlet.ServletRequest,javax.servlet.ServletResponse)行:223 weblogic.servlet.internal.StubSecurityHelper $ ServletServiceAction.ru n()行:286 weblogic.servlet.internal.StubSecurityHelper $ ServletServiceAction.run()行:260 weblogic.servlet.internal.StubSecurityHelper.invokeServlet(javax.servlet.ServletRequest,javax.servlet。 http.HttpServletRequest,weblogic.servlet.internal.ServletRequestImpl,javax.servlet.ServletResponse,javax.servlet.http.HttpServletResponse,javax.servlet.Servlet)line:137 weblogic.servlet.internal.ServletStubImpl.execute(javax .servlet.ServletRequest,javax.servlet.ServletResponse,weblogic.servlet.internal.FilterChainImpl)line:350 weblogic.servlet.internal.TailFilter.doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax。 servlet.FilterChain)行:25 weblogic.servlet.internal.FilterChainImpl.doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse)行:78 weblogic.servlet.internal.RequestEventsFilter.doFilter( javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servle t.FilterChain)行:32 weblogic.servlet.internal.FilterChainImpl.doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse)行:78 weblogic.servlet.internal.WebAppServletContext $ ServletInvocationAction。 wrapRun(weblogic.servlet.internal.ServletStub,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)行:3683 weblogic.servlet.internal.WebAppServletContext $ ServletInvocationAction.run()行:3649 weblogic.security.acl.internal.AuthenticatedSubject.doAs(weblogic.security.subject.AbstractSubject,java.security.PrivilegedAction)line:326 weblogic.security.service.SecurityManager.runAsForUserCode(weblogic.security。 acl.internal.AuthenticatedSubject,weblogic.security.acl.internal.AuthenticatedSubject,java.security.PrivilegedAction< T>)line:197 weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(weblogic.security.acl.internal。 AuthenticatedSubject,java.security.Priv ilegedAction,weblogic.security.acl.internal.AuthenticatedSubject)行:203 weblogic.servlet.provider.WlsSubjectHandle.run(java.security.PrivilegedAction)行:71 weblogic.servlet.internal.WebAppServletContext。 doSecuredExecute(weblogic.servlet.internal.ServletInvocationContext,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,boolean,boolean,boolean)line:2433 weblogic.servlet.internal.WebAppServletContext.securedExecute(javax) .servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,boolean)line:2281 weblogic.servlet.internal.WebAppServletContext.execute(weblogic.servlet.internal.ServletRequestImpl,weblogic.servlet.internal.ServletResponseImpl) line:2259 weblogic.servlet.internal.ServletRequestImpl.runInternal()line:1691 weblogic.servlet.internal.ServletRequestImpl.run()line:1651 weblogic.servlet.provider.ContainerSupportProviderImpl $ WlsRequestExe cutor.run()行:270 weblogic.invocation.ComponentInvocationContextManager._runAs(weblogic.invocation.ComponentInvocationContext,java.lang.Runnable)line:348 weblogic.invocation.ComponentInvocationContextManager.runAs(java.security .Principal,weblogic.invocation.ComponentInvocationContext,java.lang.Runnable)line:333 weblogic.work.LivePartitionUtility.doRunWorkUnderContext(java.lang.Runnable,weblogic.invocation.ComponentInvocationContext)line:54 weblogic .work.PartitionUtility.runWorkUnderContext(java.lang.Runnable,weblogic.invocation.ComponentInvocationContext)行:41 weblogic.work.ServerWorkManagerImpl(weblogic.work.SelfTuningWorkManagerImpl).runWorkUnderContext(weblogic.work.ExecuteThread,weblogic.work .WorkAdapter)行:640 weblogic.work.ExecuteThread.execute(weblogic.work.WorkAdapter)行:406 weblogic.work.ExecuteThread.run()行:346 我相信我不会在weblogic上搜索使用jackson的方法,我完全无法解决这个问题,只需要通过充满jaxB注释的类来解决这个问题,最重要的是为此编写XmlAdapters。 杰克逊可以免费完成所有这些工作。 这就是为什么在需要时,杰克逊会写出@class属性,包含要反序列化的类的所有内联元数据。 简直不能这么糟糕。不能。 非常感谢。解决方案好吧, Weblogic正在通过Jersey实现JAX-RS。 根据球衣文件,这应该是一个简单的问题,可以在你的部署中使用依赖来完成从Moxy到Jackson的切换。 例如 < dependency> < groupId> org.glassfish.jersey.media< / groupId> < artifactId> jersey-media-json-jackson< / artifactId> < version> 2.26-b09< / version> < scope>运行时< / scope> < / dependency> 请参阅以下参考资料。 https://jersey.github.io/documentation/latest/ media.html #json 似乎不是那么琐碎,要做切换,我的weblogic行为仍然反映了Moxy的用法,即使我曾经在泽西文献中添加了图书馆。也许我尝试使用错误的版本...我今天不会发现这个。 老实说,我的耐心已达到这个小问题的极限。 我决定顺其自然。让泽西岛保持默认行为让它成为Moxy。我不会挡路。 我发现Moxy比jackson更冗长,我并不特别想要传播像蘑菇这样的jaxb.properties文件包含休息DTOS的文件夹。 jaxb.properties示例: javax.xml.bind.context。 factory = org.eclipse.persistence.jaxb.JAXBContextFactory 在任何情况下,现在我希望结果之间存在一致性在Weblogic和Wildfly上休息。如果应用服务器是Weblogic用A去序列化,如果它是野生动物用B反序列化它,我就不会写。没办法! 那么我是什么确实非常简单。 Wildfly使用restEasy。休息轻松简单! :) 所以我只是去了我的web.xml 并提供了以下信息: < context-param> < param-name> resteasy.providers< / param-name> <param-value>org.eclipse.persistence.jaxb.rs.MOXyJsonProvider</param-value> < / context-param> Thanks restEasy documentation, that was really helpful! Finally, since I always use EclipseLink instead of Hibernate, the eclipselink module is already active whend df I startup wildfly. No need to activate it via jboss-deployment descriptor.xml. However, the module was lacking sufficient metadata. I had to pump into the module \"org.eclipse.persistence\" main.xml the following dependency:<module name=\"javax.ws.rs.api\" /> That means my module looks as follows:<module xmlns=\"urn:jboss:module:1.3\" name=\"org.eclipse.persistence\"> < properties> <property name=\"jboss.api\" value=\"private\"/> < / properties> <resources> <resource-root path=\"jipijapa-eclipselink-10.1.0.Final.jar\"/> <resource-root path=\"eclipselink-2.6.4.jar\"> <filter> <exclude path=\"javax/**\" /> </filter> </resource-root> < / resources> < dependencies> <module name=\"asm.asm\"/> < module name =javax.api/> <module name=\"javax.annotation.api\"/> <module name=\"javax.enterprise.api\"/> <module name=\"javax.persistence.api\"/> <module name=\"javax.transaction.api\"/> <module name=\"javax.validation.api\"/> <module name=\"javax.xml.bind.api\"/> <module name=\"org.antlr\"/> <module name=\"org.dom4j\"/> <module name=\"org.javassist\"/> <module name=\"org.jboss.as.jpa.spi\"/> <module name=\"org.jboss.logging\"/> <module name=\"org.jboss.vfs\"/> <!-- Add dependency on rest api --> <module name=\"javax.ws.rs.api\" /> < / dependencies> < / module> NOTE: Just be careful maintaining such information, you want to automate hacking these files because you will lose track of this as time goes by. Best is you create an installer for wildfly that given a vanilla zip does all your hacky tunings to the base metadata files, otherwise you are lost. In any case, now Wildfly is rendering the output of rest calls based on Moxy and not based on Jackson. This means I will have to refactor my rest client to be Moxy based, but quite honestly... I am out of energy to struggle against weblogic. I prefer Jackson, so much simpler and quicker to use, but hey... pick your battles right? Editing informaiton: some more information on weblogic: On Weblogic, the following configuration is effective. IF you write RestApplication class and override the public Map getProperties() you can add the following property:proprties.put(\"jersey.config.server.disableMoxyJson\", true); And this will disable the Server behavior of using moxy and switch to jackson. This has not effect on wildfly since only weblogic uses jersey and wildfly uses resteasy. Finally, to make a rest client you would do:javax.ws.rs.client.ClientBuilder.newClient().register(Class.forName(\"org.glassfish.jersey.jackson.JacksonFeature\")) On Weblogic JEE 7 (version 12.2.1.2), I am finding it quite strange to understand the behavior of the application server in relation to the enablement and configuration of the JAX-RS web services.The first point that I am trying to understand is a phenomena that I find quite inexplicable.On a sample application where I was testing a trivial jax-rs web service where initially there were only to components:Component (A) @ApplicationPath("rest")public class RestApplication extends Application { private static final Logger LOGGER = LoggerFactory.getLogger(RestApplication.class); // Class loading { LOGGER.info("Rest application static constructor invoked"); } /** * Default not arguments constructor */ public RestApplication() { LOGGER.info("Rest application default constructore invoked."); }}Which appropriately enables the base context for all rest endpoints you may want to use in your deployment.Works exactly as in Wildfly - 100%. So nothing to say about this component.And then we enter the "swamp", component B, our rest endpoint.There are several dummy apis on this dummy endpoint, we focus just on the most trivial of all.@Path("/exampleRestEndpoint")@Consumes({ "application/json", "text/html" })@Produces({ "application/json" })public class ExampleRestEndpoint { private static final Logger LOGGER = LoggerFactory.getLogger(ExampleRestEndpoint.class); @PostConstruct public void postConstruct() { LOGGER.info("Rest Endpoint constructed."); } @GET @Path("/ping") public BasicJsonResponseDto<String> ping() { Instant date = Instant.now(); return new BasicJsonResponseDto<String>("Ping-service invoked successfully. " + date.toString()); }}I will go into details on the DTO class later at the bottom.There are already points of discussion here.The first point of discussion for me is the the metadata annotation at the top of the class that declares that for this endpoint we want to deliver back to the clients application/json.But on my first writing of this annotation, I had in fact not added ANY such anotation.So on my first implementation, the application server was working returning me a reply.On a second step, when I added the annotation stating that the rest endpoint was to be returing applicaiton/json, weblogic stopped rendering any response complaining of the following: SEVERE: MessageBodyWriter not found for media type=application/json, type=class com.jersey.jaxb.Todo, genericType=class com.jersey.jaxb.Todo.Same experiment on wildfly, the endpoint worked immediately no major hassle.The following stack overflow thread yielded me an answer that worked:test serializations REST JAXRSThe fact that weblogic would complain that it knows of know body writers that are capable of redering this mime type is suprising to me, being that any JEE 7 container should be able of doing this out of the box... but ok!On my pom for the sample application I pumped the following dependencies to be going into war, in the Web-inf/lib.<dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-json-provider</artifactId> <version>2.8.6</version></dependency><dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-jaxb-annotations</artifactId> <version>2.8.6</version></dependency>And problem solved.The rest web service goes back to working.On chrome I can control the http response metadata all perfect.Funy thing now, when I deploy the same application and take away the jackson provider library, the rest endpoint continues to work without any problems.Actually, I can no longer reproduce on my environment the weblogic complaint that I am not giving him any body writer that knows what to do with application/json replies.So, this is my first question?Does anybody know if for a basic rest service that deliver application/json where a sample application bundles no jackson library and jus uses jee7 apis, if weblogic is expected to be logging the error I quoted or not.Does anybody have any sort of oncept/explanation for the fact that when I take away the dependencies things are just working as one would normally have expected from the start ... but not as one expect after having been forced to google a solution for the no body writer problem?I really do not have an explanation for this...Now the second point is to do with the class being used a return object on the /ping API i have quoted.Originally, that endpoing API was returning a pure "String".The ping message was not being wrapped in any sort of object.And of course the result object was no real JSON object The return object was just a "some arbitrary string value".So this of course is a problem for a rest client, that is expecting to de-serialize valid json and instead of getting an object or array, is getting pure raw data on the pipe.For this reason, I then made the experiment of pumping the raw types like String and Integer under a support dto object.Here is the implementation.The implementation is important for the next question.@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "class")public class BasicJsonResponseDto<T> implements Serializable { T value; public BasicJsonResponseDto() { super(); } public BasicJsonResponseDto(T value) { super(); this.value = value; } public T getValue() { return value; } public void setValue(T value) { this.value = value; } @Override public String toString() { return "BasicJsonResponseDto [value=" + value + "]"; }}For the sharper eyes, it will be immediately be obvious that when a response object to an endpoint is delivered via a class like this, the "de-serialization" logic is not a trivial task at all.This wrapper object for the basic types Integer/String has a little be of poison in there.Namely, the value T where we pump our ping string into gives no help for the de-serialization engine to figure out what object it is to expect to read out.So the ping service, technically, is not trivial at all for the client-side code.With that said, I now have two very different behaviors on Weblogic and Wildfly.And the different must be directly related with the serialization technology that each is using.When the ping service is executed on weblogic, right now, the reponse objects I get are of the form: {"value":{"type":"string","value":"Ping-service invoked successfully. 2017-08-12T09:08:45.455Z"}}So you see that whatever ObjectMapper weblogic is using and that I have definitely not configured, is by default pumping additional metadata aboute the T value, namely declaring it as a string.(a) It is very cute that this done without my asking, but then on the client side I need to create an ObjectMapper to de-serialize that can interpret that same object medata.Most likely there is an adequate set of annotation such as @JsonInfo with @JsonSubtype that I can add to the T value field to make the de-serialization work on the client side, but in terms of the DTO object that I have written I have not asked for any such metadata to go out.(b) You will also notice, if you know jackson, that there is missing information on the object as well.namely, I do not see the class="full.qualified.name" to my object.But I have made sure I requested this metadata to go out on the response json by pumping this annotation into the class.@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "class")So my question here is:(1) What library exactly is weblogic using to serialize my json(2) What default configurations do they have in there(3) I have pumped into my pom.xml the "jackson-jaxrs-json-provider" dependency that originally make my endpoint work.I have looked at the source code of this library, and it looks to me like this library tries to be in charge of the rendering of the json responses.It does have a CDI @Provide @Consumes(/) Produces(/), and if I enable the debugger I can see during deployment that the jackson-jaxrs-json-provider gets invoked.What I cannot see happening in weblogic is the ObjectMapper of this class ever getting called.it is if I cannot override whatever default behavior is in charge right now.Does anybody understand the behavior.Are there ways to put the beast on a leash and take control of the situation?Or do I have to trivialize the code to such a degree where my String wrapped object is named" StringWrappedDto and the value field is trviailized into String value.I hope not, but right now I am struggling with this.Now, we switch to Wildfly 10.1.0.On Wildfly 10.1.0, my experience is things are going rather more according to expectation.(a) If you deploy a WAR with just the RestApplication and the Endpoint I have provided.Things work out of the box.No hassle, no messages of incapacity to render application/json.You are set to start working without taking control of any configuration.(b) If you for example want to override the rendering behavior for Json, you can define your own ObjectMapper provider.E.g. public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> { private final ObjectMapper mapper; public ObjectMapperContextResolver() { mapper = new ObjectMapper(); mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); } @Override public ObjectMapper getContext(Class<?> type) { return mapper; }}And this guy here, if you debug it, you can see it get called on every call to the Ping service.So you can take charge of how the json response will be serialized, if you need such level of control.To conclude, on wildfly, the JSON response I get is what I expect as illustrated in the following quote: {"class":"entrypoint.rest.BasicJsonResponse","value":"Ping-service invoked successfully. 2017-08-12T16:42:13.788Z"}I have tried setting breakpoints on almost every classon from jackson 2 that is involved in serialization of data, and literrally nothing gets hit on weblogic.So I am pretty certain, something in the wlserver/modules is getting used.Anyone has an idea of how to force jackson2 declared as dependency to the war to get used for serializaton and kill whatever default behavior is right now taking place?--It now starts being clear what is happening in the rendering.I have written the following unit test as an experiment: @Test public void serializeJerseyTest() throws JsonProcessingException, JAXBException { // (a) class to be marshalled into json BasicJsonResponseDto<String> objectToSerialize = new BasicJsonResponseDto<String>( "Ping-service invoked successfully. " + Instant.now().toString()); // (b) setup a jaxbcontext Map<String, Object> properties = new HashMap<String, Object>(3); JAXBContext jc = JAXBContext.newInstance(BasicStringJsonResponseDto.class); // (c) Marshall to system out Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty("eclipselink.media-type", "application/json"); marshaller.setProperty("eclipselink.media-type", "application/json"); marshaller.marshal(objectToSerialize, System.out); }And the output of the unit test looks quite familiar...{ "value" : { "type" : "string", "value" : "Ping-service invoked successfully. 2017-08-12T19:33:05.834Z" }Oracle is using Moxy to make the json...So now the question is, how do I make it use jackson2 instead?I am sure there is a way. Proably to be found on the jersey documentation, which I believe by default will want to use Moxy.For future, reference, I will be now posting a debug stack trace that speaks volumes.All the code I was trying to debug and could not find out how because I wasll the the time trying to set breakpoints on jackson when the implementation was jersey + moxy all along.So here is the answer to that.I came to this stack trace for the most rediculous reason in the world.Moxy out of the box canont deserialize the JSON object it is producing for this web service.Can anyone understand this?That moxy is serializing me som json on the POJO but then the unmarshall cannot properly unsmarshall the value field?So here is the stack trace:Daemon Thread [[ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)'] (Suspended (breakpoint at line 51 in entrypoint.rest.ObjectAdapter)) entrypoint.rest.ObjectAdapter.marshal(java.lang.Object) line: 51 entrypoint.rest.ObjectAdapter.marshal(java.lang.Object) line: 1 org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter.convertObjectValueToDataValue(java.lang.Object, org.eclipse.persistence.sessions.Session, org.eclipse.persistence.oxm.XMLMarshaller) line: 178 org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping.convertObjectValueToDataValue(java.lang.Object, org.eclipse.persistence.sessions.Session, org.eclipse.persistence.oxm.XMLMarshaller) line: 652 org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping.convertObjectValueToDataValue(java.lang.Object, org.eclipse.persistence.core.sessions.CoreSession, org.eclipse.persistence.internal.oxm.Marshaller) line: 1 org.eclipse.persistence.internal.oxm.XMLAnyObjectMappingNodeValue.marshalSingleValue(org.eclipse.persistence.internal.oxm.XPathFragment, org.eclipse.persistence.internal.oxm.record.MarshalRecord, java.lang.Object, java.lang.Object, org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.NamespaceResolver, org.eclipse.persistence.internal.oxm.record.MarshalContext) line: 72 org.eclipse.persistence.internal.oxm.XMLAnyObjectMappingNodeValue.marshal(org.eclipse.persistence.internal.oxm.XPathFragment, org.eclipse.persistence.internal.oxm.record.MarshalRecord, java.lang.Object, org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.NamespaceResolver, org.eclipse.persistence.internal.oxm.record.MarshalContext) line: 65 org.eclipse.persistence.internal.oxm.XMLAnyObjectMappingNodeValue(org.eclipse.persistence.internal.oxm.NodeValue).marshal(org.eclipse.persistence.internal.oxm.XPathFragment, org.eclipse.persistence.internal.oxm.record.MarshalRecord, java.lang.Object, org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.NamespaceResolver, org.eclipse.persistence.internal.oxm.record.MarshalContext, org.eclipse.persistence.internal.oxm.XPathFragment) line: 102 org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext.marshal(org.eclipse.persistence.internal.oxm.NodeValue, org.eclipse.persistence.internal.oxm.XPathFragment, org.eclipse.persistence.internal.oxm.record.MarshalRecord, java.lang.Object, org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.NamespaceResolver, org.eclipse.persistence.internal.oxm.XPathFragment) line: 59 org.eclipse.persistence.internal.oxm.XPathNode.marshal(org.eclipse.persistence.internal.oxm.record.MarshalRecord, java.lang.Object, org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.NamespaceResolver, org.eclipse.persistence.internal.oxm.Marshaller, org.eclipse.persistence.internal.oxm.record.MarshalContext, org.eclipse.persistence.internal.oxm.XPathFragment) line: 443 org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(org.eclipse.persistence.internal.oxm.record.XMLRecord, java.lang.Object, org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.Marshaller, org.eclipse.persistence.internal.oxm.XPathFragment) line: 243 org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(org.eclipse.persistence.internal.oxm.record.XMLRecord, java.lang.Object, org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.XMLMarshaller, org.eclipse.persistence.internal.oxm.XPathFragment) line: 118 org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(org.eclipse.persistence.internal.oxm.record.XMLRecord, java.lang.Object, org.eclipse.persistence.internal.core.sessions.CoreAbstractSession, org.eclipse.persistence.internal.oxm.Marshaller, org.eclipse.persistence.internal.oxm.XPathFragment) line: 1 org.eclipse.persistence.oxm.XMLMarshaller(org.eclipse.persistence.internal.oxm.XMLMarshaller<ABSTRACT_SESSION,CHARACTER_ESCAPE_HANDLER,CONTEXT,DESCRIPTOR,MARSHALLER_LISTENER,MEDIA_TYPE,NAMESPACE_PREFIX_MAPPER,OBJECT_BUILDER,SESSION>).marshal(java.lang.Object, org.eclipse.persistence.oxm.record.MarshalRecord, ABSTRACT_SESSION, DESCRIPTOR, boolean) line: 766 org.eclipse.persistence.oxm.XMLMarshaller(org.eclipse.persistence.internal.oxm.XMLMarshaller<ABSTRACT_SESSION,CHARACTER_ESCAPE_HANDLER,CONTEXT,DESCRIPTOR,MARSHALLER_LISTENER,MEDIA_TYPE,NAMESPACE_PREFIX_MAPPER,OBJECT_BUILDER,SESSION>).marshalStreamOrWriter(java.lang.Object, org.eclipse.persistence.oxm.record.MarshalRecord, ABSTRACT_SESSION, DESCRIPTOR, boolean) line: 1147 org.eclipse.persistence.oxm.XMLMarshaller(org.eclipse.persistence.internal.oxm.XMLMarshaller<ABSTRACT_SESSION,CHARACTER_ESCAPE_HANDLER,CONTEXT,DESCRIPTOR,MARSHALLER_LISTENER,MEDIA_TYPE,NAMESPACE_PREFIX_MAPPER,OBJECT_BUILDER,SESSION>).marshal(java.lang.Object, java.io.OutputStream, ABSTRACT_SESSION, DESCRIPTOR) line: 934 org.eclipse.persistence.oxm.XMLMarshaller(org.eclipse.persistence.internal.oxm.XMLMarshaller<ABSTRACT_SESSION,CHARACTER_ESCAPE_HANDLER,CONTEXT,DESCRIPTOR,MARSHALLER_LISTENER,MEDIA_TYPE,NAMESPACE_PREFIX_MAPPER,OBJECT_BUILDER,SESSION>).marshal(java.lang.Object, java.io.OutputStream) line: 877 org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(java.lang.Object, java.io.OutputStream) line: 496 org.glassfish.jersey.moxy.json.internal.ConfigurableMoxyJsonProvider(org.eclipse.persistence.jaxb.rs.MOXyJsonProvider).writeTo(java.lang.Object, java.lang.Class<?>, java.lang.reflect.Type, java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType, javax.ws.rs.core.MultivaluedMap<java.lang.String,java.lang.Object>, java.io.OutputStream) line: 957 org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(javax.ws.rs.ext.WriterInterceptorContext, javax.ws.rs.ext.MessageBodyWriter) line: 265 org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(javax.ws.rs.ext.WriterInterceptorContext) line: 250 org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed() line: 162 org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(javax.ws.rs.ext.WriterInterceptorContext) line: 106 org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed() line: 162 org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(javax.ws.rs.ext.WriterInterceptorContext) line: 86 org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed() line: 162 weblogic.jaxrs.server.internal.ChunkedOutputWriter.aroundWriteTo(javax.ws.rs.ext.WriterInterceptorContext) line: 65 org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed() line: 162 org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(java.lang.Object, java.lang.Class<?>, java.lang.reflect.Type, java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType, javax.ws.rs.core.MultivaluedMap<java.lang.String,java.lang.Object>, org.glassfish.jersey.internal.PropertiesDelegate, java.io.OutputStream, java.lang.Iterable<javax.ws.rs.ext.WriterInterceptor>) line: 1130 org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(org.glassfish.jersey.server.ContainerResponse) line: 711 org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(org.glassfish.jersey.server.ContainerResponse) line: 444 org.glassfish.jersey.server.ServerRuntime$Responder.process(org.glassfish.jersey.server.ContainerResponse) line: 434 org.glassfish.jersey.server.ServerRuntime$2.run() line: 329 org.glassfish.jersey.internal.Errors$1.call() line: 271 org.glassfish.jersey.internal.Errors$1.call() line: 267 org.glassfish.jersey.internal.Errors.process(java.util.concurrent.Callable<T>, boolean) line: 315 org.glassfish.jersey.internal.Errors.process(org.glassfish.jersey.internal.util.Producer<T>, boolean) line: 297 org.glassfish.jersey.internal.Errors.process(java.lang.Runnable) line: 267 org.glassfish.jersey.process.internal.RequestScope.runInScope(org.glassfish.jersey.process.internal.RequestScope$Instance, java.lang.Runnable) line: 317 org.glassfish.jersey.server.ServerRuntime.process(org.glassfish.jersey.server.ContainerRequest) line: 305 org.glassfish.jersey.server.ApplicationHandler.handle(org.glassfish.jersey.server.ContainerRequest) line: 1154 org.glassfish.jersey.servlet.WebComponent.serviceImpl(java.net.URI, java.net.URI, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 471 org.glassfish.jersey.servlet.WebComponent.service(java.net.URI, java.net.URI, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 425 org.glassfish.jersey.servlet.ServletContainer.service(java.net.URI, java.net.URI, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 383 org.glassfish.jersey.servlet.ServletContainer.service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 336 org.glassfish.jersey.servlet.ServletContainer.service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) line: 223 weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run() line: 286 weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run() line: 260 weblogic.servlet.internal.StubSecurityHelper.invokeServlet(javax.servlet.ServletRequest, javax.servlet.http.HttpServletRequest, weblogic.servlet.internal.ServletRequestImpl, javax.servlet.ServletResponse, javax.servlet.http.HttpServletResponse, javax.servlet.Servlet) line: 137 weblogic.servlet.internal.ServletStubImpl.execute(javax.servlet.ServletRequest, javax.servlet.ServletResponse, weblogic.servlet.internal.FilterChainImpl) line: 350 weblogic.servlet.internal.TailFilter.doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) line: 25 weblogic.servlet.internal.FilterChainImpl.doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse) line: 78 weblogic.servlet.internal.RequestEventsFilter.doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) line: 32 weblogic.servlet.internal.FilterChainImpl.doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse) line: 78 weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(weblogic.servlet.internal.ServletStub, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 3683 weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run() line: 3649 weblogic.security.acl.internal.AuthenticatedSubject.doAs(weblogic.security.subject.AbstractSubject, java.security.PrivilegedAction) line: 326 weblogic.security.service.SecurityManager.runAsForUserCode(weblogic.security.acl.internal.AuthenticatedSubject, weblogic.security.acl.internal.AuthenticatedSubject, java.security.PrivilegedAction<T>) line: 197 weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(weblogic.security.acl.internal.AuthenticatedSubject, java.security.PrivilegedAction, weblogic.security.acl.internal.AuthenticatedSubject) line: 203 weblogic.servlet.provider.WlsSubjectHandle.run(java.security.PrivilegedAction) line: 71 weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(weblogic.servlet.internal.ServletInvocationContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, boolean, boolean, boolean) line: 2433 weblogic.servlet.internal.WebAppServletContext.securedExecute(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, boolean) line: 2281 weblogic.servlet.internal.WebAppServletContext.execute(weblogic.servlet.internal.ServletRequestImpl, weblogic.servlet.internal.ServletResponseImpl) line: 2259 weblogic.servlet.internal.ServletRequestImpl.runInternal() line: 1691 weblogic.servlet.internal.ServletRequestImpl.run() line: 1651 weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run() line: 270 weblogic.invocation.ComponentInvocationContextManager._runAs(weblogic.invocation.ComponentInvocationContext, java.lang.Runnable) line: 348 weblogic.invocation.ComponentInvocationContextManager.runAs(java.security.Principal, weblogic.invocation.ComponentInvocationContext, java.lang.Runnable) line: 333 weblogic.work.LivePartitionUtility.doRunWorkUnderContext(java.lang.Runnable, weblogic.invocation.ComponentInvocationContext) line: 54 weblogic.work.PartitionUtility.runWorkUnderContext(java.lang.Runnable, weblogic.invocation.ComponentInvocationContext) line: 41 weblogic.work.ServerWorkManagerImpl(weblogic.work.SelfTuningWorkManagerImpl).runWorkUnderContext(weblogic.work.ExecuteThread, weblogic.work.WorkAdapter) line: 640 weblogic.work.ExecuteThread.execute(weblogic.work.WorkAdapter) line: 406 weblogic.work.ExecuteThread.run() line: 346 I believe I will now search for the way to use jackson on weblogic, there is simply no way that I am going to be working around this issue by pumping the class full of jaxB annotation and on top of that be writing XmlAdapters for this.Jackson can do all of this for free.That is why when needed, Jackson will writen the @class attribute with all the neded metadata for the class to deserialize.It simply cannot be this bad. Cannot be.Many thanks. 解决方案 Well,Weblogic is implementing JAX-RS via Jersey.According to the jersey documentation, it should be a simple matter of pumping a dependency into your deployment to do the swtich from Moxy to Jackson.E.g<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.26-b09</version> <scope>runtime</scope></dependency>See the following reference.https://jersey.github.io/documentation/latest/media.html#jsonSeems not to be so trivial, to do the switch, my weblogic behavior was still reflecting the usage of Moxy, even once I added the library on the jersey documentaiton. Perhaps I tried with the wrong version... I am not going to find this out today.Since quite honestly, my patience has reached its limit for this petty problem.I have decide to go with the flow. Leave Jersey to its default behavior let it Moxy. I will not get in the way.I find Moxy rather more verbose than jackson, and I do not particularly fancy having to be spreading around jaxb.properties files like mushrooms where folders containing rest DTOS. jaxb.properties example: javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactoryIn any case, right now I want consistency to exist between the outcome of a rest call on Weblogic and Wildfly. No way I am going to be writing if app server is Weblogic de-serialize it with A and if it is wildfly deserialize it with B. No way!So what I did was quite simple.Wildfly uses restEasy. And rest easy is easy! :)So i simply went to my web.xmlAnd pumped the following information:<context-param> <param-name>resteasy.providers</param-name> <param-value>org.eclipse.persistence.jaxb.rs.MOXyJsonProvider</param-value> </context-param> Thanks restEasy documentation, that was really helpful!Finally, since I always use EclipseLink instead of Hibernate, the eclipselink module is already active whend df I startup wildfly. No need to activate it via jboss-deployment descriptor.xml.However, the module was lacking sufficient metadata.I had to pump into the module "org.eclipse.persistence" main.xml the following dependency:<module name="javax.ws.rs.api" />That means my module looks as follows:<module xmlns="urn:jboss:module:1.3" name="org.eclipse.persistence"> <properties> <property name="jboss.api" value="private"/> </properties> <resources> <resource-root path="jipijapa-eclipselink-10.1.0.Final.jar"/> <resource-root path="eclipselink-2.6.4.jar"> <filter> <exclude path="javax/**" /> </filter> </resource-root> </resources> <dependencies> <module name="asm.asm"/> <module name="javax.api"/> <module name="javax.annotation.api"/> <module name="javax.enterprise.api"/> <module name="javax.persistence.api"/> <module name="javax.transaction.api"/> <module name="javax.validation.api"/> <module name="javax.xml.bind.api"/> <module name="org.antlr"/> <module name="org.dom4j"/> <module name="org.javassist"/> <module name="org.jboss.as.jpa.spi"/> <module name="org.jboss.logging"/> <module name="org.jboss.vfs"/> <!-- Add dependency on rest api --> <module name="javax.ws.rs.api" /> </dependencies></module>NOTE:Just be careful maintaining such information, you want to automate hacking these files because you will lose track of this as time goes by. Best is you create an installer for wildfly that given a vanilla zip does all your hacky tunings to the base metadata files, otherwise you are lost.In any case, now Wildfly is rendering the output of rest calls based on Moxy and not based on Jackson.This means I will have to refactor my rest client to be Moxy based, but quite honestly...I am out of energy to struggle against weblogic.I prefer Jackson, so much simpler and quicker to use, but hey... pick your battles right?Editing informaiton:some more information on weblogic:On Weblogic, the following configuration is effective.IF you write RestApplication class and override the public Map getProperties() you can add the following property:proprties.put("jersey.config.server.disableMoxyJson", true);And this will disable the Server behavior of using moxy and switch to jackson.This has not effect on wildfly since only weblogic uses jersey and wildfly uses resteasy. Finally, to make a rest client you would do:javax.ws.rs.client.ClientBuilder.newClient().register(Class.forName("org.glassfish.jersey.jackson.JacksonFeature")) 这篇关于Weblogic 12.2.1.2 - 如何调整对象Serializer以使用Jackson 2和jaxrs启用应用程序/ json端点的奇怪现象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-25 00:35