springboot-表单验证|AOP|统一异常处理

版权声明:fromZjy QQ1045152332 https://blog.csdn.net/qq_36762677/article/details/83001451
@PostMapping(value = "/girls")
    public Object addGirl(Girl girl) {//此处不用使用多个@RequestParam("name")
        Result result = new Result("addGirl_Error", 0, false);
        try {
            result.setResult(commandService.addGirl(girl));
            result.setType("addGirl_ACK");
            return result;
        } catch (Exception e) {
            logger.error("添加女生失败", e);
            result.setCode(-3);
            return result;
        }
    }

在这里插入图片描述

@Valid表单验证

验证传进controller的对象属性是否有错
1.Girl实体类成员变量需要添加注解

@Min(value = 18 , message = "未满18岁不可访问")
private Integer age;

2.controller参数需要处理

	@PostMapping(value = "/girls")
	//!!!!需要加@Valid注解
    public Object addGirl(@Valid Girl girl,BindingResult br) {
    	Result result = new Result("addGirl_Error", 0, false);
    	//需要处理没验证通过的结果,错误信息返回
    	if (br.hasErrors()){
    		result.setMessage(br.getFieldError().getDefaultMessage());
    		return result;
    	}
        try {
            result.setResult(commandService.addGirl(girl));
            result.setType("addGirl_ACK");
            return result;
        } catch (Exception e) {
            logger.error("添加女生失败", e);
            result.setCode(-3);
            return result;
        }
    }

使用AOP处理请求或记录日志

  • AOP面向切面 _编程范式(程序设计思想)
  • 分离通用逻辑
    1.引入依赖
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-aop</artifactId>
	</dependency>

2.具体切面代码

/**
 * 日志写入管理
 * zjy
 */
@Aspect
@Component
public class ControllerAspect {
	
	private final static Logger logger = LoggerFactory.getLogger(ControllerAspect.class);

    @Autowired
    @Qualifier("logServiceImpl")
    private LogService logService;

    @Autowired
    private UserService userService;

    @Pointcut("execution(* com.honghe.managerTool.controller.CommandController.*(..)) "
            + "|| execution(* com.honghe.managerTool.controller.UserController.*(..)) ")
    public void aspect() {//拦截所有类下所有方法
    }

	//配置前置通知,使用在方法aspect()上注册的切入点
    @Before("aspect()")
    public void before(JoinPoint joinPoint) {
        String[] paramNames = ((CodeSignature) joinPoint
                .getSignature()).getParameterNames();
        Object[] paramValues = joinPoint.getArgs();
        String userIp = "127.0.0.1";
        String oprationName = joinPoint.getSignature().getName();

        switch (oprationName){
            case "start":
                oprationName=Operation.START.value;
                break;
            case "stop":
                oprationName=Operation.STOP.value;
                break;
            case "restart":
                oprationName=Operation.RESTART.value;
                break;
                default:
                    return;
        }
        if(paramValues.length>0){
            if(paramValues[0] instanceof HttpServletRequest){
                HttpServletRequest request = (HttpServletRequest)paramValues[0];
                userIp = ParamUtil.getIpAddress(request);
            }
        }

        Log log = new Log(oprationName,new Date(),userIp,1);
        logService.saveLog(log);
    }

    //配置后置通知,使用在方法aspect()上注册的切入点
    @After("aspect()")
    public void after(JoinPoint joinPoint){
        logger.info("after out successfully");
    }
}

对http请求解析

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author: zhaojianyu
 * @create: 2018-10-11 09:11
 **/
@Aspect
@Component
public class HttpAspect {

    private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);

    /**
     * 拦截所有类下所有方法
     */
    @Pointcut("execution(* com.zjy.blog.blog_start.controller.HelloContraller.*(..)) ")
    public void aspect() {
    }

    /**
     * 配置前置通知,使用在方法aspect()上注册的切入点
     */
    @Before("aspect()")
    public void before(JoinPoint joinPoint) {
        logger.info("方法开始执行"+new Date());

        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //url
        logger.info("url={}",request.getRequestURL());

        logger.info("uri={}",request.getRequestURI());
        //请求方法
        logger.info("method={}",request.getMethod());
        //请求ip地址
        logger.info("ip={}",request.getRemoteAddr());
        //类名  类方法
        logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName()+"="+joinPoint.getSignature().getName());
        //参数
        logger.info("args={}",joinPoint.getArgs());
    }

    @After("aspect()")
    public void after() {
        logger.info("方法执行完毕1"+new Date());
    }

    @AfterReturning(returning = "object",pointcut = "aspect()")
    public void afterReturning(Object object) {
        logger.info("方法执行完毕2"+new Date() + object);
    }
}

统一异常处理

在这里插入图片描述

Error和Exception区分:

Error是编译时错误和系统错误,系统错误在除特殊情况下,都不需要你来关心,基本不会出现。而编译时错误,如果你使用了编译器,那么编译器会提示。

Exception则是可以被抛出的基本类型,我们需要主要关心的也是这个类。

Exception又分为RunTimeException和其他Exception。

RunTimeException和其他Exception区分:

其他Exception,受检查异常。可以理解为错误,必须要开发者解决以后才能编译通过,解决的方法有两种,1:throw到上层,2,try-catch处理。
RunTimeException:运行时异常,又称不受检查异常,不受检查!不受检查!!不受检查!!!重要的事情说三遍,因为不受检查,所以在代码中可能会有RunTimeException时Java编译检查时不会告诉你有这个异常,但是在实际运行代码时则会暴露出来,比如经典的1/0,空指针等。如果不处理也会被Java自己处理。

统一异常处理类

import com.honghe.managerTool.config.exception.MySecurityException;
import com.honghe.managerTool.entity.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 全局处理异常
 * @author zhaojianyu
 * 2018 10 11
 */
/**
 * @ControllerAdvice  //处理所有
 * @ControllerAdvice(annotations=RestController.class)   //处理这个类下的异常
 * @ControllerAdvice(basePackages={"com.honghe.managerTool.controller"})   //处理包下的异常
 */

@ControllerAdvice
public class GlobalExceptionHandler {


    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * @ExceptionHandler(value={RuntimeException.class,MyRuntimeException.class}) //处理需要处理的异常类
     * @ExceptionHandler    //处理所有异常
     * @ExceptionHandler(MySecurityException.class)  //处理专门的异常
     */

    @ResponseBody
    @ExceptionHandler
    public Result exceptionHandler(Exception e) {
        if (e instanceof MySecurityException){
            MySecurityException me = (MySecurityException)e;
            //logger.error("权限异常",e);
            return new Result(me.getCode(),false,e.getMessage());
        }else if (e instanceof NullPointerException){
            logger.error("空指针异常",e);
            return new Result(-3,false,"空指针异常");
        }else{
            return new Result(-3,false,"异常");
        }
    }
}

自定义异常类

/**
 * 权限验证异常
 * @author zhaojianyu
 */
public class MySecurityException extends RuntimeException {

    private Integer code;

    /**
     * 无参构造方法
     */
    public MySecurityException(){
        super();
    }

    /**
     * 有参的构造方法
     */
    public MySecurityException(String message,Integer code){
        super(message);
        this.code = code;
    }

    /**
     * 用指定的详细信息和原因构造一个新的异常
     */
    public MySecurityException(String message, Throwable cause){

        super(message,cause);
    }

    /**
     * 用指定原因构造一个新的异常
     */
     public MySecurityException(Throwable cause) {
         super(cause);
     }


    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
}

抛出自定义异常

throw new MySecurityException("请求超时,请同步服务器时间",-2);

返回值代码枚举类

/**
 *
 * 返回值枚举类
 * @author: zhaojianyu
 * @create: 2018-10-11 17:50
 **/
public enum ResultEnum {
    /**
     * 异常信息
     */
    UNKONW_ERROR(-1,"未知错误"),
    SUCCESS(0,"请求成功"),
    SECURITY_EXCEPTION(-2,"权限异常"),
    PARAMS_EXCEPTION(-3,"权限异常")
    ;
    private Integer code;
    private String message;

    ResultEnum() {
    }

    ResultEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36762677/article/details/83001451
今日推荐