如何解决阻止Jackson ObjectMapper自动toString格式的复合映射键
我正在使用com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString()
从Java POJO生成JSON。
我的一个对象-称为ResultSheet
-包含属性Map<ResultId,Integer> results
。 ResultId
代表(两个FK的)复合PK。
似乎ObjectMapper
在遇到ResultId
时意识到这不能直接用JSON表示,因为JSON映射键必须是字符串。因此,它改为输出toString()
中的ResultId
。 (在这种特殊情况下,它会以"42:43"
的形式生成一个字符串,但这仅仅是因为这恰好是toString()
的当前实现方式。)
如何阻止它执行此操作?当前的行为掩盖了以下事实:被编组的结构不能正确表示为JSON结构。还将当前的toString()
实现泄漏到我的Web服务的API中。
当用作映射键的值不是String
时,或者至少在转换为String
时,我会抛出异常告诉我。 (例如,我不太担心Long
版的toString()
键。)
我已经研究了SerializationFeature
设置,但似乎没有一个能解决这个问题。 https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/SerializationFeature.html
有没有办法防止这种情况?
是否可以以一般方式完成操作,即不仅针对特定类,而且在将来可能出现的任何情况下,都会添加新类,其中一些可能用作映射键?请注意,在这种情况下,将toString()
引发异常将是不可接受的。
解决方法
要解决此问题,您可以实现并注册自己的object S; type S = S.type
object K; type K = K.type
object I; type I = I.type
// or,heck
type S = 0
type K = 1
type I = 2
类。并覆盖modifyKeySerializer方法。实现总是可以返回引发异常的序列化程序。参见以下示例:
com.fasterxml.jackson.databind.ser.BeanSerializerModifier
上面的代码打印:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
public class JsonKeySerializerApp {
public static void main(String[] args) throws IOException {
SimpleModule keyExceptionSerializerModule = new SimpleModule();
keyExceptionSerializerModule.setSerializerModifier(new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifyKeySerializer(SerializationConfig config,JavaType valueType,BeanDescription beanDesc,JsonSerializer<?> serializer) {
// specify classes you want to allow to be serialized as keys
if (valueType.getRawClass().getPackage().getName().startsWith("java.")) {
return serializer;
}
return new JsonSerializer<Object>() {
@Override
public void serialize(Object value,JsonGenerator gen,SerializerProvider serializers) {
throw new UnsupportedOperationException("You can not serialize POJO as keys!");
}
};
}
});
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(keyExceptionSerializerModule);
Map<ResultId,Long> map = Collections.singletonMap(new ResultId(1,2),1L);
mapper.writeValue(System.out,map);
}
}
@AllArgsConstructor
@Data
class ResultId {
private int id1;
private int id2;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。