spring 如果存在默认构造函数,则Sping Boot 数据类不遵守@NonNull或@NotNull

6ie5vjzr  于 2023-02-03  发布在  Spring
关注(0)|答案(1)|浏览(95)

背景

我有一个数据类

@Data
public class Data {
    @lombok.NonNull
    private String name;
}

一个控制器

@MessageMapping("/data")
public void handleData(@Validated Data data) throws Exception {
    if (data.getName().compareTo("Alice") == 0) {
        logger.info("Alice is here!");
    }
}

和一个bean来配置jackson将布尔值转换为整数(True-〉1,False-〉0)

@Bean
ObjectMapper registerObjectMapper() {
    ObjectMapper mapper = new ObjectMapper();

    SimpleModule module = new SimpleModule("MyBoolSerializer");
    module.addSerializer(Boolean.class, new MyBoolSerializer());
    module.addDeserializer(Boolean.class, new MyBoolDeserializer());
    module.addSerializer(boolean.class, new MyBoolSerializer());
    module.addDeserializer(boolean.class, new MyBoolDeserializer());
    
    mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

    return mapper;
}

当我在没有设置name参数的情况下向/data发出请求时,Jackson会将其设置为null

org.springframework.messaging.converter.MessageConversionException: 
Could not read JSON: Cannot construct instance of `com.example.myapp.entity.Data`
(no Creators, like default constructor, exist): 
cannot deserialize from Object value (no delegate- or property-based Creator)

尝试修复

然后我把@NoArgsConstructor加到Data上。

@Data
@NoArgsConstructor   // <<<<
public class Data {
    @lombok.NonNull
    private String name;
}

现在,对/data的请求将导致NullPointerException。未对参数进行空值检查,并且if-statement正在运行。
我尝试将hibernate-validator@NotNull注解用于Data中的name属性,但结果是相同的:一米一米一。

问题

我对@NonNull@NotNull注解的看法是,它们有助于验证数据,这样我就不需要在控制器中手动验证它们(检查null、检查范围内等)。然而,它似乎只有在默认构造函数不存在时才有效。这是有意义的,因为在默认构造函数中不执行null检查(没有数据要验证...)。

    • 但它与我遇到的例外相矛盾**

可能有帮助的信息

我启用了amqp,它有自己的MessageConverter bean,该bean返回一个新的Jackson2JsonMessageConverter示例。

import org.springframework.amqp.support.converter.MessageConverter;
@Bean
MessageConverter jsonMessageConverter() {
    return new Jackson2JsonMessageConverter();
}

有什么想法吗?
顺便说一句,标题可能有点含糊或误导,但我真的不知道问题出在哪里。

wwwo4jvm

wwwo4jvm1#

我猜你正在jakarta-validation API中寻找@NotEmpty@NotNull,请考虑下面的示例。

import lombok.Data;
import javax.validation.constraints.NotEmpty;

@Data
public class Data {
    
    @NotEmpty(message="Name cannot be null or blank")
    private String name;
}

确认见

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
      <version>Your spring boot version</version>
</dependency>

相关问题