gpt4 book ai didi

java - JSON 序列化跳过子元素

转载 作者:行者123 更新时间:2023-11-30 06:07:41 25 4
gpt4 key购买 nike

我正在运行 payara 微型服务器,并且在序列化对象时遇到一些困难。

根对象有一个子对象,其类型为AB extends A。问题是它总是序列化为 json,就好像它是 A 类型,即没有 B 类型的属性被序列化。

我在返回 Response 对象后立即检查了该对象是否正确。

pom.xml 如下所示:

<build>
<finalName>profile</finalName>

<plugins>
<plugin>
<groupId>fish.payara.maven.plugins</groupId>
<artifactId>payara-micro-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<goals>
<goal>bundle</goal>
<goal>start</goal>
</goals>
</execution>
</executions>
<configuration>
<payaraVersion>4.1.2.173</payaraVersion>
<useUberJar>true</useUberJar>
<deployWar>false</deployWar>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile-bom</artifactId>
<version>1.1.0</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.20</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1212</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
</dependencies>

我想也许我应该更改为org.glassfish.jersey.media.jersey-media-json-jackson,也许这会有所帮助,但后来我得到了这个异常在不在 Activity 的 Jersey 错误范围内运行的代码中检测到 HK2 故障。

所以我现在不太确定该怎么做。有没有办法配置 com.sun.jersey.jersey-json 解析器,或者我应该放弃它并尝试强制 jersey-media-json-jackson > 在那里?

编辑:我已经意识到payara默认使用MOXy json,但问题仍然相同

为了展示一些示例,我有这个稍微缩短的代码:

public class CategoryDTO {
private String name;
private List<QuestionDTO> questions;
}

public class QuestionDTO {
private String id;
}

public class QuestionAdminDTO extends QuestionDTO {
private String comment;
}

当它被序列化时,我得到

{
"name":"some name",
"questions":[
{
"id":"some id"
}
]
}

但我希望 comment 应该像这样包含

{
"name":"some name",
"questions":[
{
"id":"some id",
"comment":"some comment"
}
]
}

经过更多测试后,如果我尝试立即编码(marshal) QuestionDTO 对象,它会起作用,但如果它是嵌套的,则不起作用

我的应用程序配置了一个 /webapp/WEB-INF/glassfish-web.xml 文件,如下所示

<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD
GlassFish Application Server 3.1 Servlet 3.0//EN"
"http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
<session-config>
<session-manager/>
</session-config>
<class-loader delegate="false"/>
</glassfish-web-app>

以及“自定义”Application 类:

@ApplicationPath("/api")
public class RestApplication extends Application {

public RestApplication() {
Swagger swagger = new Swagger();
swagger.securityDefinition("JWT_AUTHORIZATION", new ApiKeyAuthDefinition("access_token", In.HEADER));
new SwaggerContextService().updateSwagger(swagger);

BeanConfig beanConfig = new BeanConfig();
beanConfig.setDescription("profile");
beanConfig.setTitle("Profile");
beanConfig.setVersion("1.0-SNAPSHOT");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setBasePath("/profile/api");
beanConfig.setResourcePackage("se.profile");
beanConfig.setScan(true);
}
}

添加 jackson 时得到的堆栈跟踪

[2018-06-21T10:37:26.526+0200] [] [WARNING] [] [org.glassfish.jersey.internal.Errors] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1529570246526] [levelValue: 900] [[
The following warnings have been detected: WARNING: HK2 failure has been detected in a code that does not run in an active Jersey Error scope.
WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 1
javax.enterprise.inject.CreationException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.jboss.weld.security.NewInstanceAction.run(NewInstanceAction.java:33)
at java.security.AccessController.doPrivileged(Native Method)
at org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:40)
at org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:50)
at org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:90)
at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:127)
at org.jboss.weld.injection.ConstructorInjectionPoint.invokeAroundConstructCallbacks(ConstructorInjectionPoint.java:92)
at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:78)
at org.jboss.weld.injection.producer.AbstractInstantiator.newInstance(AbstractInstantiator.java:28)
at org.jboss.weld.injection.producer.BasicInjectionTarget.produce(BasicInjectionTarget.java:112)
at org.jboss.weld.injection.producer.BeanInjectionTarget.produce(BeanInjectionTarget.java:180)
at org.glassfish.jersey.ext.cdi1x.internal.AbstractCdiBeanHk2Factory$2.getInstance(AbstractCdiBeanHk2Factory.java:139)
at org.glassfish.jersey.ext.cdi1x.internal.AbstractCdiBeanHk2Factory._provide(AbstractCdiBeanHk2Factory.java:91)
at org.glassfish.jersey.ext.cdi1x.internal.GenericCdiBeanHk2Factory.provide(GenericCdiBeanHk2Factory.java:63)
at org.jvnet.hk2.internal.FactoryCreator.create(FactoryCreator.java:153)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:487)
at org.jvnet.hk2.internal.PerLookupContext.findOrCreate(PerLookupContext.java:70)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2126)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:777)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:740)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:710)
at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:385)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:342)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:392)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:369)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1495)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1294)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5303)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5548)
at com.sun.enterprise.web.WebModule.start(WebModule.java:522)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:900)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:684)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2057)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1703)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:294)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:357)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:501)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:220)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:488)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:544)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:540)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:539)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:570)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:562)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:561)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1469)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:111)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1851)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1727)
at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:134)
at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:149)
at fish.payara.micro.impl.PayaraMicroImpl.deployAll(PayaraMicroImpl.java:1377)
at fish.payara.micro.impl.PayaraMicroImpl.bootStrap(PayaraMicroImpl.java:993)
at fish.payara.micro.impl.PayaraMicroImpl.main(PayaraMicroImpl.java:186)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at fish.payara.micro.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at fish.payara.micro.boot.loader.Launcher.launch(Launcher.java:107)
at fish.payara.micro.boot.loader.Launcher.launch(Launcher.java:70)
at fish.payara.micro.boot.PayaraMicroLauncher.main(PayaraMicroLauncher.java:79)
at fish.payara.micro.PayaraMicro.main(PayaraMicro.java:361)
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/annotation/JsonMerge
at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector.<clinit>(JacksonAnnotationIntrospector.java:50)
at com.fasterxml.jackson.databind.ObjectMapper.<clinit>(ObjectMapper.java:291)
at io.swagger.util.ObjectMapperFactory.create(ObjectMapperFactory.java:35)
at io.swagger.util.ObjectMapperFactory.createJson(ObjectMapperFactory.java:23)
at io.swagger.util.ObjectMapperFactory.createJson(ObjectMapperFactory.java:19)
at io.swagger.util.Json.mapper(Json.java:13)
at io.swagger.jaxrs.DefaultParameterExtension.<init>(DefaultParameterExtension.java:50)
at io.swagger.jaxrs.ext.SwaggerExtensions.<clinit>(SwaggerExtensions.java:36)
at io.swagger.jaxrs.utils.ReaderUtils.collectParameters(ReaderUtils.java:123)
at io.swagger.jaxrs.utils.ReaderUtils.collectFieldParameters(ReaderUtils.java:96)
at io.swagger.jaxrs.Reader.read(Reader.java:291)
at io.swagger.jaxrs.Reader.read(Reader.java:175)
at io.swagger.jaxrs.config.BeanConfig.scanAndRead(BeanConfig.java:242)
at io.swagger.jaxrs.config.BeanConfig.setScan(BeanConfig.java:221)
at se.profile.RestApplication.<init>(RestApplication.java:30)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:119)
... 66 more
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.annotation.JsonMerge
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1655)
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1501)
... 86 more

]]

最佳答案

最简单的解决方案是使用 Jackson。 MOXy 基于 JAXB 规则,在某些情况下可能会变得非常复杂(包括使用继承)。 jackson 只是工作。

只需添加 Jackson 依赖项(在提供的范围内,因为 Payara 已经具有依赖项)并向应用程序注册 JacksonFeature

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.25.1</version>
<scope>provided</scope>
</dependency>

我看不到您如何配置应用程序,因此无法建议注册 JacksonFeature 的适当方法。如果您不知道如何执行此操作,可以使用应用程序配置更新您的帖子,也可以仅搜索注册方式。

更新

要在 Application 类中注册 JacksonFeature,您可以使用属性

public class RestAppication extends Application {

@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashSet<>();

String classnames = JacksonFeature.class.getName();
props.put("jersey.config.server.provider.classnames", classnames);
props.put("jersey.config.disableMoxyJson", true);
return props;
}
}

如果您遇到 Jackson 依赖项冲突,这可能是在使用 Swagger(将 Jackson 引入)时发生的,您可以将 Jackson 从 Swagger 中排除,因为服务器应该已经具有依赖项

<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.20</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<exclusion>
</exclusions>
</dependency>

关于java - JSON 序列化跳过子元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50950697/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com