SpringBoot Rest API数值验证需求:字符串类型金额参数需抛出异常
解决方案:严格限制BigDecimal字段仅接受数值类型输入
方法1:自定义Jackson反序列化器拦截字符串输入
默认Jackson会自动将字符串格式的数字转换为BigDecimal,我们可以通过自定义反序列化器,直接拦截字符串类型的输入并抛出异常:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.math.BigDecimal; public class StrictBigDecimalDeserializer extends StdDeserializer<BigDecimal> { protected StrictBigDecimalDeserializer() { super(BigDecimal.class); } @Override public BigDecimal deserialize(JsonParser parser, DeserializationContext context) throws IOException { // 仅允许数值类型输入,字符串直接抛异常 if (!parser.isExpectedNumberType()) { throw new IllegalArgumentException("amount必须为数值类型,不能是字符串"); } return parser.getDecimalValue(); } }
在DTO的amount字段上指定使用该反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.math.BigDecimal; public class YourRequestDTO { @JsonDeserialize(using = StrictBigDecimalDeserializer.class) private BigDecimal amount; // getter、setter方法 }
方法2:通过Jackson全局配置禁用字符串转数值
直接在配置文件中禁用Jackson自动转换字符串为数值的特性,配合全局异常处理器统一抛出指定异常:
- 在
application.properties中添加配置:
spring.jackson.deserialization.accept-string-as-number=false
- 编写全局异常处理器,将Jackson抛出的转换异常转为
IllegalArgumentException:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import com.fasterxml.jackson.databind.JsonMappingException; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(JsonMappingException.class) public ResponseEntity<String> handleNumberMappingException(JsonMappingException ex) { if (ex.getMessage().contains("Cannot deserialize value of type `java.math.BigDecimal` from String")) { throw new IllegalArgumentException("amount必须为数值类型"); } return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); } }
验证效果
- 传入
{"amount": 1234.5}:正常解析,接口正常执行 - 传入
{"amount": "1234.5"}:触发IllegalArgumentException或自定义错误提示
内容的提问来源于stack exchange,提问作者Manoj Kumar Durishetti
相关产品推荐
相关产品推荐

