在 Spring Boot / Jackson 中防止原始字符串转换
Prevent Primitive To String Conversion in SpringBoot / Jackson
我们写了一个Springboot Rest Service,它在内部使用Jackson 序列化/反序列化Json Rest APIs 的输入/输出。
对于 API 输入/输出,我们不希望基元与字符串之间的类型转换。
我们已使用
禁用字符串到原始类型的转换
spring.jackson.mapper.allow-coercion-of-scalars=false
但是仍然允许从 Primitive 到 String 的转换。
例如
"name": 123,
从API仍然反序列化为"123"
,Java这里name
的数据类型是String
。
我们已经阅读了 Spring 文档的 Customize the Jackson ObjectMapper 部分,看起来这些枚举中没有任何东西可以使用。
有没有办法在不编写自定义 ObjectMapper / Deserializer 的情况下实现这一点?
我们没有找到实现此目的的任何配置 属性,最终采用了 Michał Ziober 发布的解决方案。
package xyz;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.core.JsonToken;
import java.io.IOException;
public class StrictStringDeserializer extends StringDeserializer {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonToken token = p.currentToken();
if (token.isBoolean()
|| token.isNumeric()
|| !token.toString().equalsIgnoreCase("VALUE_STRING")) {
ctxt.reportInputMismatch(String.class, "%s is not a `String` value!", token.toString());
return null;
}
return super.deserialize(p, ctxt);
}
}
POJO Class
public class XyzAbc {
// ...
@JsonDeserialize(using = StrictStringDeserializer.class)
private String name;
// ...
}
我们写了一个Springboot Rest Service,它在内部使用Jackson 序列化/反序列化Json Rest APIs 的输入/输出。
对于 API 输入/输出,我们不希望基元与字符串之间的类型转换。
我们已使用
禁用字符串到原始类型的转换spring.jackson.mapper.allow-coercion-of-scalars=false
但是仍然允许从 Primitive 到 String 的转换。
例如
"name": 123,
从API仍然反序列化为"123"
,Java这里name
的数据类型是String
。
我们已经阅读了 Spring 文档的 Customize the Jackson ObjectMapper 部分,看起来这些枚举中没有任何东西可以使用。
有没有办法在不编写自定义 ObjectMapper / Deserializer 的情况下实现这一点?
我们没有找到实现此目的的任何配置 属性,最终采用了 Michał Ziober 发布的解决方案。
package xyz;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.core.JsonToken;
import java.io.IOException;
public class StrictStringDeserializer extends StringDeserializer {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonToken token = p.currentToken();
if (token.isBoolean()
|| token.isNumeric()
|| !token.toString().equalsIgnoreCase("VALUE_STRING")) {
ctxt.reportInputMismatch(String.class, "%s is not a `String` value!", token.toString());
return null;
}
return super.deserialize(p, ctxt);
}
}
POJO Class
public class XyzAbc {
// ...
@JsonDeserialize(using = StrictStringDeserializer.class)
private String name;
// ...
}