From 95c76fabfdc227deebe0198539bc9a398f824b79 Mon Sep 17 00:00:00 2001 From: liqiangqiang Date: Fri, 12 Apr 2019 01:12:50 +0800 Subject: [PATCH] =?UTF-8?q?WebFlux=20REST=20API=20=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=20=20Error=20Handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pom.xml | 51 +++++++++++++++++++ .../org/spring/springboot/Application.java | 20 ++++++++ .../error/GlobalErrorAttributes.java | 32 ++++++++++++ .../error/GlobalErrorWebExceptionHandler.java | 47 +++++++++++++++++ .../springboot/error/GlobalException.java | 15 ++++++ .../springboot/handler/CityHandler.java | 27 ++++++++++ .../spring/springboot/router/CityRouter.java | 20 ++++++++ .../src/main/resources/application.properties | 0 pom.xml | 2 + 9 files changed, 214 insertions(+) create mode 100755 2-x-spring-boot-webflux-handling-errors/pom.xml create mode 100644 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/Application.java create mode 100644 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorAttributes.java create mode 100644 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorWebExceptionHandler.java create mode 100644 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalException.java create mode 100644 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/handler/CityHandler.java create mode 100644 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/router/CityRouter.java create mode 100644 2-x-spring-boot-webflux-handling-errors/src/main/resources/application.properties diff --git a/2-x-spring-boot-webflux-handling-errors/pom.xml b/2-x-spring-boot-webflux-handling-errors/pom.xml new file mode 100755 index 0000000..aadde20 --- /dev/null +++ b/2-x-spring-boot-webflux-handling-errors/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + springboot + 2-x-spring-boot-webflux-handling-errors + 0.0.1-SNAPSHOT + 2-x-spring-boot-webflux-handling-errors + + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/Application.java b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/Application.java new file mode 100644 index 0000000..347d452 --- /dev/null +++ b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/Application.java @@ -0,0 +1,20 @@ +package org.spring.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Spring Boot 应用启动类 + * + */ +// Spring Boot 应用的标识 +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + // 程序启动入口 + // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 + SpringApplication.run(Application.class,args); + + } +} diff --git a/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorAttributes.java b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorAttributes.java new file mode 100644 index 0000000..c8f7158 --- /dev/null +++ b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorAttributes.java @@ -0,0 +1,32 @@ +package org.spring.springboot.error; + +import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; + +import java.util.Map; + +@Component +public class GlobalErrorAttributes extends DefaultErrorAttributes { + + @Override + public 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; + } +} diff --git a/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorWebExceptionHandler.java b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorWebExceptionHandler.java new file mode 100644 index 0000000..32e6864 --- /dev/null +++ b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorWebExceptionHandler.java @@ -0,0 +1,47 @@ +package org.spring.springboot.error; + +import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +import java.util.Map; + +@Component +@Order(-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()); + } + + @Override + protected 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)); + } + +} diff --git a/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalException.java b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalException.java new file mode 100644 index 0000000..e5e300b --- /dev/null +++ b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalException.java @@ -0,0 +1,15 @@ +package org.spring.springboot.error; + +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + +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); + } +} diff --git a/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/handler/CityHandler.java b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/handler/CityHandler.java new file mode 100644 index 0000000..56d0297 --- /dev/null +++ b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/handler/CityHandler.java @@ -0,0 +1,27 @@ +package org.spring.springboot.handler; + +import org.spring.springboot.error.GlobalException; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +import java.util.Optional; + +@Component +public 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()); + } +} diff --git a/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/router/CityRouter.java b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/router/CityRouter.java new file mode 100644 index 0000000..0cef9af --- /dev/null +++ b/2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/router/CityRouter.java @@ -0,0 +1,20 @@ +package org.spring.springboot.router; + +import org.spring.springboot.handler.CityHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Configuration +public class CityRouter { + + @Bean + public RouterFunction routeCity(CityHandler cityHandler) { + return RouterFunctions.route(RequestPredicates.GET("/hello").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), cityHandler::helloCity); + } + +} diff --git a/2-x-spring-boot-webflux-handling-errors/src/main/resources/application.properties b/2-x-spring-boot-webflux-handling-errors/src/main/resources/application.properties new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml index 73acb51..6a43a0b 100644 --- a/pom.xml +++ b/pom.xml @@ -9,6 +9,8 @@ pom + + 2-x-spring-boot-webflux-handling-errors chapter-1-spring-boot-quickstart