springboot填坑日常--统一参数异常处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012865381/article/details/80696148

最近做springboot项目,踩下的坑,留个笔记

接收参数的对象

package cn.invcloud.platform.optMnt.vo;

import javax.validation.constraints.NotBlank;

public class PasswordUserVO {

    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

将参数自动转成对象,如果参数@Valid有错误,就会保存在BindingResult中

填坑一:BindingResult 对象必须在 @Valid 的紧挨着的后面,否则接收不到错误信息。

    @ApiOperation(value = "用户名密码方式登陆API", notes = "传入用户名密码,获取登陆token")
    @PostMapping("/password")
    public ResponseBean login(@RequestBody @Valid PasswordUserVO passwordUserVO, BindingResult bindingResult) {

        //根据用户名密码获取用户
        OperateUser operateUser = loginService.getOperateUserFromPassword(passwordUserVO.getUsername(), passwordUserVO.getPassword());
        if (operateUser == null) {
            throw new OperationServException(OperationServExceptionEnum.WRONGUSERNAMEORPASSWORD);
        }

        //查询权限,把用户名,角色放到jwt并签名
        Role role = roleRepository.findById(operateUser.getRoleId()).get();
        String[] roles = {role.getName()};

        String sign = JWTUtil.sign(operateUser.getUuid(), roles);
//        response.addCookie(new Cookie("sign",sign));
//        response.setStatus(302);
        return new ResponseBean(sign);
    }

AOP拦截所有的controller相关的方法,bindingResult如果有异常,就获取其中错误,往外抛,让异常处理器处理

package cn.invcloud.platform.optMnt.aop;

import cn.invcloud.platform.optMnt.exception.OperationServException;
import cn.invcloud.platform.optMnt.exception.OperationServExceptionEnum;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.ArrayList;
import java.util.List;

/**
 * 统一参数异常处理
 */
@Aspect
@Component
public class ParamValidatorInterceptor {
    @Around("execution(* cn.invcloud.platform.optMnt.controller.*.*(..)) && args(..,bindingResult)")
    public Object doAround(ProceedingJoinPoint pjp, BindingResult bindingResult) throws Throwable {
        //检查请求bindingResult是否有异常
        if (bindingResult.hasErrors()) {
            List<String> errMsgs = new ArrayList<>();
            for(ObjectError error : bindingResult.getAllErrors()){
                errMsgs.add(error.getDefaultMessage());
            }
            OperationServException operationServException =  new  OperationServException(OperationServExceptionEnum.BADREQUESTPARAM,errMsgs);
            //向外抛出异常,由异常处理器处理
            throw operationServException;
        }
        return pjp.proceed();
    }
}

异常处理器

package cn.invcloud.platform.optMnt.exception;

import cn.invcloud.platform.optMnt.vo.ResponseBean;
import org.apache.shiro.ShiroException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

@RestControllerAdvice
public class MyExceptionHandler {
    private Logger LOGGER = LoggerFactory.getLogger(MyExceptionHandler.class);
    // 捕捉已知的业务异常
    @ExceptionHandler(OperationServException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseBean globalException(HttpServletRequest request, OperationServException ex) {
        ex.printStackTrace();
        LOGGER.error(ex.getMessage());
        return new ResponseBean(ex.getCode(), ex.getMessage(), ex.getErrorDetail());
    }
}

填坑二:AOP拦截器的expression 包含了我的controller,如果controller的方法是private的,会导致@Autowired依赖注入失败,只需把controller的请求方法改成public即可

详情可参考http://www.cnblogs.com/lcngu/p/6246950.html

附上常见限制说明
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012865381/article/details/80696148
今日推荐