SpringBootは@ControllerAdviceアノテーションを使用します

@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公式アカウントをフォローしてください。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/CharlesYooSky/article/details/106332283