在 Weblogic JEE 7(版本 12.2.1.2)上,我发现理解应用程序服务器与 JAX-RS Web 服务的启用和配置相关的行为非常奇怪。
我试图理解的第一点是一个我觉得非常难以解释的现象。
在一个示例应用程序中,我正在测试一个简单的 jax-rs Web 服务,最初只有组件:
成分(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.");
}
}
这会适当地为您可能想要在部署中使用的所有其余端点启用基本上下文。
与 Wildfly 完全一样 - 100%。
所以这个组件没什么好说的。
然后我们进入“沼泽”,组件 B,我们的休息端点。
这个虚拟端点上有几个虚拟 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 constructed.");
}
@GET
@Path("/ping")
public BasicJsonResponseDto<String> ping() {
Instant date = Instant.now();
return new BasicJsonResponseDto<String>("Ping-service invoked successfully. " + date.toString());
}
}
我稍后会在底部详细介绍 DTO 类。
这里已经有讨论的要点了。
对我来说,讨论的第一点是类顶部的元数据注释,它声明我们希望将此端点传递回客户端 application/json。
但在我第一次写这个注释时,我实际上没有添加任何这样的注释。
因此,在我的第一次实现中,应用程序服务器正在向我返回回复。
第二步,当我添加注释说明其余端点将返回 applicaiton/json 时,weblogic 停止渲染任何抱怨以下内容的响应:
严重:找不到媒体类型 = application/json 的 MessageBodyWriter,
类型=类 com.jersey.jaxb.Todo,genericType=类
com.jersey.jaxb.Todo。
在野蝇上进行同样的实验,终点立即起作用,没有出现重大麻烦。
以下堆栈溢出线程给了我一个有效的答案:测试序列化 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>
问题解决了。
其余的网络服务恢复工作。
在 chrome 上我可以完美地控制 http 响应元数据。
现在有趣的是,当我部署相同的应用程序并删除杰克逊提供程序库时,其余端点继续工作,没有任何问题。
实际上,我无法再在我的环境中重现 weblogic 的抱怨,即我没有给他任何知道如何处理 application/json 回复的正文编写器。
所以,这是我的第一个问题?
有谁知道对于提供 application/json 的基本休息服务,其中示例应用程序不捆绑杰克逊库并且仅使用 jee7 api,weblogic 是否应该记录我引用的错误。
有没有人对这样一个事实有任何概念/解释:当我去掉依赖项时,事情就像人们通常从一开始就预期的那样工作......但在被迫谷歌搜索解决方案后却不像人们所预期的那样没有身体作家的问题吗?
对此我真的没有任何解释......
现在第二点是与我引用的 /ping API 上使用返回对象的类有关。
最初,该 endpoing API 返回一个纯“字符串”。
ping 消息没有被封装在任何类型的对象中。
当然,结果对象不是真正的 JSON 对象,返回对象只是一个“某个任意字符串值”。
所以这对于休息客户端来说当然是一个问题,它期望反序列化有效的 json,而不是获取对象或数组,而是获取管道上的纯原始数据。
因此,我随后进行了在支持 dto 对象下泵送 String 和 Integer 等原始类型的实验。
这是实现。
实施对于下一个问题很重要。
@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 + "]";
}
}
对于敏锐的眼睛来说,很明显,当通过这样的类传递对端点的响应对象时,“反序列化”逻辑根本不是一项微不足道的任务。
这个基本类型 Integer/String 的包装对象有一点有毒。
也就是说,我们将 ping 字符串注入的值 T 并不能帮助反序列化引擎找出期望读出的对象。
因此,从技术上讲,ping 服务对于客户端代码来说一点也不简单。
话虽如此,我现在在 Weblogic 和 Wildfly 上有两种截然不同的行为。
而不同之处必定与各自所使用的序列化技术直接相关。
当在 weblogic 上执行 ping 服务时,现在我得到的响应对象的形式如下:
{“value”:{“type”:“string”,“value”:“Ping 服务已成功调用。
2017-08-12T09:08:45.455Z"}}
因此,您会看到,无论 Weblogic 使用什么 ObjectMapper(我绝对没有配置),默认情况下都会泵入有关 T 值的附加元数据,即将其声明为字符串。
(a) 非常可爱的是,这不需要我的要求就完成了,但是在客户端,我需要创建一个 ObjectMapper 来反序列化,它可以解释相同的对象元数据。
最有可能的是,有一组足够的注释,例如 @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) 我已将最初使我的端点工作的“jackson-jaxrs-json-provider”依赖项注入到我的 pom.xml 中。
我查看了这个库的源代码,在我看来这个库试图负责 json 响应的渲染。
它确实有一个 CDI @Provide @Consumes(/) 产生(/),如果我启用调试器,我可以在部署过程中看到 jackson-jaxrs-json-provider 被调用。
我在 weblogic 中看不到发生的是此类的 ObjectMapper 被调用。
如果我无法覆盖现在负责的任何默认行为。
有人理解这种行为吗?
有没有办法拴住野兽并控制局势?
或者我是否必须将代码简化到这样的程度,即我的字符串包装对象被命名为“StringWrappedDto”,并且值字段被简化为字符串值。
我希望不会,但现在我正在为此苦苦挣扎。
现在,我们切换到Wildfly 10.1.0。
在 Wildfly 10.1.0 上,我的经验是事情进展得更符合预期。
(a) 如果您仅使用我提供的 RestApplication 和 Endpoint 部署 WAR。
一切开箱即用。
没有麻烦,没有无法渲染 application/json 的消息。
您无需控制任何配置即可开始工作。
(b) 例如,如果您想要覆盖 Json 的渲染行为,您可以定义自己的 ObjectMapper 提供程序。
例如。
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;
}
}
这里的这个人,如果你调试它,你可以看到每次调用 Ping 服务时都会调用它。
因此,如果您需要这种级别的控制,您可以负责如何序列化 json 响应。
总而言之,在 Wildfly 上,我得到的 JSON 响应正是我所期望的,如以下引用所示:
{“class”:“entrypoint.rest.BasicJsonResponse”,“value”:“Ping 服务
调用成功。 2017-08-12T16:42:13.788Z"}
我尝试在 jackson 2 中涉及数据序列化的几乎每个类上设置断点,但实际上 weblogic 上没有任何结果。
所以我非常确定,wlserver/modules 中的某些东西正在被使用。
任何人都知道如何强制宣布为战争依赖的 jackson2 用于序列化并杀死现在正在发生的任何默认行为?
--
现在渲染中发生的事情开始变得清晰起来。
我编写了以下单元测试作为实验:
@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);
}
单元测试的输出看起来很熟悉......
{
"value" : {
"type" : "string",
"value" : "Ping-service invoked successfully. 2017-08-12T19:33:05.834Z"
}
Oracle 正在使用 Moxy 来制作 json...
那么现在的问题是,我该如何让它使用 jackson2 呢?
我确信有办法。可能可以在球衣文档中找到,我相信默认情况下会使用 Moxy。
为了将来参考,我现在将发布一个有意义的调试堆栈跟踪。
我试图调试所有代码,但无法找出如何调试,因为当实现一直是 jersey + moxy 时,我总是试图在 Jackson 上设置断点。
这是这个问题的答案。
我出于世界上最荒谬的原因来到这个堆栈跟踪。
Moxy 开箱即用,无法反序列化为此 Web 服务生成的 JSON 对象。
有谁能理解这一点吗?
那个 moxy 正在 POJO 上序列化我的 som json,但是解组无法正确解组值字段?
所以这是堆栈跟踪:
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
我相信我现在将寻找在 weblogic 上使用 jackson 的方法,我根本无法通过注入充满 jaxB 注释的类并为此编写 XmlAdapters 来解决这个问题。
杰克逊可以免费完成这一切。
这就是为什么在需要时,Jackson 会编写 @class 属性,其中包含要反序列化的类所需的所有元数据。
事情不可能这么糟糕。不可能是。