創造を続け、成長を加速させましょう!「ナゲッツデイリーニュープラン・6月アップデートチャレンジ」に参加して7日目です。クリックしてイベントの詳細をご覧ください。
SpringBoot例外処理
開発する方法は2つあります
- 1つは、javawebメソッドの開発に基づく従来の方法での開発であり、ビジネスコードとビューはプロジェクトで記述されます。
- フロントエンドとバックエンドは別々に開発されています。フロントエンドとバックエンドは分離されており、バックエンドはインターフェイスを作成するだけで済みます。
フロントエンドとバックエンドの分離開発は、フロントエンドとバックエンドの分離を実現することは間違いありません。従来の開発方法と比較して、フロントエンドとバックエンドの分離開発には多くの利点があります。将来的には、フロントエンドとバックエンドの分離開発が世界になると考えられます。
この記事のSpringBootの例外処理メカニズムについても、2種類の従来の開発と、フロントエンドおよびバックエンドの分離開発に基づいて説明します。
1.1従来のJavaWeb開発での例外処理
-
なぜ例外処理メカニズムが表示されるのですか?
- ユーザーリクエストの処理中にランタイム例外が発生すると、ユーザーのエラーインターフェイスに直接応答しますが、これはユーザーエクスペリエンスに適していません。
-
グローバル例外処理メカニズムとは何ですか
- これは、システム全体のいずれかのコントローラーが例外をスローしたときに、統合処理エントリを解決するために使用されます
-
グローバル例外処理の使用方法
- このクラスはHandlerExceptionResolverを実装してから、インターフェースのresolveExceptionメソッドを書き換えます。
-
グローバル例外処理メカニズムを使用する利点
-
ユーザーに比較的優れたユーザーエクスペリエンスをもたらすことができます
-
各コントローラーメソッドの例外処理にtry...catchを使用すると、コードの冗長性が発生し、例外処理メカニズムを使用して、例外が発生したときにすべてのコントローラーメソッドに統一された処理エントリを提供します。これにより、コードの冗長性の問題が解決されます。 。、また、ある程度のデカップリングを実現し、実際のビジネスメソッドから例外処理をデカップリングします。
-
さまざまな例外タイプに応じて、さまざまなページにジャンプできます
-
SpringBootはSpringMVCとSpringの利点を兼ね備えています。実際、SpringBootの例外処理メカニズムはSpringMVCの例外処理メカニズムにのみ準拠しています。以前にSpringMVCの例外処理メカニズムに関する記事を書きました。読んだ後は、例外処理メカニズムの一般的な理解。
次に、従来の方法(javaweb)でSpringBoot例外処理を使用してみましょう。
使用されるパッケージ構造
- 依存関係をインポートする
themeleafを使用するため、themeleafの依存関係をインポートし、構成ファイルでthemeleafテンプレートディレクトリとテンプレートサフィックスを構成する必要があります
<!--使用thymelaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
复制代码
application.yml
spring:
thymeleaf:
prefix: classpath:/templates/ # 指定thymeleaf模板前缀目录
suffix: .html # 指定模板的后缀
cache: false # 是否开启thymeleaf缓存,默认为true是开启的,在开发过程中建议 # 关了
复制代码
- application.yml構成ファイル
server:
port: 8081 # 设置项目端口号
spring:
thymeleaf:
prefix: classpath:/templates/ # 指定thymeleaf模板前缀目录
suffix: .html # 指定模板的后缀
cache: false # 是否开启thymeleaf缓存,默认为true是开启的,在开发过程中建议 # 关了
复制代码
- 使用したthemeleafテンプレート
注:themeleafを使用する場合は、htmlファイルを次のように変更する必要があります。
<html lang="en">
复制代码
着替える
<html lang="en" xmlns:th="http://www.thymeleaf.org">
复制代码
hello.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>hello html</title>
</head>
<body>
<h1>hello springboot</h1>
</body>
</html>
复制代码
500.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>hello html</title>
</head>
<body>
<h1>系统内部错误,请稍后再试...</h1>
</body>
</html>
复制代码
error.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>hello html</title>
</head>
<body>
<h1>系统错误: 用户名不正确!!!</h1>
</body>
</html>
复制代码
- カスタム例外クラスを開発する
// 自定义 用户名不存在异常
public class UserNameNotFoundException extends RuntimeException{
public UserNameNotFoundException(String message) {
super(message);
}
}
复制代码
- 開発コントローラー
@Controller
@RequestMapping("demo")
public class DemoController {
@RequestMapping("demo")
public String demo(){
System.out.println("demo ok ...");
int n = 1 / 0; // 除0异常
return "hello";
}
@RequestMapping("login")
public String login(String username, String password){
System.out.println("login ...");
System.out.println("username: " + username);
System.out.println("password: " + password);
if("xiaochen".equals(username) && "123".equals(password)){
return "hello";
}else {
throw new UserNameNotFoundException("用户名不正确!!");
//如果输入信息错误会抛出UserNameNotFoundException
}
}
}
复制代码
- 例外処理クラスを開発する
@Component // 在工厂中创建这个类的对象
public class GlobalExceptionSolver implements HandlerExceptionResolver {
// resolveException: 当控制器中任意一个方法出现异常时 如果该控制器的方法没有自己异常处理(try...catch),则会进入当前方法
// 在异常处理这个方法中,可以完成自定义的异常处理
// 参数1: 当前请求对象
// 参数2: 当前请求对应的响应对象
// 参数3: 当前方法对象
// 参数4: 出现异常时的异常对象
// 返回值: ModelAndView 模型和视图
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
System.out.println("这是全局异常处理....");
System.out.println("当前异常为: " + e);
ModelAndView modelAndView = new ModelAndView();
// 根据不同的异常类型跳转到不同的页面
if(e instanceof UserNameNotFoundException){
modelAndView.setViewName("error");
return modelAndView;
}
modelAndView.setViewName("500"); // 跳转到 500.html 这个页面
return modelAndView;
}
}
复制代码
- テスト
1.2フロントエンドとバックエンドを別々に開発する場合の例外処理
例外処理メカニズムの概念は前述したため、フロントエンドとバックエンドが分離されている場合は、例外処理の操作を直接実行します。
使用されるパッケージ構造
- 最初に例外クラスを定義します
// 自定义异常类 非法数字异常
public class IllegalNumberException extends RuntimeException{
public IllegalNumberException(String message) {
super(message);
}
}
复制代码
- 開発コントローラー
@RestController
@RequestMapping("demos")
public class DemoController {
@GetMapping
public ResponseEntity<String> demo(){
System.out.println("demo ok");
int n = 1/0;
return new ResponseEntity<>("demook", HttpStatus.OK);
}
@GetMapping("/{id}")
public ResponseEntity<String> demo1(@PathVariable("id") Integer id){
System.out.println("demo ok " + id);
if(id < 0) throw new IllegalNumberException("无效id,请检查!");
return new ResponseEntity<>("demo ok", HttpStatus.OK);
}
}
复制代码
- 例外処理クラスを開発する
@ControllerAdvice
// 这个注解应用于类上,表示这个类中的方法应用于全局所有controller,这个注解有一个value属性,默认
// 作用于所有controller
// 如果不想作用于所有controller,可以在value属性上指定哪些包可以用
public class GlobalExceptionResolver {
// 处理自定义异常
@ExceptionHandler(IllegalNumberException.class)
@ResponseBody
public ResponseEntity<String> illegalNumberExceptionHandler(Exception e){ // 方法名随便,不过为了望文生意,一般就取为exceptionHandler
System.out.println("进入非法参数异常处理");
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
// 处理Exception及其子类异常(几乎就是所有异常了)
@ExceptionHandler(Exception.class)
// 用在方法上 作用:用来处理指定异常 value属性: 用来处理指定异常类型
// 写Exception.class就是把Exception及其所有子类异常都处理了
@ResponseBody // 将方法的返回值以json的格式返回
public ResponseEntity<String> exceptionHandler(Exception e){ // 方法名随便,不过为了望文生意,一般就取为exceptionHandler
System.out.println("进入自定义异常处理");
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
// 服务器内部错误
}
}
复制代码
- テスト