一文让你明白@RequestBody接收不到boolean值的原因

本文探讨了boolean和Boolean的区别,指出在容器使用场景、toString/valueOf转换和JPA中的选择。同时揭示了前后端开发中boolean参数接收问题的解决方案,通过@JsonProperty调整属性名。

一、boolean和Boolean的区别和使用场景

  1. boolean是基本数据类型,Boolean是它的封装类,和其他类一样,有属性有方法。他们的关系其实是:Boolean 是boolean 的实例化对象类,和Integer对应int一样。
  2. 知道了他们的区别,那我们就可以知道该使用boolean还是Boolean了,第一个就是我们在使用容器内需要装布尔值的时候,这时候我们别无选择,只能使用Boolean类。其次,当我们需要用到toString()valueOf()方法与String相互转换的场景应该使用Boolean类。比如,
Boolean.valueOf(target);

        来转换成Boolean对象。

        3.除此之外,在使用JPA(Java Persistence API的过程中还是觉得使用boolean更有优势,因为我们只需要进行true/false的标记,就直接用boolean即可。

二、用boolean时接收不到前端参数

在使用前后端分离开发中,往往用Json传参是最高效的方式之一,但是我们可能遇到接收不到boolean类型(默认值是false)的参数。

这种情况其实是因为我们定义boolean参数的时候加了“is”,比如

private boolean isDeleted;

它的方法也是isDeleted(),RPC框架在反向解析的时候,会误判deleted才是属性名称,导致属性获取不到,进而产生抛出异常或者传参失败等情况。

三、解决办法

  1. @JsonProperty是作用在实体类的属性上的,把属性的名称序列化另一个名称,属性名称和@JsonProperty("")里面的名称是映射关系。比如数据库字段是"is_deleted",实体类属性名称是"isDeleted",这种情况,只需加上@JsonProperty("isDeleted")就能获取到Json的传参了
  2. 综上,解决办法是:
@JsonProperty("isDeleted")
private boolean isDeleted;

    @JsonProperty(value = "is_deleted")
    public boolean isDeleted() {
        return deleted;
    }
    @JsonProperty(value = "is_deleted")
    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }

### @RequestBody 接收 boolean 类型参数失败的解决方案 当使用 `@RequestBody` 注解接收 `boolean` 类型参数时,可能会因为前端递的数据格式正确或后端解析逻辑的问题导致失败。以下是具体的解决方法: #### 1. 确保前端递正确的布尔 前端递的布尔需要严格遵循 JSON 格式规范。例如,布尔应为 `true` 或 `false`(小写),而是字符串 `"true"` 或 `"false"`[^1]。如果前端递了字符串形式的布尔Spring Boot 默认的 JSON 解析器(如 Jackson)将无法正确解析为布尔类型。 ```json { "isActive": true } ``` #### 2. 使用包装类 Boolean 替代基本类型 boolean 在某些情况下,前端可能递了空(`null`)。如果后端使用的是基本类型 `boolean`,则会抛出异常。因此,建议使用包装类 `Boolean` 来替代基本类型 `boolean`,以支持 `null` 的处理[^4]。 ```java public class RequestDto { private Boolean isActive; // 使用包装类 Boolean // Getter 和 Setter 方法 } ``` #### 3. 自定义全局异常处理 如果仍然出现类型转换异常,可以通过自定义全局异常处理器捕获并处理相关错误。例如,捕获 `HttpMessageNotReadableException` 异常,并返回友好的提示信息[^4]。 ```java @ExceptionHandler(HttpMessageNotReadableException.class) @ResponseBody public ResponseEntity<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) { return new ResponseEntity<>("请求参数格式错误,请检查布尔是否为 true 或 false", HttpStatus.BAD_REQUEST); } ``` #### 4. 配置 Jackson 的宽松模式 如果前端递了字符串形式的布尔(如 `"true"` 或 `"false"`),可以通过配置 Jackson 的宽松模式来支持自动转换。在 Spring Boot 中,可以通过以下方式启用该功能[^3]: ```java @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return mapper; } ``` 此外,还可以通过自定义反序列化器来处理特定场景下的布尔转换。 ```java public class BooleanDeserializer extends JsonDeserializer<Boolean> { @Override public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String value = p.getText(); if ("true".equalsIgnoreCase(value)) { return true; } else if ("false".equalsIgnoreCase(value)) { return false; } return null; } } ``` 然后在 DTO 中使用该自定义反序列化器: ```java public class RequestDto { @JsonDeserialize(using = BooleanDeserializer.class) private Boolean isActive; // Getter 和 Setter 方法 } ``` #### 5. 检查 Controller 方法签名 确保 `@RequestBody` 注解的方法参数是一个 DTO 对象,而是直接使用基本类型 `boolean`。例如,避免以下写法: ```java @PostMapping("/example") public ResponseEntity<String> example(@RequestBody boolean isActive) { return ResponseEntity.ok("Success"); } ``` 改为使用 DTO 对象封装参数: ```java @PostMapping("/example") public ResponseEntity<String> example(@RequestBody RequestDto dto) { return ResponseEntity.ok("Success"); } ``` --- ### 示例代码 以下是一个完整的示例,展示如何正确处理 `boolean` 类型参数: ```java // DTO 定义 public class RequestDto { private Boolean isActive; public Boolean getIsActive() { return isActive; } public void setIsActive(Boolean isActive) { this.isActive = isActive; } } // Controller 定义 @RestController @RequestMapping("/api") public class ExampleController { @PostMapping("/example") public ResponseEntity<String> example(@RequestBody RequestDto dto) { if (dto.getIsActive() != null && dto.getIsActive()) { return ResponseEntity.ok("Active is true"); } return ResponseEntity.ok("Active is false or null"); } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值