Spring MVC使用ServerHttpRequest报错:无可用构造方法求助
问题原因
在Spring Web MVC(Servlet栈)环境中,直接将org.springframework.http.server.ServerHttpRequest作为控制器方法参数时,Spring会默认尝试通过ModelAttributeMethodProcessor来实例化该参数。但ServerHttpRequest是抽象接口,既无公共构造方法也无默认构造方法,因此抛出IllegalStateException异常。
ServerHttpRequest本质是Spring WebFlux(响应式Web框架)的核心请求抽象,Spring MVC默认并未为它提供对应的参数解析器,无法直接注入。
解决方案
方案1:手动转换HttpServletRequest为ServerHttpRequest
在控制器方法中注入标准的HttpServletRequest,手动包装为Servlet环境下的ServerHttpRequest实现类ServletServerHttpRequest:
@ApiOperation(value = "sample text") @ApiResponses( value = { @ApiResponse( code = 200, message = "Successful retrieval", response = SampleResponse.class) }) @PostMapping( consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public DeferredResult<SampleResponse> create( @RequestBody RequestBodyDO requestBodyDo, HttpServletRequest servletRequest) { // 包装为ServerHttpRequest ServerHttpRequest request = new ServletServerHttpRequest(servletRequest); // 后续业务逻辑处理 }
方案2:自定义参数解析器实现自动注入
如果需要在多个控制器中复用ServerHttpRequest参数注入,可自定义HandlerMethodArgumentResolver,让Spring MVC自动识别并注入该参数:
步骤1:实现参数解析器
@Component public class ServerHttpRequestArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { // 判断参数类型是否为ServerHttpRequest return ServerHttpRequest.class.isAssignableFrom(parameter.getParameterType()); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { // 从原生请求中获取HttpServletRequest并包装 HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); return new ServletServerHttpRequest(servletRequest); } }
步骤2:注册参数解析器
@Configuration public class WebMvcConfig implements WebMvcConfigurer { private final ServerHttpRequestArgumentResolver argumentResolver; // 构造注入自定义解析器 public WebMvcConfig(ServerHttpRequestArgumentResolver argumentResolver) { this.argumentResolver = argumentResolver; } @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { // 将自定义解析器加入Spring MVC的参数解析器列表 resolvers.add(argumentResolver); } }
完成配置后,即可像最初的代码一样,直接在控制器方法中使用ServerHttpRequest作为参数。
内容的提问来源于stack exchange,提问作者Rineeth Saladi
相关产品推荐
相关产品推荐

