我有以下Java Bean:
public class Something {
@NotBlank
private final String value;
@JsonCreator
public Something(@JsonProperty("value")final String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public boolean equals(final Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}
以及以下用于处理json序列化和反序列化的实用程序类
public class JsonUtils {
private final ObjectMapper objectMapper;
@Inject
public JsonUtils(final ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public <T> T jsonToObject(final String jsonString, final Class<T> classType) {
try {
return objectMapper.readValue(jsonString, classType);
} catch (IOException e) {
throw new JsonException(ErrorMessage.ERROR_PARSE_JSON_TO_OBJECT, e);
}
}
public <V> String objectToJson(final V objectToBeParsed) {
try {
return objectMapper.writeValueAsString(objectToBeParsed);
} catch (IOException e) {
throw new JsonException(ErrorMessage.ERROR_PARSE_OBJECT_TO_JSON, e);
}
}
}
我的对象映射器在这里配置
public class ParserModule extends AbstractModule {
@Provides
public ObjectMapper getObjectMapper() {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(WRITE_DATES_AS_TIMESTAMPS);
objectMapper.enable(ALLOW_NUMERIC_LEADING_ZEROS);
objectMapper.findAndRegisterModules();
objectMapper.registerModule(getSerializersModule());
objectMapper.registerModule(getDeserializerModule());
return objectMapper;
}
private SimpleModule getSerializersModule() {
final SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Something.class, new SomethingSerializer());
return simpleModule;
}
private SimpleModule getDeserializerModule() {
final SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(Something.class, new SomethingDeserializer());
return simpleModule;
}
}
最后,此JSON对象将是REST API响应主体中的返回值,但API规范要求仅包含“值”字段值的原始字符串。因此,如果我的事物的值为"hello world"
,它应该在响应正文中返回hello world
,而不是{"value":"hello world"}
。
该规范不是我定义的,我必须遵守,并且它不可能改变。
因此,我创建了以下序列化器和反序列化器,它们已在对象映射器中注册,如前所述
public class SomethingSerializer extends StdSerializer<Something> {
public SomethingSerializer() {
this(null);
}
public SomethingSerializer(final Class<Something> t) {
super(t);
}
@Override
public void serialize(final Something something, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeRawValue(something.getValue());
}
}
public class SomethingDeserializer extends StdDeserializer<Something> {
public SomethingDeserializer() {
this(null);
}
public SomethingDeserializer(final Class<?> t) {
super(t);
}
@Override
public Something deserialize(final JsonParser jsonParser, final DeserializationContext context) throws IOException {
return new Something(jsonParser.getCodec().readTree(jsonParser).toString());
}
}
现在我在某物对象中拥有的实际值不是"hello world"
,而是一个看起来像这样的字符串:01.something.this.that.org
。注意这里的前导零。
因此,每当我尝试反序列化这样的对象时:
Something result = jsonUtils.jsonToObject(response.getBody(), Something.class);
我得到一个例外:
JsonParseException: Invalid numeric value: Leading zeroes not allowed
at [Source: (String)"01.something.this.that.org"; line: 1, column: 2]
在Jackson的源代码中研究了这个异常之后,我发现有一个功能可以让我“跳过”这个异常,并且我以为我找到了解决方案,所以我将其添加到了对象映射器中:
objectMapper.enable(ALLOW_NUMERIC_LEADING_ZEROS);
现在我不再收到异常了,很酷。但是反序列化的字符串变为:1.something.this.that.org
。所以我回到第一场。
有什么办法吗?
1)开头的零没有例外
2)实际上保持前导零
谢谢。
编辑:
实际上,在添加允许前导零的功能之后,我的第一个测试是仅解析返回01
的{{1}}值,但是如果我尝试解析此处给出的示例字符串,我得到另一个例外:
1
所以我想我的问题确实是,我如何让杰克逊将原始字符串解释为实际的字符串,因为目前看来它似乎将其解释为数字。