SpringCloud exception handling unified encapsulation I do – use the article
Introduction to the
Let me write the repeat function. In the SpringBoot project, there are global exception handling and return packaging, etc., return front is with SUCC, code, MSG, data and other fields. It is easy to solve in the case of a single project. When there are many microservice modules, in many cases the development is to copy the original code to build another project, which results in the need to modify multiple services to upgrade these functions. On this basis, We have packaged a component called Unified Dispose – Spring-cloud-starter which contains some basic exception handling and return wrapper functionality.
Depend on add startup
Add the dependentps:Actual version Use the latest versionLatest version:
Check out the latest version
<dependency> <groupId>com.purgeteam.cloud</groupId> <artifactId>unified-dispose-spring-cloud-starter</artifactId> . < version > 0.3.0 RELEASE < / version > < / dependency >Copy the code
Startup class add the @enableGlobalDispose annotation to enable the following functions.
@EnableGlobalDispose @SpringBootApplication public class GlobalDisposeSpringBootApplication { public static void main(String[] args) { SpringApplication.run(GlobalDisposeSpringBootApplication.class, args); }}Copy the code
One Exception handling ⚠️
System exceptions, such as NullPointerExceptions, often occur in projects. If the default is not handled, SpringBoot will respond to the default error message, which is not friendly to the user experience. If the system level error is not perceived by the user, even if the error is 500, the user can be prompted with a friendly message like server alarm.
The module contains some basic exception handling methods (and does not need to do any coding already has basic exception handling), as well as some common exception code, users only need to care about business exception handling can be directly thrown by the way of new exception.
Exception handling contains types
# Common 500 Exception class catch 500 Exception handling # FeignException class catch FeignException ClientException class catch # Business custom BusinessException class catch Business general custom exception # parameters calibration abnormal HttpMessageNotReadableException error exception BindException parameter error exceptionCopy the code
The program actively throws an exception
throw new BusinessException(BusinessErrorCode.BUSINESS_ERROR); // throw new BusinessException("CLOUD800"," No excess inventory ");Copy the code
It is generally not recommended to throw a generic BusinessException directly. Instead, you should add a dome-specific exception handling class and the corresponding enumeration error type to the corresponding module.
Such as membership module: create UserException exception class, UserErrorCode enumeration.
UserException:
Inheritance BusinessException
/** * {@link RuntimeException} User service exception ** @author purgeyao * @since 1.0 */ Getter Public Class UserException extends BusinessException { private String code; private boolean isShowMsg = true; @param errorCode Error enumeration */ public UserException(UserErrorCode errorCode) {super(errorcode.getCode (), errorCode.getMessage()); this.code = errorCode.getCode(); }}Copy the code
UserErrorCode:
@getter Public enum UserErrorCode {/** * permissions failed */ NOT_PERMISSIONS("CLOUD401"," you do not have permissions "),; private String code; private String message; UserErrorCode(String code, String message) { this.code = code; this.message = message; }}Copy the code
The final service usage is as follows:
Throw new UserException(userErrorCode.not_permissions);Copy the code
In the above manner, the exception thrown will be handled by the module. The front desk returns the following:
"Ts ": 1566467628851, // Timestamp "data": null, // data" code": "CLOUD800", // error type" MSG ": "Service exception ", // Error description}Copy the code
Tow unified return package 🗳
In REST-style development, avoid telling the foreground whether the return was successful and the status code. Here we usually return the util wrapper work, such as: Result similar class, which contains succ, code, MSG, data and other fields.
Interface calls are handled like this:
@GetMapping("hello")
public Result list(){
return Result.ofSuccess("hello");
}Copy the code
Results:
{"succ": true, // successful "ts": 1566467628851, // Timestamp "data": "hello", // data" code": null, // error type "MSG ": Null, // error description "fail": true}Copy the code
Function using
By default, all Web Controllers are encapsulated in the following return format.
Interface:
@GetMapping("test")
public String test(){
return "test";
}Copy the code
return
{"succ": true, // successful "ts": 1566386951005, // timestamp "data": "test", // data" code": null, // error "MSG ": null, // error description}Copy the code
Ignore encapsulated annotations@IgnoreResponseAdvice
Public @interface IgnoreResponseAdvice {/** * Whether global exception handling encapsulates * @return true: this exception is processed; False: No exception handling */ Boolean errorDispose() default true; }Copy the code
The @ignoreresponseAdvice allows for: class + method, indicating that the return of all methods under this class on the class will ignore return encapsulation.
Interface:
@ignoreresponseadvice @getMapping ("test") public String test(){return "test"; }Copy the code
Return to the test
FeignClient
Invoke exception return handling
The default FeignClient call exception returns a FeignException 500 exception. Because uniform exception handling is enabled, the called feign exception is handled as a wrapped result.
Server:
@override public Boolean testBoolean() throws Exception {throw new Exception(" Exception "); }Copy the code
Calls to end:
@getMapping ("testBoolean") public Boolean testBoolean() throws Exception {// Exception occurs when calling the server. // If the server is not added IgnoreResponseAdvice(errorDispose = false) There was an unexpected error (type=Internal Server error, status=500). // Error while extracting response for type [class java.lang.Boolean] and content type [application/json; charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.lang.Boolean` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.Boolean` out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 1] return exampleFeignClient.testBoolean(); }Copy the code
So the exampleFeignClient#testBoolean call has a FEIGN conversion exception.
Here you need to turn off the provider’s FeIGN interface exception handling. Or add @ignoreresponseAdvice (errorDispose = false) to this interface class
/** * Add the IgnoreResponseAdvice#errorDispose set to an exception that does not need to be wrapped */ @override @ignoreresponseAdvice (errorDispose = false) public Boolean testBoolean() throws Exception {throw new Exception(" simulated Exception "); }Copy the code
conclusion
There are many duplicate codes in the project. We can simplify them in certain ways to reduce the amount of development. PurgeTeam has some excellent open source components that reduce the amount of day-to-day development.
Example code address :unified-dispose-spring-cloud-starter
GitHub: Purgeyao welcome to follow
Qq communication group: 812321371 wechat communication group: MercyYao
Wechat Official Account:
This article is published by OpenWrite!