1

I added an async endpoint to a existing spring-mvc application:

@RestController
public class MyController {
    @PostMapping("/")
    public Mono<String> post(Object body) {
       return Mono.just("test");
       //webClient.retrieve().bodyToMono(String.class);
    }
}

I want to create a global interceptor/filter that will log the request body payload. But how can I get access to it?

I tried adding a HandlerInterceptorAdapter, but the payload is always empty:

static class LoggingInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request);
            byte[] buf = wrapper.getContentAsByteArray();
            System.out.println(buf);
            System.out.println(buf.length);

            return true;
        }
}

Maybe the payload is not yet present in the request, or has already been read. So how can I access the body in this async case?

membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • use `IOUtils.toString(request.getReader())` get the request body content,but I don't know what different between our codes? – TongChen Apr 01 '20 at 11:23

1 Answers1

0

Unfortunately in Webflux you cannot use HandlerInterceptorAdapter because it came from web mvc module and works only with the servlets. I found a good article with solutions.

P.S. You must to remove spring-mvc dependencies if going to use reactive endpoins.

Yauhen Balykin
  • 731
  • 5
  • 13
  • I have to keep spring-mvc unfortunately. – membersound Apr 01 '20 at 12:19
  • 1
    So,for async endpoints in web mvc use @Async annotation without webflux – Yauhen Balykin Apr 01 '20 at 12:24
  • Ok that would work, but in my real world app I return a `Mono` coming directly from `webClient` call, so I have to return a Mono here (or use `.block()` on the webclient, which is not good). – membersound Apr 01 '20 at 12:27
  • I understand, but you shouldn’t mix webflux and webmvc, these are absolutely different paradigms, use RestTemplate instead of webclient for webmvc application. – Yauhen Balykin Apr 01 '20 at 13:31
  • 1
    dont use RestTemplate, it is deprecated. You should use WebClient, if you wish to use WebClient like RestTemplate, you call block() and it will act the same way As restTemplate. – Toerktumlare Apr 02 '20 at 07:39
  • 1
    Blocking is bad in a full webflux application if you have a rest endpoint that returns a Mono/Flux to the calling client, then it is bad to block. And a reactive application is not a necessarily "async". So saying "Async spring controller" is wrong. A reactive application can be "synchronous" if the application feels that the request should be processed in sync. – Toerktumlare Apr 02 '20 at 07:42