我在使用Jackson1.9.13(和Jackson2.5.0)进行序列化/反序列化时遇到了一个问题,现在已经解决了几天了,没有任何成功。
我的目标是使用@jsonanygetter&@jsonanysetter,我想动态地计算对象是否应该写入输出。我有一个用ObjectMapper序列化的JSON定义(并检查是否应该包含对象),然后将对象转换回字符串。
为此,我使用了一个“HidableSerializer”,它在序列化过程中很有效,但在将对象转换回字符串时就不行了。
如果没有@jsonanysetter/-getter或“hidableSerializer”,每个东西都能正常工作,但不能两者一起工作。
为什么这不起作用?我怎样才能解决这个问题呢?欢迎更好的方法!
堆栈跟踪如下所示:
堆栈跟踪
org.codehaus.jackson.map.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: ch.hasselba.Test["[anySetter]"])
null
at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218)
at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183)
at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140)
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at ch.hasselba.HidableSerializer.serialize(HidableSerializer.java:29)
at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:2575)
at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:2097)
at ch.hasselba.Demo.main(Demo.java:54)
Caused by: java.lang.NullPointerException
at org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:243)
at org.codehaus.jackson.map.ser.AnyGetterWriter.getAndSerialize(AnyGetterWriter.java:41)
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:154)
... 7 more
package ch.hasselba;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.introspect.BasicBeanDescription;
import org.codehaus.jackson.map.module.SimpleModule;
import org.codehaus.jackson.map.ser.BeanSerializerModifier;
public class Demo {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
// register the module
Version version = new Version(1, 0, 0, "SNAPSHOT");
mapper.registerModule(new SimpleModule("HidableModule", version) {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addBeanSerializerModifier(new BeanSerializerModifier() {
@SuppressWarnings("unchecked")
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BasicBeanDescription desc,
JsonSerializer<?> serializer) {
if (IHidable.class.isAssignableFrom(desc.getBeanClass())) {
return new HidableSerializer<Object>((JsonSerializer<Object>) serializer);
}
return serializer;
}
});
}
});
// the data
String content = "{ \"foo\": \"bar\" }";
// build the Object
Test test = null;
try {
test = mapper.readValue(content, Test.class);
} catch (Exception e) {
e.printStackTrace();
}
// and now convert it back to a String
String data = null;
try {
data = mapper.writeValueAsString(test);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println( data );
}
}
测试类
package ch.hasselba;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.codehaus.jackson.annotate.JsonAnyGetter;
import org.codehaus.jackson.annotate.JsonAnySetter;
public class Test implements IHidable {
private Map<String, Object> others = new ConcurrentHashMap<String, Object>();
@JsonAnyGetter
public Map<String, Object> getOthers() {
return this.others;
}
@JsonAnySetter
public void addOther(final String name, final Object value) {
this.others.put(name, value);
}
@Override
public boolean isHidden() {
return false;
}
}
可隐藏序列化程序
package ch.hasselba;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
public class HidableSerializer<T> extends JsonSerializer<T> {
private JsonSerializer<T> defaultSerializer;
public HidableSerializer(JsonSerializer<T> serializer) {
defaultSerializer = serializer;
}
@Override
public void serialize(T value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
if( value instanceof IHidable ){
IHidable hidableValue = (IHidable) value;
if( hidableValue.isHidden() )
return;
}
defaultSerializer.serialize(value, jgen, provider);
}
}
IhidableInterface
package ch.hasselba;
public interface IHidable {
boolean isHidden();
}
问题是您在HidableSerializer中使用的defaultSerializer实例是一个ResolvableSerializer(BeanSerializer),但是当您将它包装到modifySerializer()方法中的JsonSerializer(HidableSerializer)中时,它的resolve()方法将永远不会被调用,并且无法正确初始化。
如果尝试将以下行添加到HidableSerializer.serialize()方法:
...
((ResolvableSerializer)defaultSerializer).resolve(provider);
defaultSerializer.serialize(value, jgen, provider);
...
它应该能奏效。
如果这对您有效,一个更持久的解决方案是让您的HidableSerializer实现ResolvableSerializer本身,并将resolve()委托给defaultSerializer,如下所示:
@Override
public void resolve(SerializerProvider serializerProvider) throws JsonMappingException {
if(defaultSerializer instanceof ResolvableSerializer) {
((ResolvableSerializer)defaultSerializer).resolve(serializerProvider);
}
}
我使用的是JAVA 1.6和Jackson 1.9.9我有一个枚举 我添加了一个@jsonValue,这似乎完成了它将对象序列化为:
我对解析json有一个问题。它有一个日期为exapmle-"2014-01-07"。当它解析并成为createUserRequest.getBirthday()时,它包含-"2014-01-07T04:00:00.000 04:00"。我需要它在createUserRequest对象中,然后我会用另一个对象断言它。问题是如何得到“2014-01-07”? 在CreateUserRequest中,我
问题内容: 我无法找出使用杰克逊实现自定义序列化/反序列化的正确方法。我有很多类(〜50),它们带有应被序列化/反序列化而不是原始的原始字段。喜欢: 所有序列化和反序列化都非常相似,我只需要在整数之后添加一个后缀(C,页面,米等)。 一种简单的方法是在每个这样的字段中添加一对/ 注释并实现它们。但是我最终会得到100个 非常相似的 序列化器/反序列化器。 我想到了添加自定义注释的各个领域,说或,这
可以序列化/反序列化< code >映射吗 在这种特殊情况下,我知道总是,和 - 第三方类(我有序列化器和反序列化器),其他值是盒装原语。 有可能和杰克逊做这样的事吗?使用MapSerializer/MapDeserializer可以做到这一点吗?(我找不到任何例子)
我在试着读我的。json文件。Is是一个车辆存储类。 这是错误: com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造的实例(尽管至少存在一个Creator):无法构造的实例(尽管至少存在一个Creator):没有字符串参数构造函数/工厂方法来从[Source:(File); line: 1,列: 1]处的字符串值反序列化
I'va是一个OID接口,可以由许多具体类型实现: 现在我有一个具有两个字段的对象,一个使用抽象接口类型(OID)定义,另一个使用具体类型(MyOID)定义 我想使用jackson以不同的方式序列化/反序列化字段,无论它们是使用抽象接口类型还是具体类型定义的: 注意,被序列化,包括类型信息(多态序列化),而被序列化为文本 为此,我将OID接口注释为: 并为每个具体类型分配了类型id: 最后,对容器