0

I'm using Spring Boot @RequestBody annotation to access the request body properties like below

@PostMapping ResponseEntity<UserDto> createUser (@RequestBody UserDto userDto) { // some coode return null; } 

What I want to do is instead of just accessing the userDto properties. I want to log the whole request body because someone else is using sending the request and it doesn't match my userDto

What I tried?

@PostMapping ResponseEntity<UserDto> createUser (HttpServletRequest request) { logger.info("Body: {}", request.getReader().lines().collect(Collectors.toSet())); return null; } 

This works just fine but each time I want to log the request body I have to switch between @RequestBody UserDto and HttpServletRequest request

Is there anyway I can keep that jackson @RequestBody annonation and still log request body as it is?

5
  • Did you try: logger.info("Body: {}",userDto); ? It doesn't work? Commented Dec 7, 2022 at 10:28
  • Did you override toString method for UserDto? Commented Dec 7, 2022 at 10:45
  • 3
    If you want to log the whole request, you should use a filter. Have a look here: baeldung.com/spring-http-logging theres a CommonsRequestLoggingFilter you can use. Commented Dec 7, 2022 at 11:03
  • To be honest, I would do this with a servlet filter on Spring's servlet to get access on the actual, binary request stream. Commented Dec 7, 2022 at 11:03
  • @TomStroemer CommonsRequestLoggingFilter works for me. Thanks! Commented Dec 7, 2022 at 12:51

3 Answers 3

1

Information taken from https://www.baeldung.com/spring-http-logging

You can use Springs CommonsRequestLoggingFilter for this. You can activate this via a Configuration Bean:

@Configuration public class RequestLoggingFilterConfig { @Bean public CommonsRequestLoggingFilter logFilter() { CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter(); filter.setIncludeQueryString(true); filter.setIncludePayload(true); filter.setMaxPayloadLength(10000); filter.setIncludeHeaders(false); filter.setAfterMessagePrefix("REQUEST DATA : "); return filter; } } 

The filter logs on debug, so you need to enable debug logging for the class. For example add this in your logback.xml:

<logger name="org.springframework.web.filter.CommonsRequestLoggingFilter"> <level value="DEBUG" /> </logger> 

For reference see https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/CommonsRequestLoggingFilter.html

Sign up to request clarification or add additional context in comments.

Comments

0

You can use ObjectMapper from fasterxml

add the following dependencies to the pom.xml:

<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.3</version> </dependency> 

Change your createUser method to this:

@PostMapping ResponseEntity<UserDto> createUser (@RequestBody UserDto userDto) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); logger.info("Body: "+ objectMapper.writeValueAsString(userDto)); return null; } 

Result will be like this in your console:

: Body: {"name":"John","username":"Doe"} 

1 Comment

The result is not original request body. It contains only those properties that are present in UserDto class. OP's intent is to trace original JSON with properties missing in UserDto class.
0

One way to solve this task is to write an Http Filter that logs the message before the Handler method is called.

This Baeldung Article demonstrates a filter that logs.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.