在springboot2.4(jackson)中将字符串数据类型限制为请求主体的字符串类型

6tdlim6h  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(383)

我创建了我的请求pojo如下

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Notification {

    @NotNull
    private String clientId;
    private String userId;  
    @NotNull
    private String requestingService;
    @NotNull
    private String message;
    @NotNull
    private String messageType;

当我发送如下请求正文时,它工作正常。

{
   "clientId":"9563",
    "userId":"5855541",
    "requestingService":"cm-dm-service",
    "message":"Document Created",
    "messageType":"user-msg"
}

但当我像下面一样

{
   "clientId":"9563",
    "userId":true,
    "requestingService":"cm-dm-service",
    "message":"Document Created",
    "messageType":"user-msg"
}

这是我的控制器

public ResponseEntity<Status> createNotification(@RequestBody @Valid Notification notification,
            BindingResult bindingResult, HttpServletRequest request) throws AppException {

应为:抛出一些错误
实际值:jackson将userid的真值转换为字符串。
请告诉我有没有办法达到预期的效果

eoigrqb6

eoigrqb61#

Jackson NumberDeserializers.BooleanDeserializer 编程将布尔值转换为字符串。
我们可以用我们的反序列化程序覆盖反序列化程序,防止转换并引发异常。
我可以给你举个例子,你试着把它落实到你的问题陈述中。
创建布尔反序列化类

public class MyDeser extends JsonDeserializer {
        @Override
        public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            JsonToken t = p.getCurrentToken();
            if (t.isBoolean()) {
                throw new Exception();
            }
            else if (t.isNumeric()) {
                throw new Exception();
            }
            else if (t == JsonToken.VALUE_STRING) {
                return p.getValueAsString();
            }
            return null;
        }
    }

现在将反序列化程序注入到我们的应用程序中

@SpringBootApplication
     @Configuration
     public class Application {
         @Bean
         public SimpleModule injectDeser() {
             return new SimpleModule().addDeserializer(String.class, new MyDeser());
         }
         public static void main(String[] args) {
             SpringApplication.run(Application.class, args);
         }
     }
6kkfgxo0

6kkfgxo02#

默认情况下, com.fasterxml.jackson.databind.deser.std.StringDeserializer 接受标量值。在这种情况下,可以实现自定义反序列化程序并引发异常:

class StrictStringDeserializer extends StringDeserializer {
    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonToken token = p.currentToken();
        if (token.isScalarValue()) {
            ctxt.reportInputMismatch(String.class, "%s is not a `String` value!", token.toString());
            return null;
        }
        return super.deserialize(p, ctxt);
    }
}

要注册它,请使用 SimpleModule :

SimpleModule strictModule = new SimpleModule();
strictModule.addDeserializer(String.class, new StrictStringDeserializer());

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(strictModule);

如何做到这一点 Spring 阅读:定制jackson objectmapper。
如果只想更改一个字段: userId 使用 JsonDeserialize 注解:

@JsonDeserialize(using = StrictStringDeserializer.class)
private String userId;

另请参见:
在spring中,默认情况下是否可以对类型使用自定义序列化程序/反序列化程序?

相关问题