デフォルトでは、SpringBoot には次の 3 つの戻り状況があります。
@GetMapping("/getUserName") public String getUserName(){ return "HuaGe"; }
インターフェイスを呼び出して結果を返します:
HuaGe
@GetMapping("/getUserName") public User getUserName(){ return new User("HuaGe",18,"男"); }
インターフェイスを呼び出します結果を返します:
{ "name": "HuaGe", "age": "18", "性别": "男", }
@GetMapping("/getUserName") public static String getUserName(){ HashMap hashMap = Maps.newHashMap(); return hashMap.get(0).toString(); }
ヌル ポインタ例外をシミュレートします。例外処理を行わずに、SpringBoot:## のデフォルトの戻り結果を確認できます。 #
{ "timestamp": "2021-08-09T06:56:41.524+00:00", "status": 500, "error": "Internal Server Error", "path": "/sysUser/getUserName" }上記の状況で、プロジェクト全体が統一された戻り形式を定義しておらず、5 人のバックエンド開発者が 5 つの戻り形式を定義している場合、コードが肥大化するだけでなく、フロントエンドとバックエンドのドッキングが発生します。フロントエンドが例外の詳細を直接表示するなど、特定の状況が発生すると、ユーザーのエクスペリエンスが非常に低下します。 2. 基本的なゲームプレイプロジェクトで最も一般的なことは、ツール クラスをカプセル化することです。返される必要があるフィールド情報はクラスで定義され、返される必要があるインターフェイス情報はクラスで定義されます。フロントエンドに返されるデータは、このクラスを通じてカプセル化されます。これにより、一貫性のない戻り形式の問題を解決できます。 2.1 パラメータの説明
code: ステータス コード。バックグラウンドではステータス コードの統一セットを維持できます。
message: 説明情報、インターフェイス呼び出しの成功/失敗のプロンプト情報;
data: データを返します。
#public class Result<T> {
private int code;
private String message;
private T data;
public Result() {}
public Result(int code, String message) {
this.code = code;
this.message = message;
}
/**
* 成功
*/
public static <T> Result<T> success(T data) {
Result<T> result = new Result<T>();
result.setCode(ResultMsgEnum.SUCCESS.getCode());
result.setMessage(ResultMsgEnum.SUCCESS.getMessage());
result.setData(data);
return result;
}
/**
* 失败
*/
public static <T> Result<T> error(int code, String message) {
return new Result(code, message);
}
}
public enum ResultMsgEnum { SUCCESS(0, "成功"), FAIL(-1, "失败"), AUTH_ERROR(502, "授权失败!"), SERVER_BUSY(503, "服务器正忙,请稍后再试!"), DATABASE_OPERATION_FAILED(504, "数据库操作失败"); private int code; private String message; ResultMsgEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return this.code; } public String getMessage() { return this.message; } }
#使用法
上記の 2 つの手順で を定義しますデータ戻り形式
と@GetMapping("/getUserName") public Result getUserName(){ return Result.success("huage"); }
呼び出し結果は以下の通りで、Resultで定義したパラメータの型であることがわかります。
{ "code": 0, "message": "成功", "data": "huage" }
この方法で書くことで日々のニーズを満たすことができ、多くの友人がこの方法を使用していると思いますが、多数のインターフェイスがある場合は、各インターフェイスで
Result.success## を使用します #返された情報をパッケージ化すると、繰り返されるコードが大量に追加されることになりますが、これは十分にエレガントではなく、見せびらかすには恥ずかしいことさえあります。コードを再度改善して最適な解決策を達成する方法が必要です。
3. 応用的な使い方
基本的な使い方を学んだ後は、主に次の 2 つの知識を使用した究極版を見てみましょう。 、または若い女性を指導することは必要なスキルです。 3.1 クラスの紹介
@RestControllerAdvice:
このアノテーションはコントローラーの拡張機能であり、スローされた例外をグローバルにキャプチャできます。
新しい
ResponseBodyAdvice インターフェイス、
supports
このクラスは、戻り値を均一にカプセル化するために使用されます。コントローラーの結果のインターフェイスの。
@RestControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice<Object> { @Autowired private ObjectMapper objectMapper; /** * 是否开启功能 true:是 */ @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) { return true; } /** * 处理返回结果 */ @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { //处理字符串类型数据 if(o instanceof String){ try { return objectMapper.writeValueAsString(Result.success(o)); } catch (JsonProcessingException e) { e.printStackTrace(); } } return Result.success(o); } }
Result
を直接使用して返される結果が一貫していることがわかります。ResponseAdvice では、結果の処理に
Result.success(o) が使用されており、エラー タイプの結果が「未処理」であることに気づいたはずです。例外が発生したときに返される結果は何でしょうか?上記の HashMap null ポインター例外コードを引き続き使用すると、テスト結果は次のようになります。
{ "code": 0, "message": "成功", "data": { "timestamp": "2021-08-09T09:33:26.805+00:00", "status": 405, "error": "Method Not Allowed", "path": "/sysUser/getUserName" } }形式には問題ありませんが、コードおよびデータ フィールド内の特定のデータが不親切であるか、正しくありません。これらの問題をうまく処理できないと、フロントエンドの姉妹の心の中の背の高いイメージに深刻な影響を与えることになり、これは決して許されません。
3.3 グローバル例外ハンドラ
過去に例外に遭遇したとき、最初に思い浮かんだのは try..catch..final でしたが、この方法では多くのことが起こります。メンテナンスの困難さやロジックの肥大化などの問題は、私たちが望む結果ではありません。
@RestControllerAdvice
アノテーションを追加します。このアノテーションの機能は Hua 兄弟がすでに紹介しているので、詳細は説明しません。@RestControllerAdvice public class CustomerExceptionHandler { }
@ExceptionHandler
アノテーションを使用して変更します。アノテーション パラメーターはターゲットの例外タイプです。例: コントローラーのインターフェイスで例外が発生すると、
Execption
ResponseAdviceメソッドは、データを統一形式でカプセル化し、フロントエンド パートナーに返します。
@RestControllerAdvice @Slf4j public class CustomerExceptionHandler { @ExceptionHandler(AuthException.class) public String ErrorHandler(AuthorizationException e) { log.error("没有通过权限验证!", e); return "没有通过权限验证!"; } @ExceptionHandler(Exception.class) public Result Execption(Exception e) { log.error("未知异常!", e); return Result.error(ResultMsgEnum.SERVER_BUSY.getCode(),ResultMsgEnum.SERVER_BUSY.getMessage()); } }
再次调用接口getUserName
查看返回结果,会发现还是有一些问题,因为我们在CustomerExceptionHandler
中已经将接口返回结果封装成Result
类型,而代码执行到统一结果返回类ResponseAdvice
时,又会结果再次封装,就出现了如下问题。
{ "code": 0, "message": "成功", "data": { "code": 503, "message": "服务器正忙,请稍后再试!", "data": null } }
解决上述问题非常简单,只要在beforeBodyWrite
中增加一条判断即可。
@RestControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice<Object> { @Autowired private ObjectMapper objectMapper; /** * 是否开启功能 true:开启 */ @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) { return true; } /** * 处理返回结果 */ @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { //处理字符串类型数据 if(o instanceof String){ try { return objectMapper.writeValueAsString(Result.success(o)); } catch (JsonProcessingException e) { e.printStackTrace(); } } //返回类型是否已经封装 if(o instanceof Result){ return o; } return Result.success(o); } }
以上がSpringBoot 統合インターフェイスの戻り値とグローバル例外を処理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。