It can be reproduced.

Spring 5.3.x works normally; it is recommended that 6.2.10 maintains backward compatibility: WebDataBinder.getTarget() is null

  • Purpose: Map alias values of Query parameters to actual fields via @ControllerAdvice and @InitBinder?
@ControllerAdvice
public class GlobalInitBinder {

    @InitBinder
    public void initBinder(WebDataBinder binder, HttpServletRequest request) {
        //Spring 6 fails to retrieve Params parameter objects, with binder.getTarget() = null; 
        // please help troubleshoot the issue.
        Object target = binder.getTarget();
        if (target == null) {
            return;
        }
        Map<String, String[]> parameterMap = request.getParameterMap();
        MutablePropertyValues mpv = new MutablePropertyValues(parameterMap);
        Field[] fields = target.getClass().getDeclaredFields();
}
@RestController
@RequestMapping("v1")
public class TestController {

    @PostMapping("/test")
    public void getLoadWeightRuleList(Params params) {}
}
import lombok.Data;
@Data
public class Params implements Serializable {
    @FormFieldAlias(alternateNames = {"PageNum", "PageNumber", "pageNum"})
    private Integer pageNum;
}
  • How to bind multiple aliases to @BindParam("PageNumber"),like {alternateNames = {"PageNum", "PageNumber", "pageNum"}}?
  • link: #26721
import org.springframework.web.bind.annotation.BindParam;

public class Params implements Serializable {
    @BindParam("PageNumber")
    private Integer pageNum;
    public Params(Integer pageNum) {
        this.pageNum = pageNum;
    }
}

  • to use HandlerMethodArgumentResolver to solve the binding of multiple aliases to fields during query submission, or to use to ServletRequestDataBinder to invoke bind(ServletRequest)?

Comment From: sbrannen

Hi @dexchong,

Congratulations on submitting your first issue for the Spring Framework! 👍

If I understand you correctly, you are presenting two distinct topics in this issue.

  1. You claim there is a regression in the behavior of WebDataBinder.getTarget() when invoked from an @InitBinder method in a @ControllerAdvice bean.
  2. You are proposing that alias support be introduced in @BindParam.

Is that a correct assessment of what you are trying to convey?

If so, the proposal for @BindParam should be addressed in a separate GitHub issue, so that we can focus on one topic per issue.

Cheers,

Sam

Comment From: dexchong

Hi @sbrannen , Yes.

  1. In Spring 6.2.10, @InitBinder is incompatible with WebDataBinder.getTarget() for retrieving parameter objects from Form requests. In Spring 5, this issue didn’t occur because binding was processed and the object returned via ModelAttributeMethodProcessor.resolveArgument first, then @InitBinder was executed.
  2. The recommended solution, @BindParam can be used for single alias mapping verification. does not support mapping multiple aliases (e.g., {alternateNames = {"PageNum", "PageNumber"}}) to specified fields. Is there a plan to support this?
  1. You claim there is a regression in the behavior of WebDataBinder.getTarget() when invoked from an @InitBinder method in a @ControllerAdvice bean.
  2. You are proposing that alias support be introduced in @BindParam.

Comment From: rstoyanchev

Indeed this is a result of DataBinder support for constructor binding in #26721. The target object is no longer pre-instantiated in ModelAttributeMethodProcessor before calling DataBinder, and therefore not available during DataBinderFactory initialization. On the positive side, it means you can initialize the DataBinder before both constructor and setter binding, and you may be able to remove setter binding, which is less safe.

From what I can see, you need mainly Class information, and that you can still get, just switch from getTarget() to getTargetType().

There are no plans currently for@BindParam to support multiple values.

Comment From: dexchong

Thanks! Root cause & alternatives confirmed. Proposal: Unavailable during initialization, support optional rebinding (user-decided) when WebDataBinder.getTarget() is null. Resolved via ServletRequestDataBinder rebinding, ticket closed.