SpringBoot异常处理器的使用与添加员工功能实现流程介绍

作者:懒羊羊.java 时间:2021-10-21 19:24:23 

承接上文 传送门

一.完善登录功能

按照常理,只有登陆过后才能进入首页,若没有登陆则应当直接跳转到登陆页面,这样的场景不就完美契合过滤器的功效吗

下面,针对此功能来设计一个过滤器

@Slf4j
@WebFilter(filterName = "loginFilterCheck", urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
   @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
       HttpServletRequest request = (HttpServletRequest) servletRequest;
       HttpServletResponse response = (HttpServletResponse) servletResponse;
       log.info("拦截到请求:{}", request.getRequestURI());//{}相当于一个占位符 可以实现动态变更
       filterChain.doFilter(request,response);
   }
}

通过它可以拦截到来自页面的请求

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

对于拦截的请求,我们要做如下的处理:

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

1、获取本次请求的URI,并定义不需要放行的资源路径

//获取本次请求的uri
       String requestURI = request.getRequestURI();
       //定义不需要处理的资源路径
       String[] urls=new String[]{
         "/employee/login",
               "/employee/logout",
               "/backend/**",
               "/front/**"
       };

为了解决通配符的引入而造成的路径比较问题,我们可以通过路径匹配器AntPathMatcher()来解决(由Spring为我们提供的工具)

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

2、判断本次请求是否需要处理

当我们拿到工具对象之后,就可以通过遍历字符串数组的方式,将请求中的uri与事先设定中不需要拦截资源路径进行对比,然后封装成一个check方法,就像这样:

public boolean check(String[] urls,String requestURI){
       for (String url : urls) {
           boolean match = PATH_MATCHER.match(url, requestURI);
           if (match){
               return true;
           }
       }
       return false;
   }

3.如果是不需要处理的资源路径则直接放行

//判断是否需要处理
       boolean check = check(urls, requestURI);
       //如果不需要处理就直接放行
       if (check){
           filterChain.doFilter(request,response);
           return;
       }

4、判断登录状态,如果已登录,则直接放行,如果未登录则返回未登录结果(通过从Session里获得对象,查看是否为空来进行评判)

//查看登陆状态 如果已登录 则直接放行
       if (!(request.getSession().getAttribute("employee") == null)) {
           filterChain.doFilter(request, response);
           return;
       }
       //如果未登录,则通过输出流的方式向客户端页面响应数据
       response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));

二.添加员工功能

前端页面已将写好,,当用户录入信息,就伴随着一次请求,而后端要做的就是将在请求中将表单里的数据保存到数据库中

新增员工,其实就是将我们添加页面录入的员工数据插入到employee表。需要注意,employee表中对username字段加入了唯一约束,因为username是员工的登录账号,必须是唯一的

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

我们该如何实现?

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

1、当页面发送ajax请求,表单中输入的数据以json的形式提交到服务器端

2、服务端Controller层接收页面提交的数据并调用Service层将数据进行保存

3、Service调用Mapper操作数据库,保存数据

Controller层如何设计呢?

1.毋庸置疑的是,首先要封装一个用于保存的方法save()

2.其次HttpServletRequest里已经封装了表单的数据,当一次请求发生其中的数据就被当作形参传入了方法内,随即就是设置表单中没有的属性,比如:setCreateTime,setUpdateTime,setCreateUser,setUpdateUser

总而言之,方法里涵盖了表单里提交的数据和请求发生后动态变更的数据,而我们写好了save()方法之后,就得去用Service层(employeeService)来执行这个方法将数据保存到数据库中,就像这样:

@PostMapping //前端的请求路径为employee,而上述@RequestMapping("/employee")已写好
   public R<String> save(HttpServletRequest request, @RequestBody Employee employee) {
       log.info("新增员工:{}", employee.toString());
       //设置初始默认密码
      employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
       //设置更新时间
       employee.setCreateTime(LocalDateTime.now());//创建时间
       employee.setUpdateTime(LocalDateTime.now());//更新时间
       //获取当前登录用户的id
       Long empID = (Long) request.getSession().getAttribute("employee");
       employee.setCreateUser(empID);
       employee.setUpdateUser(empID);
       return R.success("添加员工成功!");
   }

当我们在前端表单中填好了新增员工的信息后,点击保存,后台就执行如下的SQL:

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

三.异常处理的运用

写好了添加的方法,我激动得添加了好几个员工,但是当我添加了一个同名员工之后,程序运行的戛然而止,后台竟然抛出了异常:java.sql.SQLIntegrityConstraintViolationException

前端也报出了接口错误500,结合之前的表设计,不难想到我的username索引设置的是unique呀!唯一约束!

很显然

我们需要处理这个异常,很多人第一时间想到的可能是:这则错误是service层调用save()方法所导致的,那我把save()方法try-catch不就行了吗?

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

这样想确实没毛病是我的话我也这样,可是以后业务一旦复杂起来,需要这样处理的方法多了怎么办呢?我要去一个一个try-catch吗?多麻烦啊!

这不就是所谓的硬编码问题嘛!处理这种问题咱们在一个地方统一配置一下不久统统解决啊,跟MyBatis解决JDBC硬编码问题是一个道理!

所以,我们使用异常 * 进行全局异常捕获,这样设置就轻松化解:

/**
* 全局异常处理
*/
@ControllerAdvice(annotations = {RestController.class, Controller.class}) //拦截有指定注解类的Controller
@Slf4j
@ResponseBody
public class GlobalExceptionHandler {
   /**
    * 异常处理方法,一旦Controller发生此异常就会被拦截到
    * @return
    */
   @ExceptionHandler({SQLIntegrityConstraintViolationException.class})
   public R<String>  excpHandler(SQLIntegrityConstraintViolationException exception) {//捕获到的异常被传到方法的形参里
      log.info("异常信息:"+exception.getMessage());
       //细化添加失败后的返回信息
       if (exception.getMessage().contains("Duplicate entry")){
           String[] s = exception.getMessage().split(" ");
           String msg=s[2]+"已存在!";
           return R.error(msg);
       }
       return R.error("发生异常!添加失败!");
   }
}

一旦Controller层发生此异常就会被拦截到!

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

通过Debug,当程序出现因为重复添加而引起的异常时我们的msg就被细化了出来

SpringBoot异常处理器的使用与添加员工功能实现流程介绍

来源:https://iyu77.blog.csdn.net/article/details/127130230

标签:SpringBoot,全局,异常处理
0
投稿

猜你喜欢

  • mybatis-plus 查询传入参数Map,返回List<Map>方式

    2022-01-05 13:39:24
  • Java原生HttpClient的使用详解

    2022-06-04 16:29:49
  • Flutter 剪裁组件的使用

    2023-06-18 13:15:04
  • C#中DataTable排序、检索、合并等操作实例

    2022-08-22 04:58:03
  • Java Servlet简单实例分享(文件上传下载demo)

    2022-03-03 06:35:04
  • Android日期选择器实现年月日三级联动

    2022-12-13 03:35:59
  • Android自定义有限制区域的图例角度自识别涂鸦工具类完结篇

    2022-10-22 23:05:13
  • Android 使用 SharedPreferences 保存少量数据的实现代码

    2023-07-03 01:00:11
  • Android Studio的中文乱码问题解决方法

    2023-06-05 04:48:14
  • SpringCloud全面解析@FeignClient标识接口的过程

    2023-08-05 12:34:44
  • 利用spring的拦截器自定义缓存的实现实例代码

    2022-07-22 00:44:47
  • Java中List Set和Map之间的区别_动力节点Java学院整理

    2022-12-11 04:57:38
  • java 中HttpClient传输xml字符串实例详解

    2023-11-24 13:40:54
  • Android Studio快捷键生成TAG、Log.x日志输出介绍

    2022-03-14 02:10:37
  • 在Spring使用iBatis及配置讲解

    2021-07-06 20:07:39
  • 详解Java关键字final

    2023-11-29 09:10:27
  • Java源码解析之接口List

    2022-06-13 08:46:44
  • java swing实现的扫雷游戏及改进版完整示例

    2022-02-27 02:01:18
  • java中分组统计的三种实现方式

    2023-05-29 06:04:13
  • SpringBoot自定义maven-plugin插件整合asm代码插桩

    2021-05-24 02:15:49
  • asp之家 软件编程 m.aspxhome.com