springboot 接口接收参数类型不匹配异常处理
在开发项目中,我们常用bean注解的方式来验证参数的合法性,比如:Bean Validation内嵌的注解很多,基本实际开发中已经够用了,注解如下:Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Long' for property 'useThreshold';Fail
·
1、在开发项目中,我们常用bean注解的方式来验证参数的合法性,比如:
2、在正常的项目开发当中,上面的这些注解验证是建立在正常标准的传值的基础之上进行验证的,但是在实际开发过程中,我们会遇到这样的情况,假设你定义的bean的字段类型是Integer或者是Long类型时,而前端传递过来的是个字符串,这个时候就会报类型转换的异常,而且这个异常会直接传递给了前端,并不会把我们配置好的message信息返回给前端
@NotNull(message = "获取门槛不能为空")
@Min(value = 0,message = "请填写大于0的正整数")
@Excel(name = "使用门槛:满多少使用")
private Long useThreshold;
返回给前端的是这些信息
Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Long' for property 'useThreshold';
Failed to convert property value of type 'java.lang.String'
to required type 'java.lang.Long' for property 'useThreshold';
nested exception is java.lang.NumberFormatException:
For input string: \"阿斯顿发\""
3、为了解决这个问题,我们尝试写自定义注解,当我们自定义注解拦截后返回给前端我们想返回的提示信息,但是也没什么卵用,依然返回的是英文信息。
4、终极大招,我们在异常拦截出进行处理,处理方式如下:
/**
* 自定义验证异常
*/
@ExceptionHandler(BindException.class)
public AjaxResult validatedBindException(BindException e)
{
log.error(e.getMessage(), e);
String message = e.getAllErrors().get(0).getDefaultMessage();
//如果是自己使用注解可以捕获的异常就直接使用
if(message != null && !message.startsWith("Failed to convert property")){
return AjaxResult.error(message);
}else {//否则基本是捕获不到的转换异常,手动去获取设定的异常信息
BindingResult bindingResult = e.getBindingResult();
FieldError fieldError = bindingResult.getFieldErrors().stream().min(Comparator.comparing(FieldError::getField)).orElse(null);
if (fieldError == null) {
return AjaxResult.error("参数格式不正确");
}
String fieldName = fieldError.getField();
Class<?> targetCalss = Objects.requireNonNull(bindingResult.getTarget()).getClass();
String erroMessage = getDataBindErrorTips(targetCalss, fieldName);
if (StringUtils.isEmpty(erroMessage)) {
erroMessage = fieldError.getDefaultMessage();
if (erroMessage != null && erroMessage.startsWith("Failed to convert property")) {
erroMessage = "参数格式不正确";
}
}
String rejectedValue = Objects.toString(fieldError.getRejectedValue());
if (rejectedValue.length() > 30) {
rejectedValue = rejectedValue.substring(0, 30) + "...";
}
log.error("BindException field={}, rejectedValue={}, errorMessage={}", fieldName, rejectedValue, erroMessage);
return AjaxResult.error(erroMessage);
}
}
/**获取字段所在实体类中所对应的自定义提示信息
* 注意:1、验证字段必须要配置验证注解
* 2、如果发生参数类型不一致时,默认提取第一个注解的message信息返给前端
* @Description
* @Author liz
* @Date 2022/1/4 17:27
* @Param [targetCalss, fieldName]
* @return java.lang.String
**/
private String getDataBindErrorTips(Class<?> targetCalss, String fieldName) {
if (targetCalss == null || StringUtils.isEmpty(fieldName)) {
return null;
}
while (targetCalss != Object.class) {
Field field;
try {
field = targetCalss.getDeclaredField(fieldName);
//获取具体注解标签的提示信息
//LongValue longValue = field.getDeclaredAnnotation(LongValue.class);
//Annotation[] annotations = field.getAnnotations();
//获取第一个注解标签的提示信息,如果没有返回null
Annotation[] anns = field.getDeclaredAnnotations();
if(null!=anns && anns.length>0) {
String json =JSON.toJSONString(anns[0]);
log.info("错误注解json字符串="+json);
JSONObject jsonObject =JSONObject.parseObject(json);
if(org.apache.commons.lang3.StringUtils.isNotBlank(jsonObject.getString("message"))) {
return jsonObject.getString("message");
}else {
return null;
}
}else {
return null;
}
} catch (NoSuchFieldException e) {
targetCalss = targetCalss.getSuperclass();
}
}
return null;
}
目前小编也只能用这种方法来解决了,如果您有更好的方法,请在留言处,给小编留言,不胜感激。
更多推荐
已为社区贡献2条内容
所有评论(0)