自己做的视频网站上传电影,html5网页制作课程,域名服务商有哪些,家居企业网站建设市场本文内容为什么要全局异常处理#xff1f;WebFlux REST 全局异常处理实战小结摘录#xff1a;只有不断培养好习惯#xff0c;同时不断打破坏习惯#xff0c;我们的行为举止才能够自始至终都是正确的。一、为什么要全局异常处理#xff1f;前后端分离开发#xff0c;一般提…本文内容为什么要全局异常处理WebFlux REST 全局异常处理实战小结摘录只有不断培养好习惯同时不断打破坏习惯我们的行为举止才能够自始至终都是正确的。一、为什么要全局异常处理前后端分离开发一般提供 REST API正常返回会有响应体异常情况下会有对应的错误码响应。挺多人咨询的Spring Boot MVC 异常处理用切面 RestControllerAdvice 注解去实现去全局异常处理。那 WebFlux 如何处理异常如何实现统一错误码异常处理全局异常处理的好处异常错误码等统一维护避免一些重复代码二、WebFlux REST 全局异常处理实战下面介绍如何统一拦截异常进行响应处理。2.1 工程信息运行环境JDK 7 或 8Maven 3.0技术栈SpringBoot 2.1.3模块工程名: 2-x-spring-boot-webflux-handling-errors工程结构├── pom.xml└── src└── main├── java│ └── org│ └── spring│ └── springboot│ ├── Application.java│ ├── error│ │ ├── GlobalErrorAttributes.java│ │ ├── GlobalErrorWebExceptionHandler.java│ │ └── GlobalException.java│ ├── handler│ │ └── CityHandler.java│ └── router│ └── CityRouter.java└── resources└── application.properties复制代码application.properties 无须配置默认即可Application Spring Boot 应用启动类是可以用来启动 Spring Boot 应用。其包含了 SpringBootApplication 注解和 SpringApplication 类并调用 SpringApplication 类的 run() 方法就可以启动该应用。具体实现类的关系图如下2.2 CityRouter 路由器类城市路由器代码如下Configurationpublic class CityRouter {Beanpublic RouterFunction routeCity(CityHandler cityHandler) {return RouterFunctions.route(RequestPredicates.GET(/hello).and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), cityHandler::helloCity);}}复制代码RouterFunctions 对请求路由处理类即将请求路由到处理器这将一个 GET 请求 /hello 路由到处理器 cityHandler 的 helloCity 方法上。跟 Spring MVC 模式下的 HandleMapping 类似。RouterFunctions.route(RequestPredicate, HandlerFunction) 方法对应的 参是请求参数和处理函数如果请求匹配就调 对应的处理器函数。2.3 CityHandler 服务处理类城市服务器处理类代码如下Componentpublic class CityHandler {public Mono helloCity(ServerRequest request) {return ServerResponse.ok().body(sayHelloCity(request), String.class);}private Mono sayHelloCity(ServerRequest request) {Optional cityParamOptional request.queryParam(city);if (!cityParamOptional.isPresent()) {throw new GlobalException(HttpStatus.INTERNAL_SERVER_ERROR, request param city is ERROR);}return Mono.just(Hello, cityParamOptional.get());}}复制代码Mono实现发布者并返回 0 或 1 个元素即单对象。Mono 是响应流 Publisher 具有基础 rx 操作符。可以成功发布元素或者错误。用 Mono 作为返回对象是因为返回包含了一个 ServerResponse 对象而不是多个元素。ServerResponse 是对响应的封装可以设置响应状态响应头响应正文。比如 ok 代表的是 200 响应码、MediaType 枚举是代表这文本内容类型、返回的是 String 的对象。ServerRequest 是对请求的封装。从请求中拿出 city 的值如果没有的话则抛出对应的异常。GlobalException 是封装的全局异常。Mono.justOrEmpty()从一个 Optional 对象或 null 对象中创建 Mono。2.4 GlobalError 处理类如图GlobalException 全局异常类代码如下public class GlobalException extends ResponseStatusException {public GlobalException(HttpStatus status, String message) {super(status, message);}public GlobalException(HttpStatus status, String message, Throwable e) {super(status, message, e);}}复制代码GlobalErrorAttributes 全局异常属性值类代码如下Componentpublic class GlobalErrorAttributes extends DefaultErrorAttributes {Overridepublic Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) {Map map super.getErrorAttributes(request, includeStackTrace);if (getError(request) instanceof GlobalException) {GlobalException ex (GlobalException) getError(request);map.put(exception, ex.getClass().getSimpleName());map.put(message, ex.getMessage());map.put(status, ex.getStatus().value());map.put(error, ex.getStatus().getReasonPhrase());return map;}map.put(exception, SystemException);map.put(message, System Error , Check logs!);map.put(status, 500);map.put(error, System Error );return map;}}复制代码重写了父类 DefaultErrorAttributes 默认错误属性类的 getErrorAttributes 获取错误属性方法从服务请求封装 ServerRequest 中获取对应的异常。然后判断是否是 GlobalException如果是 CityHandler 服务处理类抛出的 GlobalException则返回对应的异常的信息。GlobalErrorWebExceptionHandler 全局异常处理类代码如下ComponentOrder(-2)public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext,ServerCodecConfigurer serverCodecConfigurer) {super(g, new ResourceProperties(), applicationContext);super.setMessageWriters(serverCodecConfigurer.getWriters());super.setMessageReaders(serverCodecConfigurer.getReaders());}Overrideprotected RouterFunction getRoutingFunction(final ErrorAttributes errorAttributes) {return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);}private Mono renderErrorResponse(final ServerRequest request) {final Map errorPropertiesMap getErrorAttributes(request, false);return ServerResponse.status(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON_UTF8).body(BodyInserters.fromObject(errorPropertiesMap));}}复制代码代码解析如下AbstractErrorWebExceptionHandler 抽象类是用来处理全局错误时进行扩展和实现Order 注解标记 AspectJ 的切面排序值越小拥有越高的优先级这里设置优先级偏高。构造函数将 GlobalErrorAttributes 全局异常属性值类设置到 AbstractErrorWebExceptionHandler 抽象类的局部变量中。重写 getRoutingFunction 方法设置对应的 RequestPredicates 和 Mono 服务响应对象将 GlobalErrorAttributes 的全局异常属性值 map设置到新的 ServerResponse 即可。到此基本结束。Spring Boot MVC 错误码如何实战参考地址www.bysocket.com/archives/16…2.5 运行验证在 IDEA 中执行 Application 类启动任意正常模式或者 Debug 模式。然后打开浏览器访问http://localhost:8080/hello复制代码异常界面如下可见这是在 CityHandler 城市服务处理类逻辑中抛出的全局异常信息。那么正常情况会是如何改下 URL 访问如下http://localhost:8080/hello?cityWenLing复制代码正常界面如下三、小结在 Spring 框架中没有代表错误响应的类只是返回响应对象一个 Map。如果需要定义业务的错误码返回体参考错误码如何实战参考地址www.bysocket.com/archives/16…本文重点还是有别于 Spring Boot 传统 MVC 模式统一异常处理实战了 WebFlux 全局异常处理机制。实战中这块扩展需要考虑异常分层从基类中扩展出来错误码设计分层易扩展比如在错误码中新增调用量字段…