@ControllerAdviceは、Spring 3.2によって提供される新しいアノテーションです。これは、コントローラーの@RequestMappingによってアノテーションが付けられたメソッドにロジックを追加できるコントローラーエンハンサーです。3つの主な機能があります
- コントローラのグローバル構成は、@ ControllerAdviceアノテーションを使用して同じ場所に配置できます。
- @ControllerAdviceアノテーションが付けられたクラスのメソッドは、@ ExceptionHandler、@ InitBinder、および@ModelAttributeでアノテーションが付けられます。
- @ExceptionHandler:コントローラーで例外をグローバルに処理し、グローバル例外処理を実行するために使用されます
- @InitBinder:WebDataBinderをセットアップするために使用され、フォアグラウンドリクエストパラメーターをモデルに自動的にバインドし、グローバルデータを前処理するために使用されます。
- @ModelAttribute:元の関数は、キーと値のペアをモデルにバインドすることです。ここで、グローバル@RequestMappingは、ここで設定されたキーと値のペア、およびグローバルデータバインディングを取得できます。
- @ControllerAdviceアノテーションは、@ RequestMappingアノテーションが付けられたすべてのコントローラーメソッドに適用されます。
グローバル例外処理:
@ExceptionHandlerと協力する必要があります。
コントローラーに例外をスローする場合、返されるjson形式を指定するか、エラーページにジャンプして、例外を均一に処理できます。
/**
* @ClassName:CustomExceptionHandler
* @Description: 全局异常捕获
* @Author:
* @Date: 2020/5/25、13:38
*/
@Slf4j
@ControllerAdvice(annotations = {Controller.class, RestController.class})
public class WebControllerAdvice {
@ResponseBody
@ExceptionHandler
public Map errorHandler(Exception ex) {
Map errorMap = new HashMap();
errorMap.put("code", 400);
//判断异常的类型,返回不一样的返回值
if (ex instanceof MissingServletRequestParameterException) {
errorMap.put("msg", "缺少必需参数:" + ((MissingServletRequestParameterException) ex).getParameterName());
} else if (ex instanceof MyException) {
errorMap.put("msg", "这是自定义异常");
}
return errorMap;
}
カスタム例外
/**
* @ClassName:MyException
* @Description: 定义异常
* @Author:
* @Date: 2020/5/25、13:44
*/
public class MyException extends RuntimeException {
private long code;
private String msg;
public MyException(Long code, String msg) {
super(msg);
this.code = code;
this.msg = msg;
}
public MyException(String msg) {
super(msg);
this.msg = msg;
}
}
テストコントローラー
@RestController
public class TestController {
@RequestMapping("testException")
public String testException() throws Exception{
throw new MissingServletRequestParameterException("name","String");
}
@RequestMapping("testMyException")
public String testMyException() throws MyException{
throw new MyException("i am a myException");
}
試験結果:
{"msg":"缺少必需参数:name","code":400}
{"msg":"这是自定义异常","code":400}
グローバルデータバインディング
グローバルデータバインディング関数を使用して、いくつかの初期データ操作を実行できます。@ ControllerAdviceアノテーションが付けられたクラスでいくつかのパブリックデータを定義できるため、各コントローラーのインターフェイスでデータにアクセスできます。手順を使用するには、最初にグローバルデータを次のように定義します。
/**
* @ClassName:MyGlobalDataHandler
* @Description: 全局数据
* @Author:
* @Date: 2020/5/25、14:01
*/
@ControllerAdvice
public class MyGlobalDataHandler {
@ModelAttribute(name = "md")
public Map<String,Object> getGlobalData(){
HashMap<String, Object> map = new HashMap<>();
map.put("age", 99);
map.put("gender", "男");
return map;
}
@ModelAttributeアノテーションを使用して、メソッドの戻りデータをグローバルデータとしてマークします。デフォルトでは、このグローバルデータのキーは返された変数名であり、値はメソッドの戻り値です。もちろん、開発者は-@ ModelAttributeアノテーションキーのname属性を使用して指定します。定義が完了すると、ここで定義されたデータは、任意のコントローラーインターフェイスで取得できます。
@GetMapping("/hello")
public String hello(Model model) {
Map<String, Object> map = model.asMap();
System.out.println(map);
int i = 1 / 0;
return "hello controller advice";
}
運転結果
{md={gender=男, age=99}}
2020-05-25 14:04:44.388 - [WARN ] - [org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver:logException:197] - Resolved [java.lang.ArithmeticException: / by zero]
グローバルデータ前処理
次のように定義された、BookとAuthorの2つのエンティティクラスがあるとします。
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Book extends BaseEntity {
private String name;
private Long price;
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Author extends BaseEntity {
private String name;
private Long price;
}
次のように、データ追加インターフェイスを定義すると、次のようになります。
@PostMapping("/book")
public void addBook(Book book, Author author) {
System.out.println(book);
System.out.println(author);
}
現時点では、両方のエンティティクラスに名前属性があり、フロントエンドから渡されたときに区別できないため、追加操作には問題があります。この時点で、@ ControllerAdviceのグローバルデータ前処理でこの問題を解決できます
解決手順は次のとおりです:
1。インターフェースの変数をエイリアスします:
@PostMapping("/book")
public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author) {
System.out.println(book);
System.out.println(author);
}
2.リクエストデータの前処理
を実行します。 @ ControllerAdviceでマークされたクラスに次のコードを追加します。
@InitBinder("b")
public void b(WebDataBinder binder) {
binder.setFieldDefaultPrefix("b.");
}
@InitBinder("a")
public void a(WebDataBinder binder) {
binder.setFieldDefaultPrefix("a.");
}
@InitBinder( "b")アノテーションは、メソッドがBookおよび関連パラメーターの処理に使用されることを示します。メソッドで、パラメーターにbプレフィックスを追加します。つまり、リクエストパラメーターにはbプレフィックスが必要です。
3.リクエストを送信します
リクエストが送信されると、さまざまなオブジェクトのパラメータにさまざまなプレフィックスを追加することで、パラメータを区別できます。
これは私のWeChat公式アカウントです:Program Yuanwei Magazineその他の記事については、WeChat公式アカウントをフォローしてください。