- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在研究 Jackson
配置,我想知道是否有任何选项可以反序列化不同类型的字段模式。
例如,我有一个对象:
class DeserializeIt {
String fieldOne;
String fieldOneAndHalf;
String fieldTwo;
String fieldThree;
String fieldFour;
//getters setters etc.
}
我有以下 JSON
有效负载:
{
"fieldOne" : "value1",
"field_ONE-and_Half": "value15",
"FIELD_TWO": "value2",
"FIELD_THREE" : "value3",
"field_four": "value4"
}
我想将所有这些字段名称反序列化为驼峰式大小写,无一异常(exception)。
我尝试创建自定义 PropertyNamingStrategy
但它从另一个方向进行:它不会将分隔字段转换为驼峰式大小写,而是尝试转换对象字段并在解析的字符串中搜索它们。
由于我无法传递可能的字符串列表而不是一个变体(fieldOne
可以变为 field-one
、field_one
、field-ONE
等),因此这不起作用。
你知道我还可以配置什么来实现如此轻松的反序列化吗?
最佳答案
我们需要扩展com.fasterxml.jackson.databind.deser.BeanDeserializerModifier
和com.fasterxml.jackson.databind.deser.BeanDeserializer
来反序列化POJO
类。下面的解决方案取决于您使用的版本
,因为我从基类复制了一些代码,该代码尚未准备好拦截额外的功能。如果您的 POJO
类没有任何额外的配置,vanillaDeserialize
方法将被调用,我们将尝试改进该方法。
在其他情况下,您需要调试此解串器并根据需要更新其他位置。以下解决方案使用版本 2.9.8
.
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
SimpleModule relaxedModule = new SimpleModule();
relaxedModule.setDeserializerModifier(new RelaxedBeanDeserializerModifier());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(relaxedModule);
System.out.println(mapper.readValue(jsonFile, DeserializeIt.class));
}
}
class RelaxedBeanDeserializerModifier extends BeanDeserializerModifier {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
JsonDeserializer<?> base = super.modifyDeserializer(config, beanDesc, deserializer);
if (base instanceof BeanDeserializer) {
return new RelaxedBeanDeserializer((BeanDeserializer) base);
}
return base;
}
}
class RelaxedBeanDeserializer extends BeanDeserializer {
private Map<String, String> properties = new HashMap<>();
public RelaxedBeanDeserializer(BeanDeserializerBase src) {
super(src);
_beanProperties.forEach(property -> {
properties.put(property.getName().toLowerCase(), property.getName());
});
}
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
// common case first
if (p.isExpectedStartObjectToken()) {
if (_vanillaProcessing) {
return vanillaDeserialize(p, ctxt, p.nextToken());
}
// 23-Sep-2015, tatu: This is wrong at some many levels, but for now... it is
// what it is, including "expected behavior".
p.nextToken();
if (_objectIdReader != null) {
return deserializeWithObjectId(p, ctxt);
}
return deserializeFromObject(p, ctxt);
}
return _deserializeOther(p, ctxt, p.getCurrentToken());
}
protected Object vanillaDeserialize(JsonParser p, DeserializationContext ctxt, JsonToken t) throws IOException {
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
// [databind#631]: Assign current value, to be accessible by custom serializers
p.setCurrentValue(bean);
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
String propName = p.getCurrentName();
do {
String relaxedName = getRelaxedName(propName);
String mappedName = properties.get(relaxedName);
defaultImplementation(p, ctxt, bean, mappedName);
} while ((propName = p.nextFieldName()) != null);
}
return bean;
}
private void defaultImplementation(JsonParser p, DeserializationContext ctxt, Object bean, String propName) throws IOException {
p.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
prop.deserializeAndSet(p, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
return;
}
handleUnknownVanilla(p, ctxt, bean, propName);
}
private String getRelaxedName(String name) {
return name.replaceAll("[_\\-]", "").toLowerCase();
}
}
上面的代码打印:
DeserializeIt{fieldOne='value1', fieldOneAndHalf='value15', fieldTwo='value2', fieldThree='value3', fieldFour='value4'}
另请参阅:
关于java - "Relaxed"Jackson 的字段名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55846834/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 5 年前。
我需要使用 java 编写一个程序来完成作业。程序需要在给定坐标处输出一个给定半径的圆。到目前为止,我已经创建了一个嵌套在另一个 for 循环内的 for 循环,以扫描所有坐标并在坐标满足圆方程时打印
在 Dijkstra 的最短路径算法和其他算法中,检查一条边以查看它是否提供到节点的更好路径被称为放松边。为什么叫放松? 最佳答案 一般来说,放松是进行减少约束的改变。当 Dijkstra 算法检查一
我正在研究 Jackson 配置,我想知道是否有任何选项可以反序列化不同类型的字段模式。 例如,我有一个对象: class DeserializeIt { String fieldOne;
我的问题和标题一样。在计算图的最短路径时,经常会用到一个叫做relax的操作。很容易理解为什么使用这个操作,但这个名字的含义对我来说是个谜。“放松”是什么意思? 这里是用伪代码编写的Dijkstra示
我需要 (Ref)UnwindSafe ty,和Cell没有提供,所以我使用 AtomicBool相反。 是否保证在单线程上下文中更新到一个 Rc使用 Relaxed (商店)订购在其他 Rc 上立即
documentation对于 scipy.integrate.ode.integrate 没有描述 relax 参数的作用。它有什么作用?打开源代码显示它是一个 bool 标志,但我得到的只有这些。
我目前正在实现一些图形算法,我想要一个具有斐波那契堆或松弛堆复杂性的容器(具体来说,我想要至少 O(logN) 用于推送和弹出,O(1) 用于reduce_key)。 如果可能的话(开发和测试的开销和
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 5 年前。
我正在编写一个放松 NG 模式来验证一些 XML 文件。对于大多数元素,有一些必需的属性,并且此 XML 模式的实例还可以添加任何额外的属性。 例如,这是一个有效的文档: 在我的 Rel
我想使用 Relax NG 紧凑模式。我是否按照 XSD 的方式在 xsi:schemaLocation 中指定 .rnc 文件?我不想将 Relax NG 转换为 XSD,因为 XSD 的局限性对我
我正在尝试将 Relax.js 与 React 一起使用,但无法理解如何使用它。我只能找到https://www.npmjs.com/package/rellax#target-node .在那个链接
这个问题在这里已经有了答案: Chrome is not displaying my emoji correctly (2 个回答) 9 个月前关闭。 我正在尝试为网站信使显示表情符号,除 Smili
我用过this python 三角形模块,用于从一组随机二维点坐标创建三角形网格。我现在想要的是,在不添加任何点或拆分三角形的情况下,修改三角形点的位置,使三角形之间的间距更大,使它们等边或更接近等边
是否有可能在 RELAX NG Compact Syntax 中以定义正则表达式的方式为 text 定义一个模式,或者,可能更简单的正则语法变体只有“或”和字符类/排序操作? 基本上,我想将一个属性声
解析“宽松”JSON但避免邪恶eval的最简单方法是什么? 以下抛出错误: JSON.parse("{muh: 2}"); 因为正确的 JSON 应该引用键:{"muh": 2} 我的用例是一个简单的
Http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync。假设x最初为0:。断言不能失败。。我不明白为什么不能对这两个加载重新排序,以便在y之前读取z,这可以得到
Http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync。假设x最初为0:。断言不能失败。。我不明白为什么这两个加载不能被重新排序,这样z在y之前被读取,这可以给
Http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync。假设x最初为0:。断言不能失败。。我不明白为什么不能对这两个加载重新排序,以便在y之前读取z,这可以得到
在只有 1 行的关系 X 中 X.A=null X.B= "blahblah" 现在我想做的是: Y = FILTER X BY A != B ; 我想说的是,由于 A 为空而 B 不为空,因此条件应
我是一名优秀的程序员,十分优秀!