一、@Valid验证

场景:添加部门信息时,增加部门下的人数;满足一定人数可以被成功添加,否则返回NULL

//部门人数
@Min(value=18,message="不满足18个人,不能成立新部门!")
private Integer count;//get/set 方法@PostMapping(value="/saveDept")
public  DeptTemp saveDept(@Valid DeptTemp temp,//错误信息返回对象BindingResult result){if (result.hasErrors()) { //如果有错误信息,则打印 并返回System.out.println(result.getFieldError().getDefaultMessage());return null;}temp.setdName(temp.getdName());temp.setLoc(temp.getLoc());temp.setCount(temp.getCount());return deptRespository.save(temp);
}

由于,我们处理了验证不同过时的信息,如果验证不通过时会在控制台打印“自定义的验证信息,例如:不满足18个人,不能成立新部门!”

否则的话,此访问路径则会返回“500”错误,运行时异常;

在满足正确的条件下则可以被添加数据库,否则被拒之门外。

二、AOP统一处理日志

AOP是一种编程规范,与语言无关,是一种程序设计思想;

场景:记录下每次访问的请求

第一步:添加依赖

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

第二步:定义Aspect类

@Aspect
@Component //该文件引用到spring 容器里
public class HttpAspect {@Before("execution(public * com.test.controller.DeptController.getList(..))")
public void log(){System.out.println("Aspect:log");}
}

该log方法将作用在getList方法上面,并且先于该方法之前打印出日志。

同样也会有After方法,方法同上。

//Spring自带的日志框架,底层实现是logback
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);@Pointcut("execution(public * com.test.controller.DeptController.getList(..))")
public void log(){}@Before("log()")
public void doBefore(){logger.info("Aspect:before:log");
}@After("log()")
public void doAfter(){logger.info("Aspect:after:log");
}

1.记录请求方法的url、method、ip等信息

@Before("log()")
public void doBefore(JoinPoint joinPoint){//请求的urlServletRequestAttributes attributes =  (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();logger.info("url={}",request.getRequestURL());//请求的methodlogger.info("method={}",request.getMethod());//请求的iplogger.info("ip={}",request.getRemoteAddr());//请求的方法logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());//请求的参数logger.info("args={}",joinPoint.getArgs());
}

请求路径如下:http://localhost:8081/dept/getDept/2

2.获取返回的内容

@AfterReturning(returning = "object" , pointcut="log()")
public void doAfterReturning(Object object){logger.info("response={}",object);
}

返回结果如下:

三、异常处理

场景:判断部门下的人数,小于10人,划分成一个小组;10-18建议划分小组;大于18,成立新小组。

在之前的添加部门的方法时有必输校验,如果没有填写该值则会报错,会触发后台异常;

解决方法:把异常信息返回在前台页面

第一步:改造添加部门方法

第二步:验证

1.非法输入参数

2.正常输入参数

这就带来一个问题,返回的格式不一致!这对接口调用方来说,很不方便,这个时候就需要定义个传输标准

例如:

##接口调用异常
{"code" : -1,"msg"  : "XX必输","data" : NULL
}##接口调用正常
{"code" : -1,"msg"  : "XX必输","data" : {"id"    : "2","dName" : "一部","loc" : "北京","count" : "20"}
}

第一步:定义业务类

/*** version 1.0* TODO http请求返回的最外层对象* @param <T>*/
public class ReturnMsg<T> {/** 错误码 */private Integer code;/** 提示的信息 */private String msg;/** 具体的内容 */private T data;//get/set 方法
}

第二步:定义返回成功、失败的公共方法

public class ReturnUtil {public static ReturnMsg success(Object obj){ReturnMsg msg = new ReturnMsg();msg.setCode(0);msg.setMsg("成功");msg.setData(obj);return msg;}public static ReturnMsg success(){return success(null);}public static ReturnMsg error(Integer code,String msg){ReturnMsg returnMsg = new ReturnMsg();returnMsg.setCode(code);returnMsg.setMsg(msg);return returnMsg;}
}

第三步:改造新增时的方法

测试结果如下:

正确数据:

异常数据:

回到我们最一开始的业务场景,判断部门下的人数,小于10人,划分成一个小组;10-18建议划分小组;大于18,成立新小组。

常规做法:在service处理业务逻辑,进行if判断,但这个时候会带来一个问题:往往service不只是单纯处理的逻辑判断还会根据判断的结果进行更进一步的业务处理,这个时候就需要用到统一异常处理的类,来进行异常处理。

第一步:service定义方法

第二步:自定义Exception异常

@ControllerAdvice
public class NoExceptionHandle {@ExceptionHandler(value = Exception.class)@ResponseBodypublic ReturnMsg handle(Exception e){return ReturnUtil.error(100, e.getMessage());}
}

第三步:controller调用

@GetMapping(value = "/getNo/{no}")
public void getNo(@PathVariable("no") Integer no) throws Exception{deptService.getNo(no);
}

调用结果如下:

现在已经基本完善,但还有一点不是很明确,就是返回的code,始终是100,这个时候对排查错误不是很友好,此时需要改造Exception

第一步:自定义异常类

//因为Spring框架只会对RuntimeException进行事务回滚
public class MyException extends RuntimeException{private Integer code;public MyException(Integer code,String msg) {super(msg);this.code = code;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}
}

第二步:改造service

第三步:改造handle

验证:

还需要进行改造的是:code和msg部分;方便统一管理

第一步:定义枚举

//定义code和msg
public enum ResultEnum {UNKOWN_ERROR(-1,"未知错误"),SUCCESS(0,"成功"),LESS_TEAM(100,"人数不足,划分为一个小组!"),MID_TEAM(101,"人数过多,建议划分!"),NEW_TEAM(102,"人数过多,成立新小组");private Integer code;private String msg;//只需要get方法
}

第二步:改造MyException

第三步:改造service

结果同上。

转载于:https://blog.51cto.com/mazongfei/2134465

spring-boot入门之二——验证、AOP日志、异常处理相关推荐

  1. Spring Boot入门教程(二十八): 校验(validation)

    validation主要是校验用户提交的数据的合法性,比如是否为空,密码是否符合规则,邮箱格式是否正确等等,校验框架比较多,用的比较多的是hibernate-validator, 也支持国际化,也可以 ...

  2. Spring Boot入门教程(二十五): Apache Shiro

    1. pom.xml shiro并没有提供对应的Starter,而是使用的shiro-spring,其它的依赖都是辅助 <dependency><groupId>org.spr ...

  3. Spring boot入门(三):集成AdminLTE(Freemarker),结合generate代码生成器,利用DataTable和PageHelper分页...

    Spring boot入门(三):SpringBoot集成结合AdminLTE(Freemarker),利用generate自动生成代码,利用DataTable和PageHelper进行分页显示 标题 ...

  4. Spring Boot 入门(五):集成 AOP 进行日志管理

    本篇文章是接着 Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理写的,按照前面几篇博客的教程,可以搭建一个简单的项目,主要包含了 Pagehelper+MyBatis 分页 ...

  5. Spring Boot入门到精通(超详细)

    1.Spring Boot简介 我们知道,从 2002 年开始,Spring 一直在飞速的发展,如今已经成为了在Java EE(Java Enterprise Edition)开发中真正意义上的标准, ...

  6. Spring Boot整合ELK 处理为服务日志,妙!

    你知道的越多,不知道的就越多,业余的像一棵小草! 成功路上并不拥挤,因为坚持的人不多. 编辑:业余草 developer.ibm.com 推荐:https://www.xttblog.com/?p=5 ...

  7. Spring Boot 入门

    一.Spring Boot 入门 1.Spring Boot 简介 简化Spring应用开发的一个框架: 整个Spring技术栈的一个大整合: J2EE开发的一站式解决方案: 2.微服务 2014,m ...

  8. Spring Boot 入门与实战笔记

    **一.**Spring Boot 入门 1.Spring Boot 简介 简化Spring应用开发的一个框架: 整个Spring技术栈的一个大整合: J2EE开发的一站式解决方案: 2.微服务 20 ...

  9. springboot 创建地址_这可能是史上最易懂的 Spring Boot 入门教程

    目录 一.Spring Boot 是什么 二.为什么要使用 Spring Boot 三.快速入门 3.1 创建 Spring Boot 项目 3.2 项目结构 3.3 引入 Web 依赖 3.4 编写 ...

  10. Spring Boot 入门笔记

    一.Spring Boot 入门 1.Spring Boot 简介 简化Spring应用开发的一个框架: 整个Spring技术栈的一个大整合: J2EE开发的一站式解决方案: 2.微服务 2014,m ...

最新文章

  1. linux的android工作室,Android工作室在启动时抛出错误,linux机器
  2. python代码怎么运行-Python程序执行原理,python程序怎么运行的?
  3. 数据远程实时备份容灾方案
  4. figma下载_我如何使用Figma,CSS Grid和CSS Flexbox构建登录页面
  5. android 文字反转_多文字共享信息系统
  6. ie11用不了html5,HTML5拖放不能在IE11上运行
  7. 适用于数据科学家的Kubernetes,Linux原理,对硬件问题进行故障排除,Python等
  8. 转载--SQL还原数据库后孤立用户问题处理(SQL 数据库 拥有对象 无法删除)
  9. 用__postback传递JavaScript变量到c#(pass a js variable to C# by a __postback )
  10. 如何回滚特定的迁移?
  11. 基于seaborn的相关性热力图可视化分析
  12. Halcon学习笔记之OCR系列-喷码字体识别
  13. 高电压与绝缘技术方向,代做EMTP,ATP输电线路防雷仿真
  14. Python:SEIR传染病模型
  15. 如何阅读看懂datasheet
  16. String实现 intern
  17. ABAP 语法备忘 刘欣
  18. len计算机语言,python中len的使用方法
  19. 【支付宝小程序控制硬件①】 申请个人支付宝小程序开发的个人账户,说说那些睬坑日志,集成mqtt协议在支付宝小程序,实现基本通讯!
  20. 福大软工 · 第八次作业 课堂实战+后续部分

热门文章

  1. 基于JavaWeb实现在线租房系统
  2. 安装scala之后,命令行中输入scala报错nullpointException
  3. markdown编辑器语法——背景色
  4. magento中调用图片的方法
  5. 科大讯飞AIUI(1)
  6. [2009.08.09]博客园北京俱乐部活动暨《博客园精华集:Web标准之道》现场签售通知...
  7. Linux入门第二弹!Xshell、Xftp、tomcat的Linux版本、双X的教学资源!
  8. linux boa服务器访问 404,Linux上boa服务器的配置和使用
  9. mysql多列索引不全用,MySQL多列索引的生效规则
  10. 网线传输速度测试_高效的以太网测试仪应该具备哪些功能?