- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试实现 HL7 FHIR spec's assertion that JSON representing a FHIR model will not have empty objects nor empty arrays 。为了不让我的消费者的生活变得更加困难,我在反序列化期间没有严格执行这一点,但我想确保我的库生成的序列化 JSON 符合指定的要求。我正在使用 Java 和 Jackson ObjectMapper 将对象序列化为 JSON。我对编写自定义序列化器的理解是,无论您要转换为什么,该对象在某一时刻都表示为 JsonNode。
我想做的是在 JsonNode 退出序列化器时拦截它,对其进行一些调整(查找并删除空数组和对象),然后让它继续前进。我需要在无法调整 ObjectMapper 的环境中执行此操作,因为我无权访问它。此外,这个库中模型的复杂层次结构大量使用 Jackson 的默认序列化和注释等,我无法消除这一点。
如果我选择为基本类型定义自定义序列化器,比如说“资源”,那么我就会遇到问题,因为我仍然需要原始序列化器的输出才能生成修改后的输出。此外,这需要适应模型中各种类型可能已经存在的任何自定义序列化器。
我使用https://www.baeldung.com/jackson-call-default-serializer-from-custom-serializer对上述选项进行了相当多的了解最后一个选项是实现 BeanSerializerModifier,但我遇到了无法控制库使用者使用的 ObjectMapper 的问题。
示例 POJO(使用 Lombok 作为访问器):
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonIgnoreProperties(ignoreUnknown = true)
abstract class Resource {
private FhirString id;
private List<Extension> extension;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public abstract ResourceType getResourceType();
}
@Data
@Builder
class SomethingElse extends Resource {
FhirUri someProperty;
CodeableConcept someCode;
List<Reference> someReferences;
@Override
public ResourceType getResourceType() {
return ResourceType.SOMETHING_ELSE;
}
}
以及 SomethingElse 类的示例实例:
SomethingElse somethingElse = SomethingElse.builder()
.someProperty(FhirUri.from("some-simple-uri"))
.someCode(new CodeableConcept())
.someReference(List.of(new Reference()))
.build();
somethingElse.setId(FhirString.randomUuid());
somethingElse.setExtension(new ArrayList<>());
当我告诉任何映射器(或者,例如,使用 Spring 服务)将 SomethingElse 类映射到 JsonNode 时,我可能会得到空对象和数组,如下所示:
ObjectMapper mapper = getUntouchableMapper();
JsonNode somethingElseNode = mapper.valueToTree(somethingElse);
System.out.println(somethingElseNode.toString());
变成:
{
"resourceType": "SomethingElse",
"id": "00000000-0002-0004-0000-000000000000",
"someProperty": "some-simple-uri",
"someCode": {},
"someReferences": [{}],
"extension": []
}
根据 FHIR,这实际上应该是这样的:
{
"resourceType": "SomethingElse",
"id": "00000000-0002-0004-0000-000000000000",
"someProperty": "some-simple-uri"
}
总结
无论使用什么 ObjectMapper,如何保留已经存在的序列化机制,并以某种方式从 Jackson 序列化过程生成的传出 JSON 中删除空列表和对象?
编辑:我也尝试过@JsonInclude(JsonInclude.Include.NON_EMPTY)
,它确实省略了空列表实现。然而,该库中的绝大多数数据都是由序列化为映射和基元的 POJO 表示的,并且只有当它们直接由模型中的映射和基元表示时,此注释才有效。
最佳答案
解决方案是使用自定义的@JsonInclude
,即new in Jackson 2.9 。感谢@dai 让我重新认识这个功能。
在资源基类上,如下所示:
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = FhirJsonValueFilter.class)
class Resource implements FhirTypeInterface {
...
@Override
public boolean isEmpty() {
//Details omitted for simplicity
}
}
为了可见性,上面使用的界面:
interface FhirTypeInterface {
boolean isEmpty();
}
我对 FhirJsonValueFilter 的自定义定义实现了 JsonInclude.Include.NON_EMPTY
的所有功能,但还添加了用于检查 FHIR 类型实现的方法的功能(此实现与答案无关) )。
public class FhirJsonValueFilter {
@Override
public boolean equals(Object value) {
return !getWillInclude(value);
}
/**
* Returns true for an object that matched filter criteria (will be
* included) and false for those to omit from the response.
*/
public boolean getWillInclude(Object value) {
//Omit explicit null values
if (null == value) {
return false;
}
//Omit empty collections
if (Collection.class.isAssignableFrom(value.getClass())) {
return !((Collection) value).isEmpty();
}
//Omit empty maps
if (Map.class.isAssignableFrom(value.getClass())) {
return !((Map) value).isEmpty();
}
//Omit empty char sequences (Strings, etc.)
if (CharSequence.class.isAssignableFrom(value.getClass())) {
return ((CharSequence) value).length() > 0;
}
//Omit empty FHIR data represented by an object
if (FhirTypeInterface.class.isAssignableFrom(value.getClass())) {
return !((FhirTypeInterface) value).isEmpty();
}
//If we missed something, default to include it
return true;
}
}
请注意,自定义省略过滤器使用 Java 的 Object.equals 功能,其中 true 表示省略属性,并且我使用了第二种方法来减少此答案中的困惑。
关于java - Jackson:如何在序列化过程中对 JsonNode 进行后处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58311830/
我必须在 Python 中分析/可视化模拟(Simulink、EES)的结果。 平均我必须从结果文件中导入 40-100 个变量(每个变量是一个包含多个 thausend 行的向量):每个变量在 re
我有一个使用 glKit 运行的游戏,我想在每一帧渲染后使用着色器添加一些后期处理效果。 是否可以在 glKit 下执行此操作? 最佳答案 这是可能的。 您需要创建自己的屏幕外帧缓冲区对象和相关纹理。
我是 GPS 世界的新手。我需要知道如何使用 DGPS 进行后处理。我在网上找到了关于 DGPS、后处理等的定义,但是,找不到关于如何实际进行 DGPS 后处理的明确步骤。在搜索提供商时,我发现 CO
我正在研究从 Apache 切换到 Nginx 作为后端 Grails 应用程序前面的反向代理。我正在玩一些 URL 重写并且遇到了从我的后端发回的响应的问题。我可以处理位置 header 重写,但我
如何在 Assimp 中加载网格、编辑顶点,然后让 assimp 重新计算顶点并进行其他后处理? 导入器可以导入场景并支持一些标志,其中包括生成法线的标志。然而,在我加载网格之后,我稍微编辑了网格(添
我正在尝试实现来自 http://www.aftek.com/afteklab/aftek-RTMP-library.shtml 的库从 red5 服务器流式传输实时视频。 在服务器上,我正在使用 s
我在 Godot 中有一个项目可以在敌人上方渲染广告牌四边形。四边形(网格实例)是敌人节点的子节点。我只想将四边形渲染到视口(viewport)以进行后处理,但四边形需要在屏幕上具有与敌人相同的位置(
我正在设置一个服务器来使用 tesseract 进行大量自动 OCR,并且我想对结果进行一些后处理。 在理论方面有很多关于此的资源,但在实践方面我没有找到太多资源。 我想你可以做一些基本的事情,比如:
假设我有一个函数fancyParse,旨在获取服务器返回的响应并将其转换为其他内容。如果响应毫无意义,或者设置了特殊的“内部错误”标志,则该函数将抛出异常。 我想将此函数链接到 $.post 调用中以
我有一个带有 knockout 值的基本输入字段: 但是,我想在收到“mytext”的值后对我的 View 模型执行一些逻辑。最初我想到了某种后处理事件ala“valueUpdate”,但基本上我只
将 PostProcessEffectRenderer 的实现添加到 Unity 后处理堆栈后,该效果在 Unity 编辑器中完美运行,但未在构建的游戏中显示。 对构建质量的更改没有效果,使用最高质量
我有一堆相当冗长的 xml 文件,它们以某种方式命名,例如“verbosefile_*.xml”。我有一对 python 脚本,可以将这些 xml 文件转换为紧凑的 json 格式,反之亦然。目前我的
我需要对从包(包是共享对象文件)导入的函数进行多次调用。但是,每次我从这个包中调用函数时,我都需要执行一些预处理/后处理步骤。像这样的事情: import xyz prepare() xyz.foo(
我需要对从包(包是共享对象文件)导入的函数进行多次调用。但是,每次我从这个包中调用函数时,我都需要执行一些预处理/后处理步骤。像这样的事情: import xyz prepare() xyz.foo(
我的问题是是否有一种方法可以简单地发布处理 wicket HTML 响应? 我想做的是使用 Rhino (http://www.mozilla.org/rhino/) 和 jQuery 将一些 DOM
这是我要存储在我的 Realm 数据库中的类。在构建应用程序时,它会抛出 “错误:如果声明了自定义构造函数,则必须声明不带参数的默认公共(public)构造函数。” 但在使用 realm 之前没问题
我正在尝试组合 SMAA和 SSAO在我的 THREE.EffectComposer 中,如下所示: this.composer = new THREE.EffectComposer(this.ren
我正在尝试为我的应用程序开发直接文件上传到 S3。我正在关注 github 教程,一切都差不多,但是在尝试进行后期处理时收到错误消息。 我做了以下事情: 我有一个名为 clip.rb 的 active
我已经开始使用 C++ 并在 projecteuler.net 上摆弄一些问题。 我在回答问题 #4,这是我的代码: 判断数字是否为回文的算法: bool forwardCheck(long posP
我是一名优秀的程序员,十分优秀!