Secara lalai, SpringBoot akan mempunyai tiga situasi pemulangan berikut.
@GetMapping("/getUserName") public String getUserName(){ return "HuaGe"; }
Panggil antara muka untuk mengembalikan hasil:
HuaGe
Panggil antara muka untuk pulangkan hasil:
@GetMapping("/getUserName") public User getUserName(){ return new User("HuaGe",18,"男"); }
{ "name": "HuaGe", "age": "18", "性别": "男", }
mensimulasikan pengecualian penuding nol Tanpa sebarang pengendalian pengecualian, anda boleh melihat hasil pulangan lalai SpringBoot:
@GetMapping("/getUserName") public static String getUserName(){ HashMap hashMap = Maps.newHashMap(); return hashMap.get(0).toString(); }Untuk situasi di atas, jika keseluruhan projek tidak mentakrifkan format pemulangan bersatu dan lima pembangun bahagian belakang mentakrifkan lima format pemulangan, ini bukan sahaja akan menjadikan kod mengembang, bahagian hadapan dan belakang -Kecekapan dok hujung akan menjadi rendah, tetapi juga akan terdapat beberapa ketidakkonsistenan Apabila situasi tertentu berlaku, seperti bahagian hadapan secara langsung memaparkan butiran pengecualian, dll., ini memberikan pengguna pengalaman yang sangat buruk. 2. Permainan asas Perkara yang paling biasa dalam projek ialah merangkum kelas alat Maklumat medan yang perlu dikembalikan ditakrifkan dalam kelas, dan maklumat antara muka yang perlu dikembalikan ke bahagian hadapan dikapsulkan melalui kelas ini, ini boleh menyelesaikan masalah format pulangan yang tidak konsisten. 2.1 Perihalan Parameter
kod: kod status, latar belakang boleh mengekalkan set kod status bersatu
mesej: maklumat perihalan, maklumat pantas kejayaan/kegagalan panggilan antara muka;
{ "timestamp": "2021-08-09T06:56:41.524+00:00", "status": 500, "error": "Internal Server Error", "path": "/sysUser/getUserName" }
Tentukan kembali kod status
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); } }
Kaedah penggunaan
dan , kemudian mari kita lihat cara menggunakannya dalam antara muka.
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; } }Hasil panggilan adalah seperti berikut. Anda boleh melihat bahawa ia adalah jenis parameter yang kami takrifkan dalam Hasil. Walaupun
@GetMapping("/getUserName") public Result getUserName(){ return Result.success("huage"); }boleh ditulis seperti ini untuk memenuhi keperluan harian, dan saya percaya ramai rakan menggunakannya dengan cara ini, tetapi jika kita mempunyai bilangan antara muka yang banyak, dan kemudian gunakan
dalam setiap antara muka untuk membungkus mengembalikan maklumat, Banyak kod pendua akan ditambah, yang kelihatan tidak elegan malah memalukan untuk dipamerkan. Mesti ada cara untuk memperbaiki kod sekali lagi dan mencapai penyelesaian yang optimum. 数据返回格式
状态码
3. Penggunaan Lanjutan
Selepas mempelajari penggunaan asas, mari kita lihat versi muktamad, yang kebanyakannya menggunakan dua mata pengetahuan berikut, sama ada ia digunakan untuk mengajar kanak-kanak perempuan , atau Memberi bimbingan kepada wanita muda adalah kemahiran yang diperlukan.
3.1 Pengenalan KelasResult.success
ResponseBodyAdvice:
Antara muka ini disediakan oleh SpringMVC 4.1, yang membenarkan data pengembalian tersuai selepas melaksanakan@RestControllerAdvice: Anotasi ini adalah peningkatan kepada Pengawal dan boleh menangkap pengecualian yang dilemparkan secara global. @ResponseBody
Buat kelas
, ResponseAdvice
Kelas ini digunakan untuk merangkum secara seragam hasil pulangan antara muka dalam pengawal. ResponseBodyAdvice
supports
beforeBodyWrite
{ "code": 0, "message": "成功", "data": "huage" }Kami boleh mengujinya melalui antara muka
@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); } }
getUserName
Walaupun tiada masalah dalam format, data khusus dalam medan kod dan data adalah tidak mesra atau tidak betul. Kegagalan untuk menangani perkara ini dengan baik akan menjejaskan imej tinggi seseorang dalam minda kakak bahagian hadapan, yang tidak akan pernah diterima. Result
3.3 Pengendali Pengecualian GlobalResponseAdvice
Apabila kami menghadapi pengecualian pada masa lalu, perkara pertama yang kami fikirkan ialah mencuba..tangkap..akhir. Walau bagaimanapun, kaedah ini akan membawa kepada banyak perkara Pertindihan kod Masalah seperti kesukaran dalam penyelenggaraan dan logik kembung bukanlah hasil yang kita inginkan. Result.success(o)
Brother Hua telah pun memperkenalkan fungsi anotasi ini di atas, jadi saya tidak akan menjelaskan butirannya lagi.
{ "code": 0, "message": "成功", "data": { "timestamp": "2021-08-09T09:33:26.805+00:00", "status": 405, "error": "Method Not Allowed", "path": "/sysUser/getUserName" } }
dan maklumat pengecualian yang tidak kemas akan ditukar kepada format yang ditentukan dan diserahkan kepada @RestControllerAdvice
kaedah untuk enkapsulasi format bersatu dan Kembali kepada rakan kongsi bahagian hadapan.
@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); } }
Atas ialah kandungan terperinci Cara mengendalikan pulangan antara muka bersatu SpringBoot dan pengecualian global. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!