一、表单校验
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;
}