Spring boot(三):Web 进阶

一、表单校验
1、 后端校验同样是通过注解的形式进行设置
在实体类中属性上添加注解

/**
* Created by Advancer on 2017/12/19 21:08.
* auth: lbh
*/
@Entity //注解的包 都是引用的 javax.persistence 下的
public class User {

        @Id
        @GeneratedValue
        private Integer id;

        private String name;

        @Min(value = 18, message = "禁止添加未成年人员!")
        private String age;

        @NotNull(message = "金额必传")
        private Double money;

            getter()  setter()  toString()

}

2、在控制层中 可以进行校验

     /**
        * 新增一条记录
        * @param user
        * @return
        */
        @PostMapping(value = "/addUser")
        public Object addUser(@Valid User user, BindingResult bindingResult){
            if (bindingResult.hasErrors()){
                return ResultUtils.error(1, bindingResult.getFieldError().getDefaultMessage());
            }
            user.setAge(user.getAge());
            user.setMoney(user.getMoney());

        return ResultUtils.success(userRepository.save(user));
    }

@Valid 验证实体信息
BindingResult 错误校验信息类
返回类型 ResultUtils 工具类,在下面 异常处理中 讲解到
3、返回结果
这里写图片描述

二、AOP思想
OOP (面向对象) 面向对象是将不同的需求功能垂直划分为不同的并且相对独立的,它会封装成良好的类,并让它们有自己的行为。代表技术有 Java、C++、 C#…
AOP (面向切面)一种编程范式(编程思想),与程序语言无关,将面向对象构建的庞大体系进行水平的切割, 并将影响到的多个类的公共的行为,封装成一个公共的模块,这个模块就成为 切面;思想:将通用的逻辑从业务逻辑中进行分离。
POP (面向过程) 以事件、过程为中心的编程思想。 C语言

这里写图片描述

这里写图片描述

例子:以登入访问为例:要求用户必须先登录才能访问

1、首先在 pom.xml 中新增一个依赖:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
        <version>1.5.9.RELEASE</version>
</dependency>

2、创建一个处理文件

package com.lbh.aspect;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
* AOP 处理类
* Created by Advancer on 2018/1/14 16:26.
* auth: lbh
*/
@Aspect
@Component
public class HttpAspect {

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

        @Pointcut("execution(public * com.lbh.Controller.UserController.*(..))")      //拦截 UserController 类中 所有的方法
        public void log(){
        }

        @Before("log()")
        public void doBefore(){
            logger.info("doBefore()111");
            // ....一些逻辑操作
        }

        @After("log()")
        public void doAfter(){
            logger.info("doAfter()222");
     // ....一些逻辑操作
        }

}

3、以getUsers 为例,运行结果
这里写图片描述

三、异常统一处理
1、首先将 json 返回格式进行统一处理一下

创建一个 result 返回提示实体类;

/**
* 错误消息提示类
* Created by Advancer on 2018/1/14 18:51.
* auth: lbh
*/
public class Result<T> {

    private Integer code; //错误码
    private String msg; //错误消息
    private T data; //具体内容

 getter()  setter()  toString()

}

再写一个工具类:

public class ResultUtils {

    public static Result success(Object obj){
        Result result = new Result();
        result.setCode(0);
        result.setMsg("成功!");
        result.setData(obj);
        return result;
    }

    public static Result success(){
        return success(null);
    }

    public static Result error(Integer code, String msg){
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

2、在controller中使用

/**
* 新增一条记录
* @param user
* @return
*/
@PostMapping(value = "/addUser")
public Object addUser(@Valid User user, BindingResult bindingResult){
    if (bindingResult.hasErrors()){
        return ResultUtils.error(1, bindingResult.getFieldError().getDefaultMessage());
    }
    user.setAge(user.getAge());
    user.setMoney(user.getMoney());

    return ResultUtils.success(userRepository.save(user));
}

测试结果,可在表单验证节点看到。
这里写图片描述

3、再建立一个 异常捕获类

@ControllerAdvice
public class ExceptionHandle {

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

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result<User> handle(Exception e){
        if (e instanceof UserException){
            UserException userException = (UserException) e;
            return ResultUtils.error(userException.getCode(), userException.getMessage());
        }else {
            logger.info("【系统异常】{}", e);
            return ResultUtils.error(-1, "未知错误!");
        }
    }

}
/**
* 异常处理类
* Created by Advancer on 2018/1/15 11:28.
* auth: lbh
*/
public class UserException extends RuntimeException {
    // 继承RuntimeException 有事务回滚,Exception 事务提交不会自动回滚

    private Integer code ;

    /**
    * Constructs a new runtime exception with the specified detail message.
    * The cause is not initialized, and may subsequently be initialized by a
    * call to {@link #initCause}.
    *
    * @param message the detail message. The detail message is saved for
    * later retrieval by the {@link #getMessage()} method.
    * @param code
    */
    public UserException(ResultEnum resultEnum) {
        super(resultEnum.getMsg());
        this.code = resultEnum.getCode();
    }

    public Integer getCode() {
        return code;
    }

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

4、错误码、错误消息 统一管理
采用 枚举实现

/**
* Created by Advancer on 2018/1/15 13:49.
* auth: lbh
*/
public enum ResultEnum {
    UNKNOW_ERROR(-1, "未知错误!"),
    SUCCESS(0, "成功!"),
    PRIMARY_SCHOOL(100, "你可能还在上小学!"),
    MIDDLE_SCHOOL(101, "你可能在上初中!")
    ;

    private Integer code;
    private String msg;

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

    getter()   //枚举不需要setter()方法
}

方法具体使用实现

public Integer getAge(Integer id) throws Exception{
    User user = userRepository.findOne(id);
    Integer age = Integer.parseInt(user.getAge());
    if (age < 10){
        //...
        throw new UserException(ResultEnum.PRIMARY_SCHOOL);
    }else if (age > 10 && age < 16){
        //...
        throw new UserException(ResultEnum.MIDDLE_SCHOOL);
    }
    // ..
    return 0;
}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值