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?
CodePudding user response:
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
CodePudding user response:
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"}
CodePudding user response:
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.