I found that when using Spring Boot 3.4.1, this version places the properties from the header into the request when handling web requests.
There is a property bu in the header of request.
code:
@GetMapping("/periodic-data")
fun periodicData(condition: MarketingBoardDataDtoV2) = marketingBoardV2Service.periodicData(condition)
data class MarketingBoardDataDtoV2(
val category: String?,
val subBrand: String?,
val bu: String?,
val startDate: LocalDate,
val endDate: LocalDate,
)
request:
GET {{host}}/v2/marketing-board/periodic-data?startDate=2024-08-14&endDate=2024-12-14
in 3.4.1:
in <=3.4.0
Comment From: bclozel
Have you tried filtering this property in the binder as explained here?
Comment From: 664623107
Have you tried filtering this property in the binder as explained here?
@bclozel I added the property bu
to the header of each request in the Filter.
override fun doFilter(request: ServletRequest?, response: ServletResponse?, chain: FilterChain) {
val httpServletRequest = request as HttpServletRequest
// something ...
request.setHeader(Constant.BU, "$bu")
// something ...
}
But in the old version, there were no issues; I have always used it this way.
Comment From: bclozel
@664623107 that is not what I was suggesting. Please try the code snippet suggested here, configuring the binder to ignore the "bu" header.
Here's a class you can copy to your project that will ignore all header values. Let us know how this works for you.
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
@ControllerAdvice
public class MyControllerAdvice {
@InitBinder
public void initBinder(ExtendedServletRequestDataBinder binder) {
binder.addHeaderPredicate(header -> false);
}
}
Comment From: 664623107
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
@ControllerAdvice
public class MyControllerAdvice {
@InitBinder
public void initBinder(ExtendedServletRequestDataBinder binder) {
binder.addHeaderPredicate(header -> false);
}
}
@bclozel Thanks,It worked. But why were there no issues in versions <= 3.4.0? Is this a bug?
Comment From: bclozel
Thanks for letting us know. I think this is due to #34073, so not a bug. Your DTO class takes this argument in its constructor, which is a pretty strong signal for the binder to do the binding. I'll leave this opened for now to let Rossen comment on this, but I suspect that binding constructor arguments is the expected behavior here.
Comment From: bclozel
We have discussed this as a team, and we're going to refine this support in #34182. As for this particular case, we think that this behavior change uncovered a problem in the design of your application. Rather than using request headers as a context map, you should be adding this information as a request attribute.
We're closing this issue in favor of #34182. You can keep using the code snippet I shared but please consider refactoring this part of your application. Thanks!