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

时间:2015-10-03 11:27:19

标签: spring spring-mvc httprequest

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

如何使用我自己的实现将其传递给Spring并且它将无缝地使用它?

UPDATE1

善意提供的解决方案Bohuslav Burghardt无效:

  

HTTP状态500 - 请求处理失败;嵌套异常是   java.lang.IllegalStateException:一个Errors / BindingResult参数   期望在模型属性之后立即声明,   @RequestBody或它们适用的@RequestPart参数: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
    ) {

}

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

@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

问题在于param BindingResult result,当我删除它时,它有效。但是当发生一些错误时,我需要结果来处理它。

1 个答案:

答案 0 :(得分:1)

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

模型对象

my_id

<强>解析器

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 } @Valid参数不受支持的使用情况。