1、表单验证
现在先来看看程序存在什么设计不合理的点
@PostMapping(value = "/girls")
public Girl girlAdd(@RequestParam("cupSize") String cupSize,
@RequestParam("age") Integer age){
Girl girl = new Girl();
girl.setAge(age);
girl.setCupSize(cupSize);
return girlRepository.save(girl);
}
若一个女生有很多种属性,在方法参数上就得加很多种参数。
@PostMapping(value = "/girls")
public Girl girlAdd(Girl girl){
girl.setAge(girl.getAge());
girl.setCupSize(girl.getCupSize());
return girlRepository.save(girl);
}
修改成如上。Hibernate会看包的body里携带的参数是否和Girl类的私有变量同名,同名则调用setter为实例化的girl赋值。
进入正题:怎么实现表单验证?
Girl类的私有变量添加@Min注解,value为最低值,message为不符合最低值时返回的错误信息。
@Min(value = 18,message = "未成年少女不许进入数据库")
private Integer age;
为形参添加@Valid注解,验证结果会返回给bindingResult
@PostMapping(value = "/girls")
public Girl girlAdd(@Valid Girl girl,BindingResult bindingResult){
if(bindingResult.hasErrors()){
System.out.println(bindingResult.getFieldError().getDefaultMessage());
return null;
}
girl.setAge(girl.getAge());
girl.setCupSize(girl.getCupSize());
return girlRepository.save(girl);
}
2使用AOP处理请求
什么是AOP?
AOP是一种编程范式,与语言无关,是一种程序设计思想。
面向对象关注的是将需求功能垂直划分为不同的、并且相对独立的,它会封装成良好的类,并且它们有属于自己的行为。
而面向切面技术则恰恰相反。
它利用的是一种横切的技术,将面向对象构建的庞大的类的体系进行水平的切割,并且会将那些影响了多个类的公共行为封装成一个可重用的模块,这个模块称为切面。
AOP的关键思想是将通用逻辑从业务逻辑中分离出来。
AOP讲解例子:AOP统一处理请求日志
-
添加依赖
图片.png - 新建包含通用逻辑的HttpAspect 类
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class HttpAspect {
@Before("execution(public * com.imooc.controller.GirlController.*(..))")
public void log(){
System.out.println(1111111111);
}
@After("execution(public * com.imooc.controller.GirlController.*(..))")
public void doAfter(){
System.out.println(222222222);
}
}
@Before注解的方法在切面方法执行之前就已经执行了。
@After注解的方法在切面方法执行之后执行。
..表示只要是这个方法,任何参数都会被拦截
- HttpAspect类代码再精简一下。
package com.imooc.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.springframework.stereotype.Component;
@Aspect
@Component
public class HttpAspect {
@Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")//指明切面
public void log(){//切面别名叫log()
}
@Before("log()")//在名叫log()的切面之前执行
public void doBefore(){
System.out.println(111111111);
}
@After("log()")//在名叫log()的切面之后执行
public void doAfter(){
System.out.println(222222222);
}
}
- 换作使用log打印
package com.imooc.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;
@Aspect
@Component
public class HttpAspect {
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
@Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")//指明切面
public void log(){//切面别名叫log()
}
@Before("log()")//在名叫log()的切面之前执行
public void doBefore(){
logger.info("111111111");
}
@After("log()")//在名叫log()的切面之后执行
public void doAfter(){
logger.info("222222222");
}
}
- 在切面方法内也用logger打印
@RestController
public class GirlController {
private final static Logger logger = LoggerFactory.getLogger(GirlController.class);
@Autowired
private GirlRepository girlRepository;
@Autowired
private GirlService girlService;
/**
* 查询所有女生列表
* @return
*/
@GetMapping(value = "/girls")
public List<Girl> girlList(){
logger.info("girlList");
return girlRepository.findAll();
}
- 改造@Before注解的方法,使其记录Http请求。
package com.imooc.aspect;
import org.aspectj.lang.JoinPoint;
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;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Aspect
@Component
public class HttpAspect {
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
@Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")//指明切面
public void log(){//切面别名叫log()
}
@Before("log()")//在名叫log()的切面之前执行
public void doBefore(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//url
logger.info("url={}",request.getRequestURI());
//请求method
logger.info("method={}",request.getMethod());
//ip
logger.info("ip={}",request.getRemoteAddr());
//类方法
logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName() + "\\" + joinPoint.getSignature().getName());//getDeclaringTypeName得到包名,getName得到方法名
//传过来的参数
logger.info("args={}",joinPoint.getArgs());
}
@After("log()")//在名叫log()的切面之后执行
public void doAfter(){
logger.info("222222222");
}
}
效果示例
图片.png
2019-02-15 13:52:53.819 INFO 12712 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : url=/girls/14
2019-02-15 13:52:53.819 INFO 12712 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : method=GET
2019-02-15 13:52:53.819 INFO 12712 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : ip=0:0:0:0:0:0:0:1
2019-02-15 13:52:53.819 INFO 12712 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : class_method=com.imooc.controller.GirlController\girlFindOne
2019-02-15 13:52:53.819 INFO 12712 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : args=14
Hibernate: select girl0_.id as id1_0_0_, girl0_.age as age2_0_0_, girl0_.cup_size as cup_size3_0_0_ from girl girl0_ where girl0_.id=?
2019-02-15 13:52:53.832 INFO 12712 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : 222222222
-
获取返回的内容
即获取 图片.png
package com.imooc.aspect;
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;
@Aspect
@Component
public class HttpAspect {
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
@Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")//指明切面
public void log(){//切面别名叫log()
}
@AfterReturning(returning = "object",pointcut = "log()")//名叫log()的切面若有返回值,则作为实参传给object形参
public void doAgterReturning(Object object){
logger.info("response={}",object);
}
}
效果示例:
没有返回值的切面(public void girlDelete(@PathVariable("id") Integer id))
图片.png
2019-02-15 14:27:46.127 INFO 9120 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : url=/girls/14
2019-02-15 14:27:46.127 INFO 9120 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : method=DELETE
2019-02-15 14:27:46.127 INFO 9120 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : ip=0:0:0:0:0:0:0:1
2019-02-15 14:27:46.127 INFO 9120 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : class_method=com.imooc.controller.GirlController\girlDelete
2019-02-15 14:27:46.127 INFO 9120 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : args=14
Hibernate: select girl0_.id as id1_0_0_, girl0_.age as age2_0_0_, girl0_.cup_size as cup_size3_0_0_ from girl girl0_ where girl0_.id=?
Hibernate: delete from girl where id=?
2019-02-15 14:27:46.245 INFO 9120 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : 222222222
2019-02-15 14:27:46.246 INFO 9120 --- [nio-8080-exec-5] com.imooc.aspect.HttpAspect : response=null
由于删除方法girlDelete没有返回值,故@doAfterReturning注解的doAfterReturning方法没有被传参,Object是null,所以response=null
有返回值的切面(public Girl girlFindOne(@PathVariable("id") Integer id))
图片.png
2019-02-15 14:36:17.723 INFO 9120 --- [nio-8080-exec-8] com.imooc.aspect.HttpAspect : url=/girls/2
2019-02-15 14:36:17.723 INFO 9120 --- [nio-8080-exec-8] com.imooc.aspect.HttpAspect : method=GET
2019-02-15 14:36:17.723 INFO 9120 --- [nio-8080-exec-8] com.imooc.aspect.HttpAspect : ip=0:0:0:0:0:0:0:1
2019-02-15 14:36:17.723 INFO 9120 --- [nio-8080-exec-8] com.imooc.aspect.HttpAspect : class_method=com.imooc.controller.GirlController\girlFindOne
2019-02-15 14:36:17.723 INFO 9120 --- [nio-8080-exec-8] com.imooc.aspect.HttpAspect : args=2
Hibernate: select girl0_.id as id1_0_0_, girl0_.age as age2_0_0_, girl0_.cup_size as cup_size3_0_0_ from girl girl0_ where girl0_.id=?
2019-02-15 14:36:17.730 INFO 9120 --- [nio-8080-exec-8] com.imooc.aspect.HttpAspect : 222222222
2019-02-15 14:36:17.730 INFO 9120 --- [nio-8080-exec-8] com.imooc.aspect.HttpAspect : response={"id":2,"cupSize":"B","age":13}
3、统一异常处理
视频中Girl类(表)多了一个私有变量money(字段),Girl类改动如下
import javax.validation.constraints.NotNull;
public class Girl {
···
@NotNull(message = "金额必传")
private Double money;
···
}
-
先来看看这个程序抛出的系统异常
图片.png
返回的错误:
2019-02-15 16:14:11.774 ERROR 9880 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
- 将错误信息返回给前端
增加一个女生报错时,错误信息是显示在空值台的
2019-02-15 17:03:19.598 INFO 9880 --- [nio-8080-exec-4] com.imooc.controller.GirlController : 金额必传
现要将错误信息返回给前端,将girlAdd方法改动如下
/**
* 添加一个女生
* @return
*/
@PostMapping(value = "/girls")
public Object girlAdd(@Valid Girl girl,BindingResult bindingResult){
if(bindingResult.hasErrors()){
return (bindingResult.getFieldError().getDefaultMessage());
}
girl.setAge(girl.getAge());
girl.setCupSize(girl.getCupSize());
return girlRepository.save(girl);
}
成功添加时返回给前端的信息
图片.png
金额为空时不能添加一行数据进girl表
图片.png
虽然把错误信息返回给前端了,但是又出现了一个问题,成功信息和错误信息的格式不一致。
-
将成功信息和错误信息的格式一致
图片.png
http请求返回的最外层对象
package com.imooc.domain;
/**
* http请求返回的最外层对象
*/
public class Result<T> {
/** 错误码 */
private Integer code;
/** 提示信息 */
private String msg;
/** 具体的内容 */
private T data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
改造girlAdd方法
@PostMapping(value = "/girls")
public Result<Girl> girlAdd(@Valid Girl girl, BindingResult bindingResult){
if(bindingResult.hasErrors()){
Result result = new Result();
result.setCode(1);
result.setMsg(bindingResult.getFieldError().getDefaultMessage());
result.setData(null);
return result;
}
girl.setAge(girl.getAge());
girl.setCupSize(girl.getCupSize());
Result result = new Result();
result.setCode(0);
result.setMsg("成功");
result.setData(girlRepository.save(girl));
return result;
}
money为空时返回给前端的信息
图片.png
成功添加一行数据进入girl表时返回给前端的信息
图片.png
- 写一个工具类ResultUtil,将返回结果逻辑封装起来
package com.imooc.utils;
import com.imooc.domain.Result;
public class ResultUtil {
public static Result success(Object object){
Result result = new Result();
result.setCode(0);
result.setMsg("成功");
result.setData(object);
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);
result.setData(null);
return result;
}
}
修改girlAdd方法
@PostMapping(value = "/girls")
public Result<Girl> girlAdd(@Valid Girl girl, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return ResultUtil.error(1,bindingResult.getFieldError().getDefaultMessage());
}
girl.setAge(girl.getAge());
girl.setCupSize(girl.getCupSize());
return ResultUtil.success(girlRepository.save(girl));
}
-
一个运用统一异常处理的例子
图片.png
逻辑在设计规范中都是放在service的
package com.imooc.service;
import com.imooc.domain.Girl;
import com.imooc.repository.GirlRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class GirlService {
@Autowired
private GirlRepository girlRepository;
@Transactional
public void insertTwo(){
Girl girlA = new Girl();
girlA.setAge(18);
girlA.setCupSize("A");
girlRepository.save(girlA);
Girl girlB = new Girl();
girlB.setAge(19);
girlB.setCupSize("B");
girlRepository.save(girlB);
}
演示效果及流程解释
![图片.png](https://img.haomeiwen.com/i4031144/b4f70d9ab4b5296c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
public void getAge(Integer id) throws Exception{
Girl girl = girlRepository.findById(id).get();
Integer age = girl.getAge();
if(age<10){
//返回“你还在上小学吧”
throw new Exception("你还在上小学吧");
}else if (age > 10 && age < 16){
//返回“你可能在上初中吧”
throw new Exception("你可能在上初中吧");
}
}
}
GirlController类中添加getAge方法
package com.imooc.controller;
import com.imooc.domain.Girl;
import com.imooc.domain.Result;
import com.imooc.repository.GirlRepository;
import com.imooc.service.GirlService;
import com.imooc.utils.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
public class GirlController {
private final static Logger logger = LoggerFactory.getLogger(GirlController.class);
@Autowired
private GirlRepository girlRepository;
@Autowired
private GirlService girlService;
/**
* 查询所有女生列表
* @return
*/
@GetMapping(value = "/girls")
public List<Girl> girlList(){
logger.info("girlList");
return girlRepository.findAll();
}
/**
* 添加一个女生
* @return
*/
@PostMapping(value = "/girls")
public Result<Girl> girlAdd(@Valid Girl girl, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return ResultUtil.error(1,bindingResult.getFieldError().getDefaultMessage());
}
girl.setAge(girl.getAge());
girl.setCupSize(girl.getCupSize());
return ResultUtil.success(girlRepository.save(girl));
}
//查询一个女生
@GetMapping(value = "/girls/{id}")
public Girl girlFindOne(@PathVariable("id") Integer id){
Girl girl = null;
try {
girl = girlRepository.findById(id).get();
return girl;
}
catch (Exception e){
return girl;
}
}
//更新
@PutMapping(value = "/girls/{id}")
public Girl girlUpdate(@PathVariable("id") Integer id,
@RequestParam("cupSize") String cupSize,
@RequestParam("age") Integer age){
Girl girl = new Girl();
girl.setId(id);
girl.setCupSize(cupSize);
girl.setAge(age);
return girlRepository.save(girl);
}
//删除
@DeleteMapping(value = "/girls/{id}")
public void girlDelete(@PathVariable("id") Integer id){
girlRepository.deleteById(id);
}
//通过年龄查询女生列表
@GetMapping(value = "/girls/age/{age}")
public List<Girl> girlListByAge(@PathVariable("age") Integer age){
return girlRepository.findByAge(age);
}
@PostMapping(value = "/girls/two")
public void girlTwo(){
girlService.insertTwo();
}
@GetMapping(value = "/girls/getAge/{id}")
public void getAge(@PathVariable("id") Integer id) throws Exception{
girlService.getAge(id);
}
}
演示效果及流程解释
图片.png
现在还是会有返回给前端的数据不一致的问题,我们依旧希望是code,msg,data的格式。
直接往外抛出错误会出现上图中的结果,其实我们可以对这个异常进行一个捕获,然后取到我们希望拿到的内容,再给它封装返回给浏览器。
- 新建一个捕获异常的ExceptionHandle类
package com.imooc.Handle;
import com.imooc.domain.Result;
import com.imooc.utils.ResultUtil;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 最外层捕获
*/
@ControllerAdvice//捕获异常的类需要添加这个注解
public class ExceptionHandle{
//写一个捕获异常,且捕获后返回给浏览的方法,返回给浏览器Result类型的数据
@ExceptionHandler(value = Exception.class)//声明捕获哪个异常类
@ResponseBody//由于我们返回给浏览器那边是一个json格式。类上又没有RestController注解,所以这个地方需要写明@ResponseBody
public Result handle(Exception e){
return ResultUtil.error(100,e.getMessage());
}
}
图片.png
“你还在上小学吧”和“可能在上初中吧”错误应该是不同的code,但现在都是100
图片.png
因为GirlService类往外抛Exception错误时只能传String message,
图片.png
在最外层捕获ExceptionHandle类里也就只能把code写死100了。
图片.png
- 这时候需要我们自己来写一个自己的Exception类:GirlException
package com.imooc.exception;
public class GirlException extends RuntimeException{//注意需要继承一个runtimeException,因为Spring框架只会对你抛出的runtimeException才会进行事物回滚,如果抛出Exception是不会进行事物回滚的
private Integer code;
public GirlException(Integer code,String message){
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
修改GirlService类的getAge方法在抛出异常时的类型为GirlException
public void getAge(Integer id) throws Exception{
Girl girl = girlRepository.findById(id).get();
Integer age = girl.getAge();
if(age<10){
//返回“你还在上小学吧”
throw new GirlException(100,"你还在上小学吧");
}else if (age > 10 && age < 16){
//返回“你可能在上初中吧”
throw new GirlException(101,"你可能在上初中吧");
}
}
修改最外层捕获类ExceptionHandle的handle方法
/**
* 最外层捕获
*/
@ControllerAdvice//捕获异常的类需要添加这个注解
public class ExceptionHandle{
//写一个捕获异常,且捕获后返回给浏览的方法,返回给浏览器Result类型的数据
@ExceptionHandler(value = Exception.class)//声明捕获哪个异常类
@ResponseBody//由于我们返回给浏览器那边是一个json格式。类上又没有RestController注解,所以这个地方需要写明@ResponseBody
public Result handle(Exception e){//抛出的异常作为实参传给形参e
if(e instanceof GirlException){
GirlException girlException = (GirlException)e;
return ResultUtil.error(girlException.getCode(),girlException.getMessage());
}else{
return ResultUtil.error(-1,"系统的错误,不在GirlServce预期之内的异常");
}
}
}
效果演示:
在“你可能在上初中吧”该种类型的错误的情况时,其code是101
图片.png
getAge没有抛出错误(age为18)->getAge没有抛出错误->执行doAgterReturning方法->null.toString报错->被最外层ExceptionHandle捕获->返回Reslut
图片.png
- 将系统类型的错误打印在控制台以便排除错误
/**
* 最外层捕获
*/
@ControllerAdvice//捕获异常的类需要添加这个注解
public class ExceptionHandle{
private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
//写一个捕获异常,且捕获后返回给浏览的方法,返回给浏览器Result类型的数据
@ExceptionHandler(value = Exception.class)//声明捕获哪个异常类
@ResponseBody//由于我们返回给浏览器那边是一个json格式。类上又没有RestController注解,所以这个地方需要写明@ResponseBody
public Result handle(Exception e){//抛出的异常作为实参传给形参e
if(e instanceof GirlException){
GirlException girlException = (GirlException)e;
return ResultUtil.error(girlException.getCode(),girlException.getMessage());
}else{
logger.error("【系统异常】{}",e);
return ResultUtil.error(-1,"系统的错误,不在GirlServce预期之内的异常");
}
}
}
效果演示:
在控制台打印出了异常
2019-02-15 20:45:47.638 ERROR 9516 --- [nio-8080-exec-1] com.imooc.Handle.ExceptionHandle : 【系统异常】{}
java.lang.NullPointerException: null
at com.imooc.aspect.HttpAspect.doAgterReturning(HttpAspect.java:52) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) ~[spring-aop-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:626) ~[spring-aop-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.aop.aspectj.AspectJAfterReturningAdvice.afterReturning(AspectJAfterReturningAdvice.java:66) ~[spring-aop-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:56) ~[spring-aop-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at ...(部分)
- 用枚举维护错误类型列表
定义枚举
package com.imooc.enums;
public enum ResultEnum {
UNKNOWN_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;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
修改GirlService的getAge方法
public void getAge(Integer id) throws Exception{
Girl girl = girlRepository.findById(id).get();
Integer age = girl.getAge();
if(age<10){
//返回“你还在上小学吧”
throw new GirlException(ResultEnum.PRIMARY_SCHOOL);
}else if (age > 10 && age < 16){
//返回“你可能在上初中吧”
throw new GirlException(ResultEnum.MIDDLE_SCHOOL);
}
}
修改GirlException类构造方法
package com.imooc.exception;
import com.imooc.enums.ResultEnum;
public class GirlException extends RuntimeException{//注意需要继承一个runtimeException,因为Spring框架只会对你抛出的runtimeException才会进行事物回滚,如果抛出Exception是不会进行事物回滚的
private Integer code;
public GirlException(ResultEnum resultEnum){
super(resultEnum.getMsg());
this.code = resultEnum.getCode();
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
网友评论