brief introduction
Repeat function for me to write.There are global exception handling and return wrapping in the SpringBoot project, and the return front end is with fields such as succ, code, msg, data, and so on.Single project scenario is a good solution, when there are many micro-service modules, many cases of development are to copy the original code to build another project, resulting in the upgrade of these functions need to modify multiple services, on this basis, we encapsulate a component unified-dispose-spring-cloud-starter It contains some basic exception handling and return wrapping.
Dependent Add Startup Function
Add Dependency
ps: Use the latest version for the actual version
Latest version:
Click to view the latest version
<dependency> <groupId>com.purgeteam.cloud</groupId> <artifactId>unified-dispose-spring-cloud-starter</artifactId> <version>0.3.0.RELEASE</version> </dependency>
Startup class adds the @EnableGlobalDispose annotation to turn on the following features.
@EnableGlobalDispose @SpringBootApplication public class GlobalDisposeSpringBootApplication { public static void main(String[] args) { SpringApplication.run(GlobalDisposeSpringBootApplication.class, args); } }
One exception handling⚠️
System exceptions, such as NullPointerException, are common in projects.If the default is not handled, springboot will respond to the default error prompt, which is not friendly to the user experience, system-level errors that the user cannot perceive, even if the error is 500, you can prompt the user with a friendly prompt similar to a server error, and so on.
The module contains some basic exception handling (and already has basic exception handling without any coding), as well as some common exception code s, which users only need to care about handling business exceptions and can throw directly by throw new exceptions.
Exception Handling Containment Type
#General 500 Exception Exception class catches 500 exception handling # Feign exception FeignException class capture ClientException class capture #Business Customization BusinessException class catches business common custom exceptions #Parameter Check Exception HttpMessageNotReadableException parameter error exception BindException parameter error exception
Program actively throws an exception
throw new BusinessException(BusinessErrorCode.BUSINESS_ERROR); // perhaps throw new BusinessException("CLOUD800","No excess inventory");
It is not generally recommended to throw generic BusinessException exceptions directly. Instead, add exception handling classes for corresponding domains and corresponding enumeration error types to the corresponding modules.
For example, membership module:
Create UserException exception class, UserErrorCode enumeration.
UserException:
Inherit BusinessException
/** * {@link RuntimeException} user Business Exceptions * * @author purgeyao * @since 1.0 */ @Getter public class UserException extends BusinessException { private String code; private boolean isShowMsg = true; /** * Use enumeration parameters * * @param errorCode Exception Enumeration */ public UserException(UserErrorCode errorCode) { super(errorCode.getCode(), errorCode.getMessage()); this.code = errorCode.getCode(); } }
UserErrorCode:
@Getter public enum UserErrorCode { /** * Permission Exception */ NOT_PERMISSIONS("CLOUD401","You do not have permission to operate"), ; private String code; private String message; UserErrorCode(String code, String message) { this.code = code; this.message = message; } }
The final business use is as follows:
// Determine whether you have permission to throw exceptions throw new UserException(UserErrorCode.NOT_PERMISSIONS);
In this way, the exception is thrown and handled by the module.The foreground returns as follows:
{ "succ": false, // Success or not "ts": 1566467628851, // time stamp "data": null, // data "code": "CLOUD800", // Error Type "msg": "Business Exceptions", // Error Description }
Tow Unified Return Encapsulation_
In REST-style development, avoid informing the foreground about success and status codes.Here we usually return with a util wrapper, such as Result-like classes containing fields such as succ, code, msg, data, and so on.
Interface call handling is similar to the following:
@GetMapping("hello") public Result list(){ return Result.ofSuccess("hello"); }
Result:
{ "succ": ture, // Success or not "ts": 1566467628851, // time stamp "data": "hello", // data "code": null, // Error Type "msg": null, // Error Description "fail": true }
Functional Use
By default, all web controller s are encapsulated in the following return format.
Interface:
@GetMapping("test") public String test(){ return "test"; }
Return
{ "succ": true, // Success or not "ts": 1566386951005, // time stamp "data": "test", // data "code": null, // Error Type "msg": null, // Error Description }
Ignore encapsulation annotation @IgnoreResponseAdvice
public @interface IgnoreResponseAdvice { /** * Whether to encapsulate global exception handling * @return true:Handle; false: No exception handling */ boolean errorDispose() default true; }
The @IgnoreResponseAdvice permissible range is: class + method, returns identifying all methods under this class on the class will ignore return encapsulation.
Interface:
@IgnoreResponseAdvice // Ignore data packaging to add to classes, methods @GetMapping("test") public String test(){ return "test"; }
Return to test
FeignClient calls exception return handling
The default FeignClient call exception returns a FeignException 500 exception, and because uniform exception handling is turned on, the callee's feign exception is handled and returned as a wrapped result.
Server:
@Override public Boolean testBoolean() throws Exception { throw new Exception("Analogue exception"); }
Caller side:
@GetMapping("testBoolean") public Boolean testBoolean() throws Exception { // Call service side exception // The following exception occurs if the server does not add @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(); }
So the exampleFeignClient#testBoolean call has a feign conversion exception.
The feign interface exception handling for the provider needs to be turned off here.Or add @IgnoreResponseAdvice (errorDispose = false) on this interface class with errorDispose set to false
/** * Adding IgnoreResponseAdvice#errorDispose to an exception does not require wrapping */ @Override @IgnoreResponseAdvice(errorDispose = false) public Boolean testBoolean() throws Exception { throw new Exception("Analogue exception"); }
summary
There are many duplicate code s in the project, and we can simplify them in some ways to reduce the amount of development.PurgeTeam has some excellent open source components that reduce daily development.
Sample code address: unified-dispose-spring-cloud-starter
Author GitHub:
Purgeyao Welcome to your attention
qq Group: 812321371 WeChat Group: MercyYao
WeChat Public Number:
This article is published by blog OpenWrite Release!