创建自己的 class 将 HTTP 请求转换为 Spring 中的对象?

Create own class that transforms HTTP request to object in Spring?

我想创建自己的 class,它将在我的 Spring MVC 应用程序中转换 HTTP 请求并根据此 HTTP 请求初始化对象。我可以通过在方法中定义参数来创建对象,但我需要以我自己的方式进行映射并手动进行。

我如何使用我自己的实现来完成它,它将传递给 Spring 并且它会无缝地使用它?

更新1

友情提供的解决方案Bohuslav Burghardt无效:

HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalStateException: An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the @RequestBody or the @RequestPart arguments to which they apply: public java.lang.String cz.deriva.derivis.api.oauth2.provider.controllers.OAuthController.authorize(api.oauth2.provider.domain.AuthorizationRequest,org.springframework.ui.Model,org.springframework.validation.BindingResult,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)

也许我应该提到我使用自己的验证器:

public class RequestValidator {

    public boolean supports(Class clazz) {
        return AuthorizationRequest.class.equals(clazz);
    }

    public void validate(Object obj, Errors e) {
        AuthorizationRequest request = (AuthorizationRequest) obj;
        if ("foobar".equals(request.getClientId())) {
            e.reject("clientId", "nomatch");
        }
    }

}

和我在控制器中的方法声明(请不要需要验证 - @Valid):

@RequestMapping(value = "/authorize", method = {RequestMethod.GET, RequestMethod.POST})
    public String authorize(
            @Valid AuthorizationRequest authorizationRequest,
            BindingResult result
    ) {

}

我的应用程序中有两个配置 class。

@Configuration
@EnableAutoConfiguration
@EnableWebMvc
@PropertySource("classpath:/jdbc.properties")
public class ApplicationConfig {
}

@Configuration
@EnableWebMvc
public class WebappConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new AuthorizationRequestArgumentResolver());
    }

}

怎么了?

更新 2

问题出在参数 BindingResult result 上,当我删除它时它可以正常工作。但是当出现一些错误时,我需要结果来处理它。

如果我正确理解了您的要求,您可以为此目的实施自定义 HandlerMethodArgumentResolver。有关实施细节,请参见下面的示例:


模型对象

public class AuthorizationRequestHolder {
    @Valid
    private AuthorizationRequest authorizationRequest;
    private BindingResult bindingResult;
    // Constructors, accessors omitted
}

解析器

public class AuthorizationRequestMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return AuthorizationRequestHolder.class.isAssignableFrom(parameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
        // Map the authorization request
        AuthorizationRequest authRequest = mapFromServletRequest(request);
        AuthorizationRequestHolder authRequestHolder = new AuthorizationRequestHolder(authRequest);
        // Validate the request
        if (parameter.hasParameterAnnotation(Valid.class)) {
            WebDataBinder binder = binderFactory.createBinder(webRequest, authRequestHolder, parameter.getParameterName());
            binder.validate();
            authRequestHolder.setBindingResult(binder.getBindingResult());
        }
        return authRequestHolder;
    }
}

配置

@Configuration
@EnableWebMvc
public class WebappConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new AuthorizationRequestMethodArgumentResolver());
    }
}

用法

@RequestMapping("/auth")
public void doSomething(@Valid AuthRequestHolder authRequestHolder) {
    if (authRequestHolder.getBindingResult().hasErrors()) {
        // Process errors
    }
    AuthorizationRequest authRequest = authRequestHolder.getAuthRequest();
    // Do something with the authorization request
}

编辑:更新了带有 HandlerMethodArgumentResolver 参数的 @Valid 不支持用法的解决方法的答案。