I know basics of springboot mvc but don't well understand how the underlying classes work(such as Servlet, Intercepters, Filters). Searched but didn't find answer.
To illustrate the problem, I created a demo project in github.
@RestController
public class GreetController {
protected static final Logger log = LogManager.getLogger();
@PostMapping("/")
public String greet(@RequestBody final WelcomeMessage msg) {
log.info(msg);
return "Hello " + msg.from;
}
@ExceptionHandler({HttpMessageNotReadableException.class})
public String addStudent(HttpMessageNotReadableException e) {
log.error(e.getMessage());
return "greeting from @ExceptionHandler";
}
}
valid request
curl -H "Content-Type: application/json" http://localhost:8080 --data '{"from":"jim","message":"nice to meet you!"}'
invalid request(invalid json)
curl -H "Content-Type: application/json" http://localhost:8080 --data '{"from":"jim","message""nice to meet you!"}'
log request body string before RestController's methods enter.
'log' here just represents some other logic that must be handled before RestController
(the two methods). For example, I want to record the request body string to ThreadLocal, then in @ExceptionHandler
I'll get that string and log as ERROR.
I once tried HandlerInterceptor
but will get some error like
'java.lang.IllegalStateException: Cannot call getInputStream() after getReader() has already been called for the current request'.
after some searching 1 2, I decided to use Filter
with ContentCachingRequestWrapper
.
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
ContentCachingRequestWrapper cachedRequest = new ContentCachingRequestWrapper(httpServletRequest);
chain.doFilter(cachedRequest, response);
String requestBody = IOUtils.toString(cachedRequest.getContentAsByteArray(), cachedRequest.getCharacterEncoding());
log.info(requestBody);
}
This code works well except that the log is after the RestController
. if I change the order:
String requestBody = IOUtils.toString(cachedRequest.getReader());
log.info(requestBody);
chain.doFilter(cachedRequest, response);
Works for invalid request, but when request is valid, got following exception:
com.example.demo.GreetController : Required request body is missing: public java.lang.String com.example.demo.GreetController.greet(com.example.demo.WelcomeMessage)
I also tried getContentAsByteArray
, getInputStream
and getReader
methods since some tutorials say the framework checks for specific method call. but all in vain.
Now I'm bit confused. Can anyone explain the executing order of RestController
and Filter
, when request is valid and invalid?
Is there any easier way(less code) to achive my ultimate goal? thanks!
I'm using springboot 2.6.3, jdk11.
How we can insert header and footer in google docs with google docs api using PHP code
Writing a new and appending a file in PHP without erasing contents
How to combine 2 arrays with the condition that 2 and 5 values will be from the second array?
How to keep the ?error on url if page extension not included?
I want to write a bash script that sends a message depending on whether a python script it called ran successfully or threw an error
So I am using IFRAME on my pagesThe code usually goes like this
I've the PWA app, launched on Android deviceThe app allow to take pictures and upload them to server
I have searched this website to find progress bars, but the ones I have been able to found show animated circles that go to the full 100%