JAVA-25542 Check code of spring-reactive ebook (#14880)

Co-authored-by: timis1 <noreplay@yahoo.com>
This commit is contained in:
timis1
2023-10-03 07:25:06 +03:00
committed by GitHub
parent e331611860
commit ca1590cc66
10 changed files with 10 additions and 10 deletions
@@ -1,18 +0,0 @@
package com.baeldung.spring.reactive.errorhandling;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration;
import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration;
@SpringBootApplication(exclude = {
MongoReactiveAutoConfiguration.class,
ReactiveSecurityAutoConfiguration.class,
ReactiveUserDetailsServiceAutoConfiguration.class })
public class ErrorHandlingApplication {
public static void main(String[] args) {
SpringApplication.run(ErrorHandlingApplication.class, args);
}
}
@@ -1,22 +0,0 @@
package com.baeldung.spring.reactive.errorhandling;
import java.util.Map;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
@Component
public class GlobalErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Map<String, Object> map = super.getErrorAttributes(request, options);
map.put("status", HttpStatus.BAD_REQUEST);
map.put("message", "please provide a name");
return map;
}
}
@@ -1,50 +0,0 @@
package com.baeldung.spring.reactive.errorhandling;
import java.util.Map;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions;
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;
@Component
@Order(-2)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
public GlobalErrorWebExceptionHandler(
GlobalErrorAttributes g, ApplicationContext applicationContext,
ServerCodecConfigurer serverCodecConfigurer) {
super(g, new WebProperties.Resources(), applicationContext);
super.setMessageWriters(serverCodecConfigurer.getWriters());
super.setMessageReaders(serverCodecConfigurer.getReaders());
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(final ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(final ServerRequest request) {
final Map<String, Object> errorPropertiesMap = getErrorAttributes(request, ErrorAttributeOptions.defaults());
return ServerResponse.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(errorPropertiesMap));
}
}
@@ -1,68 +0,0 @@
package com.baeldung.spring.reactive.errorhandling;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
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;
@Component
public class Handler {
public Mono<ServerResponse> handleWithErrorReturn(ServerRequest request) {
return sayHello(request)
.onErrorReturn("Hello, Stranger")
.flatMap(s -> ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.bodyValue(s));
}
public Mono<ServerResponse> handleWithErrorResumeAndDynamicFallback(ServerRequest request) {
return sayHello(request)
.flatMap(s -> ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.bodyValue(s))
.onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " + e.getMessage()))
.flatMap(s -> ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.bodyValue(s)));
}
public Mono<ServerResponse> handleWithErrorResumeAndFallbackMethod(ServerRequest request) {
return sayHello(request)
.flatMap(s -> ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.bodyValue(s))
.onErrorResume(e -> sayHelloFallback()
.flatMap(s -> ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.bodyValue(s)));
}
public Mono<ServerResponse> handleWithErrorResumeAndCustomException(ServerRequest request) {
return ServerResponse.ok()
.body(sayHello(request)
.onErrorResume(e -> Mono.error(new NameRequiredException(
HttpStatus.BAD_REQUEST,
"please provide a name", e))), String.class);
}
public Mono<ServerResponse> handleWithGlobalErrorHandler(ServerRequest request) {
return ServerResponse.ok()
.body(sayHello(request), String.class);
}
private Mono<String> sayHello(ServerRequest request) {
try {
return Mono.just("Hello, " + request.queryParam("name").get());
} catch (Exception e) {
return Mono.error(e);
}
}
private Mono<String> sayHelloFallback() {
return Mono.just("Hello, Stranger");
}
}
@@ -1,11 +0,0 @@
package com.baeldung.spring.reactive.errorhandling;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;
public class NameRequiredException extends ResponseStatusException {
public NameRequiredException(HttpStatus status, String message, Throwable e) {
super(status, message, e);
}
}
@@ -1,26 +0,0 @@
package com.baeldung.spring.reactive.errorhandling;
import static org.springframework.http.MediaType.TEXT_PLAIN;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
@Component
public class Router {
@Bean
public RouterFunction<ServerResponse> routes(Handler handler) {
return RouterFunctions
.route(GET("/api/endpoint1").and(accept(TEXT_PLAIN)), handler::handleWithErrorReturn)
.andRoute(GET("/api/endpoint2").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndFallbackMethod)
.andRoute(GET("/api/endpoint3").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndDynamicFallback)
.andRoute(GET("/api/endpoint4").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndCustomException)
.andRoute(GET("/api/endpoint5").and(accept(TEXT_PLAIN)), handler::handleWithGlobalErrorHandler);
}
}
@@ -1,124 +0,0 @@
package com.baeldung.spring.reactive.errorhandling;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.MediaType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.reactive.server.WebTestClient;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
@AutoConfigureWebTestClient(timeout = "10000")
class ErrorHandlingIntegrationTest {
@Autowired
private WebTestClient webTestClient;
@Test
void givenErrorReturn_whenUsernamePresent_thenOk() {
webTestClient.get()
.uri("/api/endpoint1?name={username}", "Tony")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectBody(String.class).isEqualTo("Hello, Tony");
}
@Test
void givenErrorReturn_whenNoUsername_thenOk() {
webTestClient.get()
.uri("/api/endpoint1")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectBody(String.class).isEqualTo("Hello, Stranger");
}
@Test
void givenResumeFallback_whenUsernamePresent_thenOk() {
webTestClient.get()
.uri("/api/endpoint2?name={username}", "Tony")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectBody(String.class).isEqualTo("Hello, Tony");
}
@Test
void givenResumeFallback_whenNoUsername_thenOk() {
webTestClient.get()
.uri("/api/endpoint2")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectBody(String.class).isEqualTo("Hello, Stranger");
}
@Test
void givenResumeDynamicValue_whenUsernamePresent_thenOk() {
webTestClient.get()
.uri("/api/endpoint3?name={username}", "Tony")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectBody(String.class).isEqualTo("Hello, Tony");
}
@Test
void givenResumeDynamicValue_whenNoUsername_thenOk() {
webTestClient.get()
.uri("/api/endpoint3")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectBody(String.class).isEqualTo("Hi, I looked around for your name but found: No value present");
}
@Test
void givenResumeRethrow_whenUsernamePresent_thenOk() {
webTestClient.get()
.uri("/api/endpoint4?name={username}", "Tony")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectBody(String.class).isEqualTo("Hello, Tony");
}
@Test
void givenResumeRethrow_whenNoUsername_thenOk() {
webTestClient.get()
.uri("/api/endpoint4")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectStatus().isBadRequest()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody().jsonPath("$.message").isEqualTo("please provide a name");
}
@Test
void givenGlobalErrorHandling_whenUsernamePresent_thenOk() {
webTestClient.get()
.uri("/api/endpoint5?name={username}", "Tony")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectBody(String.class).isEqualTo("Hello, Tony");
}
@Test
void givenGlobalErrorHandling_whenNoUsername_thenOk() {
webTestClient.get()
.uri("/api/endpoint5")
.accept(MediaType.TEXT_PLAIN)
.exchange()
.expectStatus().isBadRequest()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody().jsonPath("$.message").isEqualTo("please provide a name");
}
}