code: @PostMapping(value = "/register", headers = "Content-Type=application/x-www-form-urlencoded")
    @ResponseBody
    public Map<String, String> registerUser(
        @Valid @ModelAttribute RegisterRequest registerRequest, HttpServletRequest request)
        throws Exception {
      if (authenticationSettings.getSignUp()) {
        if (!registerRequest.getPassword().equals(registerRequest.getConfirmPassword())) {
          throw new BindException(RegisterRequest.class, "password does not match confirm password");
        }
        if (appSettings.getRecaptchaIsEnabled()
            && !reCaptchaService.validate(registerRequest.getRecaptcha())) {
          throw new CaptchaException("invalid captcha answer");
        }
        User user = toUser(registerRequest);
        String activationUri;
        if (StringUtils.isEmpty(request.getHeader("X-Forwarded-Host"))) {
          activationUri =
              ServletUriComponentsBuilder.fromCurrentRequest()
                  .replacePath(URI + "/activate")
                  .build()
                  .toUriString();
        } else {
          String scheme = request.getHeader("X-Forwarded-Proto");
          if (scheme == null) scheme = request.getScheme();
          activationUri = scheme + "://" + request.getHeader("X-Forwarded-Host") + URI + "/activate";
        }
        accountService.createUser(user, activationUri);
  
        String successMessage =
            authenticationSettings.getSignUpModeration()
                ? REGISTRATION_SUCCESS_MESSAGE_ADMIN
                : REGISTRATION_SUCCESS_MESSAGE_USER;
        return Collections.singletonMap("message", successMessage);
      } else {
        throw new NoPermissionException("Self registration is disabled");
      }
    }
docs: Spring's FormHttpMessageConverter cannot bind target classes (as ModelAttribute can)