I advise you to use the standard Spring way with Codecs to serialize objects.
I know at least 2 way for this:
- Use ServerCodecConfigurer class and EntityResponse object.
You could define ServerCodecConfigurer @Bean
@Bean
public ServerCodecConfigurer serverCodecConfigurer() {
return new DefaultServerCodecConfigurer();
}
And use it in some kind of util method like this
public class ResponseUtil {
@NotNull
public static <T> Mono<Void> putResponseIntoWebExchange(ServerWebExchange exchange, ServerCodecConfigurer serverCodecConfigurer, Mono<EntityResponse<T>> responseMono) {
return responseMono.flatMap(entityResponse ->
entityResponse.writeTo(exchange, new ServerResponse.Context() {
@NotNull
@Override
public List<HttpMessageWriter<?>> messageWriters() {
return serverCodecConfigurer.getWriters();
}
@NotNull
@Override
public List<ViewResolver> viewResolvers() {
return Collections.emptyList();
}
}));
}
}
Your code will look like this
WebExchangeBindException cvex = (WebExchangeBindException) ex;
Errors errors = new Errors();//Class wrapper for Map with errors
log.debug("errors:" + cvex.getFieldErrors());
cvex.getFieldErrors().forEach(ev -> errors.put(ev.getField(), ev.getDefaultMessage()));
log.debug("handled errors::" + errors);
final Mono<EntityResponse<Errors>> responseMono = EntityResponse.fromObject(errors)
.status(HttpStatus.UNPROCESSABLE_ENTITY)
.contentType(APPLICATION_JSON)
.build();
return ResponseUtil.putResponseIntoWebExchange(exchange, serverCodecConfigurer, responseMono);
- Use standard way for error handling.
By default Spring WebFlux using DefaultErrorAttributes class for handling all exceptions. You could simply customise it by overriding this class and defining bean of this class in spring context.
Like this:
@Component
public class CustomErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
final Map<String, Object> errorAttributes = super.getErrorAttributes(request, includeStackTrace);
Throwable error = getError(request);
//Depends of error add or replace errorAttributes with your custom message, http status, etc
if (error instanceof WebExchangeBindException) {
errorAttributes.put("message", error.getMessage());
Errors errors = new Errors();
error.getFieldErrors().forEach(ev -> errors.put(ev.getField(), ev.getDefaultMessage()));
errorAttributes.put("errors", error);
}
return errorAttributes;
}
}
It's more native way for handling exceptions in Spring WebFlux.
There is nice post about that - https://dzone.com/articles/exception-handling-in-spring-boot-webflux-reactive