Merge pull request #4670 from Tonnix/master
Added BAEL-1867 project files under the Spring-5-Reactive Project
This commit is contained in:
commit
db00197aac
@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
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{
|
||||||
|
|
||||||
|
private HttpStatus status = HttpStatus.BAD_REQUEST;
|
||||||
|
private String message = "please provide a name";
|
||||||
|
|
||||||
|
public GlobalErrorAttributes() {
|
||||||
|
super(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
|
||||||
|
Map<String, Object> map = super.getErrorAttributes(request, includeStackTrace);
|
||||||
|
map.put("status", getStatus());
|
||||||
|
map.put("message", getMessage());
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the status
|
||||||
|
*/
|
||||||
|
public HttpStatus getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param status the status to set
|
||||||
|
*/
|
||||||
|
public void setStatus(HttpStatus status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the message
|
||||||
|
*/
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message the message to set
|
||||||
|
*/
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@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<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, false);
|
||||||
|
|
||||||
|
return ServerResponse.status(HttpStatus.BAD_REQUEST)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||||
|
.body(BodyInserters.fromObject(errorPropertiesMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
package com.baeldung.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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.handlers;
|
||||||
|
|
||||||
|
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 Handler1 {
|
||||||
|
|
||||||
|
public Mono<ServerResponse> handleRequest1(ServerRequest request) {
|
||||||
|
return sayHello(request).onErrorReturn("Hello, Stranger")
|
||||||
|
.flatMap(s -> ServerResponse.ok()
|
||||||
|
.contentType(MediaType.TEXT_PLAIN)
|
||||||
|
.syncBody(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<String> sayHello(ServerRequest request) {
|
||||||
|
try {
|
||||||
|
return Mono.just("Hello, " + request.queryParam("name")
|
||||||
|
.get());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Mono.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.handlers;
|
||||||
|
|
||||||
|
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 Handler2 {
|
||||||
|
|
||||||
|
public Mono<ServerResponse> handleRequest2(ServerRequest request) {
|
||||||
|
return
|
||||||
|
sayHello(request)
|
||||||
|
.flatMap(s -> ServerResponse.ok()
|
||||||
|
.contentType(MediaType.TEXT_PLAIN)
|
||||||
|
.syncBody(s))
|
||||||
|
.onErrorResume(e -> sayHelloFallback()
|
||||||
|
.flatMap(s -> ServerResponse.ok()
|
||||||
|
.contentType(MediaType.TEXT_PLAIN)
|
||||||
|
.syncBody(s)));
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.handlers;
|
||||||
|
|
||||||
|
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 Handler3 {
|
||||||
|
|
||||||
|
public Mono<ServerResponse> handleRequest3(ServerRequest request) {
|
||||||
|
return
|
||||||
|
sayHello(request)
|
||||||
|
.flatMap(s -> ServerResponse.ok()
|
||||||
|
.contentType(MediaType.TEXT_PLAIN)
|
||||||
|
.syncBody(s))
|
||||||
|
.onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " +
|
||||||
|
e.getMessage())).flatMap(s -> ServerResponse.ok()
|
||||||
|
.contentType(MediaType.TEXT_PLAIN)
|
||||||
|
.syncBody(s)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<String> sayHello(ServerRequest request) {
|
||||||
|
try {
|
||||||
|
return Mono.just("Hello, " + request.queryParam("name")
|
||||||
|
.get());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Mono.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.handlers;
|
||||||
|
|
||||||
|
import com.baeldung.reactive.errorhandling.NameRequiredException;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Handler4 {
|
||||||
|
|
||||||
|
public Mono<ServerResponse> handleRequest4(ServerRequest request) {
|
||||||
|
return ServerResponse.ok()
|
||||||
|
.body(sayHello(request)
|
||||||
|
.onErrorResume(e ->
|
||||||
|
Mono.error(new NameRequiredException(
|
||||||
|
HttpStatus.BAD_REQUEST, "please provide a name", e))), String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<String> sayHello(ServerRequest request) {
|
||||||
|
try {
|
||||||
|
return Mono.just("Hello, " + request.queryParam("name").get());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Mono.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.handlers;
|
||||||
|
|
||||||
|
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 Handler5 {
|
||||||
|
|
||||||
|
public Mono<ServerResponse> handleRequest5(ServerRequest request) {
|
||||||
|
return ServerResponse.ok()
|
||||||
|
.body(sayHello(request), String.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<String> sayHello(ServerRequest request) {
|
||||||
|
return Mono.just("Hello, " + request.queryParam("name").get());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.routers;
|
||||||
|
|
||||||
|
import com.baeldung.reactive.errorhandling.handlers.Handler1;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Router1 {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RouterFunction<ServerResponse> routeRequest1(Handler1 handler) {
|
||||||
|
return RouterFunctions.route(RequestPredicates.GET("/api/endpoint1")
|
||||||
|
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.routers;
|
||||||
|
|
||||||
|
import com.baeldung.reactive.errorhandling.handlers.Handler2;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Router2 {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RouterFunction<ServerResponse> routeRequest2(Handler2 handler) {
|
||||||
|
return RouterFunctions.route(RequestPredicates.GET("/api/endpoint2")
|
||||||
|
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.routers;
|
||||||
|
|
||||||
|
import com.baeldung.reactive.errorhandling.handlers.Handler3;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Router3 {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RouterFunction<ServerResponse> routeRequest3(Handler3 handler) {
|
||||||
|
return RouterFunctions.route(RequestPredicates.GET("/api/endpoint3")
|
||||||
|
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest3);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.routers;
|
||||||
|
|
||||||
|
import com.baeldung.reactive.errorhandling.handlers.Handler4;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Router4 {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RouterFunction<ServerResponse> routeRequest4(Handler4 handler) {
|
||||||
|
return RouterFunctions.route(RequestPredicates.GET("/api/endpoint4")
|
||||||
|
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
package com.baeldung.reactive.errorhandling.routers;
|
||||||
|
|
||||||
|
import com.baeldung.reactive.errorhandling.handlers.Handler5;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Router5 {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RouterFunction<ServerResponse> routeRequest5(Handler5 handler) {
|
||||||
|
return RouterFunctions.route(RequestPredicates.GET("/api/endpoint5")
|
||||||
|
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest5);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.baeldung.reactive.errorhandling;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
|
||||||
|
public class ErrorHandlingTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebTestClient webTestClient;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalErrorHandlingUsingOnErrorReturn() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using onErrorReturn");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint1?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint1")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Stranger", i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalErrorHandlingUsingOnErrorResumeWithFallback() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using onErrorResume with fallback");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint2?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint2")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Stranger", i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalErrorHandlingUsingOnErrorResumeWithDynamicFallbackValue() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using onErrorResume with dynamic fallback value");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint3?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint3")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hi, I looked around for your name but found: No value present", i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalErrorHandlingUsingOnErrorResumeWithCatchAndRethrow() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using onErrorResume with catch and rethrow");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint4?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
webTestClient.get()
|
||||||
|
.uri("/api/endpoint4")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isBadRequest()
|
||||||
|
.expectHeader()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||||
|
.expectBody()
|
||||||
|
.jsonPath("$.message")
|
||||||
|
.isNotEmpty()
|
||||||
|
.jsonPath("$.message")
|
||||||
|
.isEqualTo("please provide a name");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGlobalErrorHandlingUsingErrorWebExceptionHandler() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using ErrorWebExceptionHandler");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint5?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
webTestClient.get()
|
||||||
|
.uri("/api/endpoint5")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isBadRequest()
|
||||||
|
.expectHeader()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||||
|
.expectBody()
|
||||||
|
.jsonPath("$.message")
|
||||||
|
.isNotEmpty()
|
||||||
|
.jsonPath("$.message")
|
||||||
|
.isEqualTo("please provide a name");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.baeldung.reactive.errorhandling;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
|
||||||
|
public class ApplicationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebTestClient webTestClient;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalErrorHandlingUsingOnErrorReturn() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using onErrorReturn");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint1?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint1")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Stranger", i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalErrorHandlingUsingOnErrorResumeWithFallback() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using onErrorResume with fallback");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint2?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint2")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Stranger", i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalErrorHandlingUsingOnErrorResumeWithDynamicFallbackValue() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using onErrorResume with dynamic fallback value");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint3?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint3")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hi, I looked around for your name but found: No value present", i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalErrorHandlingUsingOnErrorResumeWithCatchAndRethrow() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using onErrorResume with catch and rethrow");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint4?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
webTestClient.get()
|
||||||
|
.uri("/api/endpoint4")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isBadRequest()
|
||||||
|
.expectHeader()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||||
|
.expectBody()
|
||||||
|
.jsonPath("$.message")
|
||||||
|
.isNotEmpty()
|
||||||
|
.jsonPath("$.message")
|
||||||
|
.isEqualTo("please provide a name");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGlobalErrorHandlingUsingErrorWebExceptionHandler() throws IOException {
|
||||||
|
|
||||||
|
System.out.println("Testing local error handling using ErrorWebExceptionHandler");
|
||||||
|
|
||||||
|
// Pass a username
|
||||||
|
String i = webTestClient.get()
|
||||||
|
.uri("/api/endpoint5?name={username}", "Tony")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.returnResult(String.class)
|
||||||
|
.getResponseBody()
|
||||||
|
.blockFirst();
|
||||||
|
|
||||||
|
assertEquals("Hello, Tony", i);
|
||||||
|
|
||||||
|
// Do not pass a username
|
||||||
|
webTestClient.get()
|
||||||
|
.uri("/api/endpoint5")
|
||||||
|
.accept(MediaType.TEXT_PLAIN)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isBadRequest()
|
||||||
|
.expectHeader()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||||
|
.expectBody()
|
||||||
|
.jsonPath("$.message")
|
||||||
|
.isNotEmpty()
|
||||||
|
.jsonPath("$.message")
|
||||||
|
.isEqualTo("please provide a name");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user