繁体   English   中英

将字符串数据类型限制为仅用于 Spring 引导 2.4 (Jackson) 中的请求正文的字符串类型

[英]Restrict string data type to only string types for request body in Spring boot 2.4 (Jackson)

我创建了我的请求 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"
}

这是我的 controller

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

预期:抛出一些错误

实际:通过 jackson 将userIdtrue值转换为字符串。

请让我知道有没有办法实现预期的行为

jackson NumberDeserializers.BooleanDeserializer被编程为将 boolean 转换为字符串。

我们可以用我们的重写反序列化器并阻止转换并引发异常。

我可以给你一个例子,你尝试将它实施到你的问题陈述中。

  1. 创建 boolean 反序列化 class

    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;
        }
    }

  1. 现在将反序列化器注入我们的应用程序

    @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);
         }
     }

默认情况下, 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;

也可以看看:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM