关闭页面特效

异常处理器

1|0异常处理器


1|1问题导入


问题1:项目各个个层级均可能出现异常,异常处理代码书写在哪一层?

1|2异常介绍


  • 程序开发过程中不可避免的会遇到异常现象,我们不能让用户看到这样的页面数据

image-20230612170442650

出现异常现象的常见位置与常见诱因如下:

  • 框架内部抛出的异常:因使用不合规导致
  • 数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时)
  • 业务层抛出的异常:因业务逻辑书写错误导致(例如:遍历业务书写操作,导致索引异常等)
  • 表现层抛出的异常:因数据收集、校验等规则导致(例如:不匹配的数据类型间导致异常)
  • 工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等)

image-20230612170502958

1|3异常处理器


编写异常处理器

异常处理器的底层原理,就是AoP。

@RestControllerAdvice是对Controller进行增强的,可以全局捕获spring mvc抛的异常。并匹配相应的@ExceptionHandler中指定的异常类型,重新封装异常信息,将统一格式返回给前端。

这个类所在的包要能够被Spring MVC扫描到

package com.tyhxzy.controller; import com.tyhxzy.entity.Result; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.HandlerExceptionResolver; /** * 统一异常处理器: * 作用:一旦发现controller抛出异常,就会去处理。 * 定义统一异常处理器步骤: * 1.该类使用@ControllerAdvice注解,表示该类是一个异常处理器 * 2. */ @ControllerAdvice //controller\RestController 出现异常可以去处理 //@RestControllerAdvice //只能处理Recontroller 出现异常,返回值默认就是json public class ProjectExceptionHandler { //@ExceptionHandler 处理的是那种类型的异常 @ExceptionHandler(Exception.class) @ResponseBody public Result handlerException(Exception e){ e.printStackTrace(); return new Result(4444,null,"您的网络异常,请稍后!"); } }

注意: springConfig类需要扫描exception包

使用异常处理器之后的效果

image-20230612170612611

@RestControllerAdvice注解介绍

  • 名称:@RestControllerAdvice
  • 类型:类注解
  • 说明:此注解自带@ResponseBody注解与@Component注解,具备对应的功能

@ExceptionHandler注解介绍

  • 名称:@ExceptionHandler
  • 类型:方法注解
  • 位置:专用于异常处理的控制器方法上方
  • 作用:设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行
  • 说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常

小结

如何定义异常处理器:
1. 自定义一个类,在类上添加@ControllerAdvice或者@RestControllerAdvice注解。 2. 定义一个方法,在方法上@ExceptionHandler指定处理那种类型的异常。

1|4项目异常处理方案


问题导入

请说出项目当前异常的分类以及对应类型异常该如何处理?

项目异常分类

  • 业务异常(BusinessException) /books/1
    • 规范的用户行为产生的异常
    • 不规范的用户行为操作产生的异常
  • 系统异常(SystemException)
    • 项目运行过程中可预计且无法避免的异常
  • 其他异常(Exception)
    • 编程人员未预期到的异常

项目异常处理方案

  • 业务异常(BusinessException)
    • 发送对应消息传递给用户,提醒规范操作
  • 系统异常(SystemException)
    • 发送固定消息传递给用户,安抚用户
    • 发送特定消息给运维人员,提醒维护
    • 记录日志
  • 其他异常(Exception)
    • 发送固定消息传递给用户,安抚用户
    • 发送特定消息给编程人员,提醒维护(纳入预期范围内)
    • 记录日志

项目异常处理代码实现

根据异常分类自定义异常类

自定义项目系统级异常
package com.tyhxzy.exceptions; import lombok.Data; /** * 异常异常,用户的操作不规范导致的。 * * 如何自定义一个异常: */ @Data public class SystemException extends RuntimeException { private Integer code; //表示是什么类型的异常 public SystemException(Integer code) { this.code = code; } public SystemException(Integer code,String message) { super(message); this.code = code; } }
自定义项目业务级异常
package com.tyhxzy.exceptions; /** * 业务异常,用户的操作不规范导致的。 * * 如何自定义一个异常: */ @Data public class BusinessException extends RuntimeException { private Integer code; //表示是什么类型的异常 public BusinessException(Integer code) { this.code = code; } public BusinessException(Integer code,String message) { super(message); this.code = code; } }

自定义异常编码(持续补充)

package com.tyhxzy.entity; public interface Code { //接口成员变量默认的修饰符 public static final Integer SAVE_OK = 20011; Integer DELETE_OK = 20021; Integer UPDATE_OK = 20031; Integer GET_OK = 20041; Integer SAVE_ERR = 20010; Integer DELETE_ERR = 20020; Integer UPDATE_ERR = 20030; Integer GET_ERR = 20040; //异常的状态码(新增) Integer SYSTEM_ERR = 50001; Integer SYSTEM_TIMEOUT_ERR = 50002; Integer SYSTEM_UNKNOW_ERR = 59999; Integer BUSINESS_ERR = 60002; }

触发自定义异常

package com.tyhxzy.controller; import com.tyhxzy.entity.Book; import com.tyhxzy.entity.Code; import com.tyhxzy.entity.Result; import com.tyhxzy.exceptions.BusinessException; import com.tyhxzy.exceptions.SystemException; import com.tyhxzy.service.BookService; import org.apache.ibatis.annotations.Delete; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.util.List; @Controller //把该类变成一个controller @RestController //@RestController作用: 1. 会把该类变成contrller, 2. 所有方法的返回值都是json @RequestMapping("/books") public class BookController { @Autowired private BookService bookService; /** * 查询单个图书 * restful风格对于查询使用get的请求方式 * @param id * @return */ @GetMapping("/{id}") public Result findById(@PathVariable("id") Integer id){ if(id<0){ throw new BusinessException(Code.BUSINESS_ERR,"数据有误"); } /* //模拟数据库服务器宕机 if(true){ throw new SystemException(Code.SYSTEM_ERR,"数据库宕机"); }*/ Book book = bookService.getById(id); if(book!=null){ return new Result(Code.GET_OK,book,"查询成功"); }else{ return new Result(Code.GET_ERR,book,"查询失败"); } } }

在异常通知类中拦截并处理异常

分别写三个方法用来捕获每种异常

package com.tyhxzy.controller; import com.tyhxzy.entity.Result; import com.tyhxzy.exceptions.BusinessException; import com.tyhxzy.exceptions.SystemException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.HandlerExceptionResolver; /** * 统一异常处理器: * 作用:一旦发现controller抛出异常,就会去处理。 * 定义统一异常处理器步骤: * 1.该类使用@ControllerAdvice注解,表示该类是一个异常处理器 * 2. */ @ControllerAdvice //controller\RestController 出现异常可以去处理 //@RestControllerAdvice //只能处理Recontroller 出现异常,返回值默认就是json public class ProjectExceptionHandler { @ExceptionHandler(SystemException.class) @ResponseBody public Result handlerSystemException(SystemException e){ e.printStackTrace(); return new Result(e.getCode(),null,e.getMessage()); } @ExceptionHandler(BusinessException.class) @ResponseBody public Result handlerBusinessException(BusinessException e){ e.printStackTrace(); return new Result(e.getCode(),null,e.getMessage()); } //@ExceptionHandler 处理的是那种类型的异常 @ExceptionHandler(Exception.class) @ResponseBody public Result handlerException(Exception e){ e.printStackTrace(); return new Result(4444,null,"您的网络异常,请稍后!"); } }

测试:在postman中发送请求访问getById方法,传递参数-1,得到以下结果:

image-20230612170855272

小结

1. 不同类型的异常处理方式其实不一样。 2. 统一异常处理器可以处理不同类型的异常。

文件上传的必要前提:

1form 表单的 enctype 取值必须是:multipart/form-data(默认值是:application/x-www-form-urlencoded)enctype:是表单请求正文的类型 2 method 属性取值必须是 Post 3、提供一个文件选择域<input type=”file”/>

文件上传原理分析

form 表单的 enctype 取值不是默认值后,request.getParameter()将失效。 enctype=”application/x-www-form-urlencoded”时,form 表单的正文内容是:key=value&key=value&key=value; form 表单的 enctype 取值为 Mutilpart/form-data 时,请求正文内容就变成:每一部分都是 MIME 类型描述的正文;

SpringMVC的文件上传

构建maven工程添加相关依赖

<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>

编写 jsp 页面

<form enctype="multipart/form-data" method="post" action="/file/fileUpload"> <input type="file" name="file"> <input type="submit" value="上传"> </form>

编写控制器

@RequestMapping("fileUpload") public String fileUpload(MultipartFile file){ File dest = new File("C:\\Users\\mwx\\Pictures\\"+file.getOriginalFilename()); //文件上传 try { file.transferTo(dest); } catch (IOException e) { e.printStackTrace(); } return "main"; }

配置文件解析器

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

测试文件上传的运行结果


__EOF__

作  者YXH
出  处https://www.cnblogs.com/YxinHaaa/p/17476566.html
关于博主:编程路上的小学生,热爱技术,喜欢专研。评论和私信会在第一时间回复。或者直接私信我。
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!

posted @   YxinHaaa  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
0
0
关注
跳至底部
点击右上角即可分享
微信分享提示