微服务架构之全局异常(@ControllerAdvice + @ExceptionHandler)

您所在的位置:网站首页 异常近义词怎么写 微服务架构之全局异常(@ControllerAdvice + @ExceptionHandler)

微服务架构之全局异常(@ControllerAdvice + @ExceptionHandler)

2023-12-31 19:54| 来源: 网络整理| 查看: 265

微服务架构之全局异常处理 一、定义全局异常处理类(GlobalExceptionHandler)1、在cloud-common模块中创建全局异常处理类GlobalExceptionHandler2、编写全局异常类代码 二、测试未使用全局异常捕捉方法异常1、启动user模块进行测试2、运行结果 三、测试使用全局异常捕捉方法异常1、user测试编码2、运行结果 四、Controller层使用@Valid +@RequestBody 校验入参对象属性

今天的学习内容是在微服务的公共模块中创建全局异常处理对象,对业务异常进行拦截处理,学完这篇将会学到从零开始也会编写全局异常处理类了。 我们在对业务进行处理时,当数据库操作失败,或遇到未受检测的异常时让 Service 层抛出运行时异常,Spring 事物管理器就会进行回滚。但是我们就会在Controller层编写try-catch 捕捉Service 层的异常,然后进行错误信息封装再返回给客户端,否则会返回一些不友好的错误信息到客户端。但是,Controller 层每个方法体都写一些模板化的 try-catch 的代码,这样的代码很冗余、臃肿、难维护,而且要对 Service 层的不同异常进行不同处理,那么业务逻辑就会更复杂。使用@ControllerAdvice + @ExceptionHandler 进行全局异常处理,可以简化Controller与Service层对业务异常的处理,使代码看起来更简洁、清晰、易维护。@ControllerAdvice 使用在类上,@ExceptionHandler使用在方法上。 一、定义全局异常处理类(GlobalExceptionHandler) 1、在cloud-common模块中创建全局异常处理类GlobalExceptionHandler

cloud-common模块搭建请参考前面章节,链接:https://editor.csdn.net/md/?articleId=109964260 在这里插入图片描述

2、编写全局异常类代码 package yooo.yun.com.common.exception; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authz.UnauthenticatedException; import org.apache.shiro.authz.UnauthorizedException; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.HttpMediaTypeException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import yooo.yun.com.common.api.ApiCode; import yooo.yun.com.common.api.ApiResult; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; /** * @author wangjiao * @since 2020/11/14 */ @ControllerAdvice @RestController @Slf4j public class GlobalExceptionHandler { /** * 非法参数验证异常 * * @param ex ex * @return res */ @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(value = HttpStatus.OK) public ApiResult handleMethodArgumentNotValidExceptionHandler( MethodArgumentNotValidException ex) { BindingResult bindingResult = ex.getBindingResult(); List list = new ArrayList(); List fieldErrors = bindingResult.getFieldErrors(); for (FieldError fieldError : fieldErrors) { list.add(fieldError.getDefaultMessage()); } Collections.sort(list); log.error("fieldErrors:[ex:{}]", JSON.toJSONString(list)); return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, list); } /** * 系统登录异常处理 * * @param exception exception * @return res */ @ExceptionHandler(value = SysLoginException.class) @ResponseStatus(HttpStatus.OK) public ApiResult sysLoginExceptionHandler(SysLoginException exception) { log.warn("sysLoginExceptionHandler:系统登录异常[exception:{}]", exception.getMessage()); return ApiResult.fail(ApiCode.LOGIN_EXCEPTION); } /** * HTTP解析请求参数异常 * * @param e e * @return res */ @ExceptionHandler(value = HttpMessageNotReadableException.class) @ResponseStatus(HttpStatus.OK) public ApiResult httpMessageNotReadableException(HttpMessageNotReadableException e) { log.error("httpMessageNotReadableException:[e:{}]", e.getMessage()); return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, ApiCode.PARAMETER_PARSE_EXCEPTION); } /** * HTTP * * @param exception exception * @return res */ @ExceptionHandler(value = HttpMediaTypeException.class) @ResponseStatus(HttpStatus.OK) public ApiResult httpMediaTypeException(HttpMediaTypeException exception) { log.error("httpMediaTypeException:[exception:{}]", exception.getMessage()); return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, ApiCode.HTTP_MEDIA_TYPE_EXCEPTION); } /** * 自定义业务/数据异常处理 * * @param exception exception * @return res */ @ExceptionHandler(value = {SpringBootPlusException.class}) @ResponseStatus(HttpStatus.OK) public ApiResult springBootPlusExceptionHandler(SpringBootPlusException exception) { log.error("springBootPlusException:[exception:{}]", exception.getMessage()); int errorCode; if (exception instanceof BusinessException) { errorCode = ApiCode.BUSINESS_EXCEPTION.getCode(); } else if (exception instanceof DaoException) { errorCode = ApiCode.DAO_EXCEPTION.getCode(); } else if (exception instanceof VerificationCodeException) { errorCode = ApiCode.VERIFICATION_CODE_EXCEPTION.getCode(); } else { errorCode = ApiCode.SPRING_BOOT_PLUS_EXCEPTION.getCode(); } return new ApiResult().setCode(errorCode).setMsg(exception.getMessage()); } /** * 登陆授权异常处理 * * @param exception exception * @return res */ @ExceptionHandler(value = AuthenticationException.class) @ResponseStatus(HttpStatus.OK) public ApiResult authenticationExceptionHandler(AuthenticationException exception) { log.error("authenticationExceptionHandler:[exception:{}]", exception.getMessage()); return new ApiResult() .setCode(ApiCode.AUTHENTICATION_EXCEPTION.getCode()) .setMsg(exception.getMessage()); } /** * 未认证异常处理 * * @param exception exception * @return res */ @ExceptionHandler(value = UnauthenticatedException.class) @ResponseStatus(HttpStatus.OK) public ApiResult unauthenticatedExceptionHandler(UnauthenticatedException exception) { log.error("unauthenticatedExceptionHandler:[exception:{}]", exception.getMessage()); return ApiResult.fail(ApiCode.UNAUTHENTICATED_EXCEPTION); } /** * 未授权异常处理 * * @param exception exception * @return res */ @ExceptionHandler(value = UnauthorizedException.class) @ResponseStatus(HttpStatus.OK) public ApiResult unauthorizedExceptionHandler(UnauthorizedException exception) { log.error("unauthorizedExceptionHandler:[exception:{}]", exception.getMessage()); return ApiResult.fail(ApiCode.UNAUTHORIZED_EXCEPTION); } /** * SQL 语法异常 * * @param exception exception * @return res */ @ExceptionHandler(value = BadSqlGrammarException.class) @ResponseStatus(HttpStatus.OK) public ApiResult badSqlGrammarException(BadSqlGrammarException exception) { log.info("badSqlGrammarException:[exception:{}]", exception.getMessage()); return ApiResult.fail(ApiCode.SQL_ERROR_EXCEPTION); } /** * 默认的异常处理 * * @param exception exception * @return res */ @ExceptionHandler(value = Exception.class) @ResponseStatus(HttpStatus.OK) public ApiResult exceptionHandler(Exception exception) { log.error("exceptionHandler:[exception:{}]", exception.getMessage()); if (Objects.nonNull(exception.getMessage())) { return ApiResult.fail(exception.getMessage()); } return ApiResult.fail(ApiCode.SYSTEM_EXCEPTION); } } 二、测试未使用全局异常捕捉方法异常 1、启动user模块进行测试 因为common模块是属于微服务的公共模块,所以其他微服务模块只需要在pom文件中引入common模块的依赖就可以直接使用common中配置的信息。user模块引入common模块依赖 yooo.yun.com cloud-common 1.0-SNAPSHOT compile 代码中Controller层使用try catch捕捉service抛出的异常,编码如下: package yooo.yun.com.user.controller.saas; import com.alibaba.fastjson.JSON; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.util.DigestUtils; import org.springframework.web.bind.annotation.*; import yooo.yun.com.common.api.ApiCode; import yooo.yun.com.common.api.ApiResult; import yooo.yun.com.common.entity.pojo.UserPoJo; import yooo.yun.com.common.entity.request.UserLoginReq; import yooo.yun.com.common.entity.request.UserReq; import yooo.yun.com.user.service.UserService; import javax.annotation.Resource; import javax.validation.Valid; import java.util.Objects; /** * @author WangJiao * @since 2020/10/14 */ @Slf4j @RequestMapping(value = "/saas/user") @RestController("sUserC") public class UserController { @Resource private UserService service; /** * 用户注册 * * @param req 注册信息 * @return obj */ @PostMapping("/register") @ApiOperation("注册") public ApiResult register(@Valid @RequestBody UserReq req){ log.info("register:[req:{}]", JSON.toJSONString(req)); if (!Objects.equals(req.getPassword(), req.getRePassword())) { return ApiResult.fail(ApiCode.USER_TWO_PASSWORDS_INCONSISTENT); } try{ UserPoJo findUser = service.getByTel(req.getTel()); if (Objects.nonNull(findUser)) { return ApiResult.fail(ApiCode.USER_ACCOUNT_REGISTERED); } // md5加密 req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes())); boolean res = service.save(UserPoJo.of(req)); log.info("register:[res:{}]", res); return ApiResult.ok(res); }catch (Exception e) { e.printStackTrace(); return ApiResult.fail(e.getMessage()); } } } UserService编码: package yooo.yun.com.user.service; import yooo.yun.com.common.entity.pojo.UserPoJo; import yooo.yun.com.common.service.BaseService; /** * @author WangJiao * @since 2020/11/12 */ public interface UserService extends BaseService { /** * query user info by tel * * @param tel the tel * @return user */ UserPoJo getByTel(String tel) throws Exception; } UserServiceImpl编码: package yooo.yun.com.user.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import yooo.yun.com.common.entity.pojo.UserPoJo; import yooo.yun.com.common.service.Impl.BaseServiceImpl; import yooo.yun.com.user.mapper.UserMapper; import yooo.yun.com.user.service.UserService; import javax.annotation.Resource; /** * @author WangJiao * @since 2020/11/12 */ @Slf4j @Service public class UserServiceImpl extends BaseServiceImpl implements UserService { @Resource private UserMapper mapper; @Override public UserPoJo getByTel(String tel) throws Exception{ log.info("getByTel:[tel:{}]", tel); return mapper.selectOne(Wrappers.lambdaQuery().eq(UserPoJo::getTel, tel)) throws Exception; } } 2、运行结果 sql异常,但是抛出了一段不友好的信息给客户端 在这里插入图片描述所以我们只要对BadSqlGrammarException进行异常信息拦截,客户端只需要提示sql异常即可。 org.springframework.jdbc.BadSqlGrammarException: Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'cloud_user.r_user' doesn't exist

在这里插入图片描述

三、测试使用全局异常捕捉方法异常 1、user测试编码 package yooo.yun.com.user.controller.saas; import com.alibaba.fastjson.JSON; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.util.DigestUtils; import org.springframework.web.bind.annotation.*; import yooo.yun.com.common.api.ApiCode; import yooo.yun.com.common.api.ApiResult; import yooo.yun.com.common.entity.pojo.UserPoJo; import yooo.yun.com.common.entity.request.UserLoginReq; import yooo.yun.com.common.entity.request.UserReq; import yooo.yun.com.user.service.UserService; import javax.annotation.Resource; import javax.validation.Valid; import java.util.Objects; /** * @author WangJiao * @since 2020/10/14 */ @Slf4j @RequestMapping(value = "/saas/user") @RestController("sUserC") public class UserController { @Resource private UserService service; /** * 用户注册 * * @param req 注册信息 * @return obj */ @PostMapping("/register") @ApiOperation("注册") public ApiResult register(@Valid @RequestBody UserReq req){ log.info("register:[req:{}]", JSON.toJSONString(req)); if (!Objects.equals(req.getPassword(), req.getRePassword())) { return ApiResult.fail(ApiCode.USER_TWO_PASSWORDS_INCONSISTENT); } UserPoJo findUser = service.getByTel(req.getTel()); if (Objects.nonNull(findUser)) { return ApiResult.fail(ApiCode.USER_ACCOUNT_REGISTERED); } // md5加密 req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes())); boolean res = service.save(UserPoJo.of(req)); log.info("register:[res:{}]", res); return ApiResult.ok(res); } } UserService代码: package yooo.yun.com.user.service; import yooo.yun.com.common.entity.pojo.UserPoJo; import yooo.yun.com.common.service.BaseService; /** * @author WangJiao * @since 2020/11/12 */ public interface UserService extends BaseService { /** * query user info by tel * * @param tel the tel * @return user */ UserPoJo getByTel(String tel); } UserServiceImpl实现类编码: package yooo.yun.com.user.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import yooo.yun.com.common.entity.pojo.UserPoJo; import yooo.yun.com.common.service.Impl.BaseServiceImpl; import yooo.yun.com.user.mapper.UserMapper; import yooo.yun.com.user.service.UserService; import javax.annotation.Resource; /** * @author WangJiao * @since 2020/11/12 */ @Slf4j @Service public class UserServiceImpl extends BaseServiceImpl implements UserService { @Resource private UserMapper mapper; @Override public UserPoJo getByTel(String tel) { log.info("getByTel:[tel:{}]", tel); return mapper.selectOne(Wrappers.lambdaQuery().eq(UserPoJo::getTel, tel)); } } 2、运行结果 返回友好的信息给客户端。 在这里插入图片描述 在这里插入图片描述原因是我们定义的全局异常类对业务层抛出的异常进行了拦截处理,这一段代码处理如下: /* SQL 语法异常 * * @param exception exception * @return res */ @ExceptionHandler(value = BadSqlGrammarException.class) @ResponseStatus(HttpStatus.OK) public ApiResult badSqlGrammarException(BadSqlGrammarException exception) { log.info("badSqlGrammarException:[exception:{}]", exception.getMessage()); return ApiResult.fail(ApiCode.SQL_ERROR_EXCEPTION); } 四、Controller层使用@Valid +@RequestBody 校验入参对象属性 @Valid +@RequestBody作用于Post或Put接口,校验对象中的基础属性字段,简化校验操作,减少对空参数的校验。user入参对象编码如下: package yooo.yun.com.common.entity.request; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; import java.io.Serializable; /** * 用户表 * * @author WangJiao * @since 2019-12-19 */ @Data @AllArgsConstructor @NoArgsConstructor @ApiModel("用户信息请求") public class UserReq implements Serializable { private static final long serialVersionUID = 1L; @NotBlank(message = "电话不能为空") @ApiModelProperty(value = "电话", example = "15675454322") private String tel; @NotBlank(message = "密码不能为空") @ApiModelProperty(value = "密码", example = "yyy23") private String password; @NotBlank(message = "确认密码不能为空") @ApiModelProperty(value = "确认密码", example = "yyy23") private String rePassword; @ApiModelProperty(value = "用户头像", example = "http://test.jpg") private String avatar; @NotBlank(message = "用户名不能为空") @ApiModelProperty(value = "姓名", example = "周深") private String name; public static UserReq of() { return new UserReq(); } } 测试方法 /** * 用户注册 * * @param req 注册信息 * @return obj */ @PostMapping("/register") @ApiOperation("注册") public ApiResult register(@Valid @RequestBody UserReq req){ log.info("register:[req:{}]", JSON.toJSONString(req)); if (!Objects.equals(req.getPassword(), req.getRePassword())) { return ApiResult.fail(ApiCode.USER_TWO_PASSWORDS_INCONSISTENT); } UserPoJo findUser = service.getByTel(req.getTel()); if (Objects.nonNull(findUser)) { return ApiResult.fail(ApiCode.USER_ACCOUNT_REGISTERED); } // md5加密 req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes())); boolean res = service.save(UserPoJo.of(req)); log.info("register:[res:{}]", res); return ApiResult.ok(res); } } 测试结果: 在这里插入图片描述控制台打印的错误信息如下: 2020-11-24 14:40:36.875 ERROR 21372 [nio-5050-exec-1] y.y.c.c.e.GlobalExceptionHandler [53] : fieldErrors:[ex:["密码不能为空"]] org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument at index 0 in method: public yooo.yun.com.common.api.ApiResult yooo.yun.com.user.controller.saas.UserController.register(yooo.yun.com.common.entity.request.UserReq), with 1 error(s): [Field error in object 'userReq' on field 'password': rejected value []; codes [NotBlank.userReq.password,NotBlank.password,NotBlank.java.lang.String,NotBlank];arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userReq.password,password]; arguments []; default message [password]]; default message [密码不能为空]] at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:138) at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124) at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:891) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:884) at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:858) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) 全局异常对非法参数异常进行了封装,返回友好的提示给前端: /** * 非法参数验证异常 * * @param ex ex * @return res */ @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(value = HttpStatus.OK) public ApiResult handleMethodArgumentNotValidExceptionHandler( MethodArgumentNotValidException ex) { BindingResult bindingResult = ex.getBindingResult(); List list = new ArrayList(); List fieldErrors = bindingResult.getFieldErrors(); for (FieldError fieldError : fieldErrors) { list.add(fieldError.getDefaultMessage()); } Collections.sort(list); log.error("fieldErrors:[ex:{}]", JSON.toJSONString(list)); return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, list); }

-_- 到这里,说明你已经get到了喔!需要的小伙伴,快动手练练吧!

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3