如何解决SpringBoot读取不到request请求中的InputStream的问题
本篇内容主要讲解“如何解决SpringBoot读取不到request请求中的InputStream的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决SpringBoot读取不到request请求中的InputStream的问题”吧!
创新互联公司主要为客户提供服务项目涵盖了网页视觉设计、VI标志设计、全网整合营销推广、网站程序开发、HTML5响应式网站建设、手机网站开发、微商城、网站托管及成都网站维护公司、WEB系统开发、域名注册、国内外服务器租用、视频、平面设计、SEO优化排名。设计、前端、后端三个建站步骤的完善服务体系。一人跟踪测试的建站服务标准。已经为成都酒楼设计行业客户提供了网站维护服务。
现象
采用SpringBoot2.0版本开发项目,之前发现获取参数的时候,request.getParameter()获取不到参数,没有深究,采用
@PostMapping("/mbr/detail") public Result mbrDetail(@RequestBody JSONObject jsonObject){ MbrMember mbrMember = null; try { String mbrId = jsonObject.getString("mbrId"); mbrMember = mbrMemberService.getMbrMemberById(mbrId); }catch (Exception e) { e.printStackTrace(); return ResultGenerator.genExcepResult("服务器内部错误"); } return ResultGenerator.genSuccessResult(mbrMember); }
@RequestBody JSONObject jsonObject的方式来获取请求中的参数。
今天对原来接口改造的时候,发现从request请求中总是获取不到参数,原接口(未采用Spring模式)采用JSP形式实现,如下:
try { System.out.println("!!进入回调!!"); String postdata = AppServiceUtil.getPostData(request.getInputStream(), request.getContentLength(), Charsets.UTF_8.toString()); BdNotifyApi notifyApi = new BdNotifyApi(); result = notifyApi.bdNotify(postdata); } catch (Exception e) { e.printStackTrace(); }finally { response.setCharacterEncoding("utf8"); response.setHeader("content-type", "text/html;charset=UTF-8"); response.getWriter().print(result); }
getPostData方法如下:
public static String getPostData(InputStream in, int size, String charset) { if (in != null && size > 0) { byte[] buf = new byte[size]; try { in.read(buf); if (charset == null || charset.length() == 0) return new String(buf); else { return new String(buf, charset); } } catch (IOException e) { e.printStackTrace(); } } return null; }
request采用流读取的方式获取不到参数
分析
出现这种情况,首先怀疑输入流已经被使用了,由于请求输入流是不带缓存的,使用一次后流就无效了,通常触发解析输入流就是调用了getParameter()等方法,经过检查代码确认没有做过相关处理,所以怀疑SpringBoot底层做了处理。 查了一下SpringBoot的自动装配配置,在WebMvcAutoConfiguration中初始化了一个OrderedHiddenHttpMethodFilter,默认这个过滤器是生效的,相关代码如下:
@Bean @ConditionalOnMissingBean(HiddenHttpMethodFilter.class) @ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = true) public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() { return new OrderedHiddenHttpMethodFilter(); }
OrderedHiddenHttpMethodFilter继承了OrderedHiddenHttpMethodFilter,而OrderedHiddenHttpMethodFilter又继承了HiddenHttpMethodFilter,在该类的doFilterInternal()方法中发现有对参数做处理,相关代码如下:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { HttpServletRequest requestToUse = request; if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) { String paramValue = request.getParameter(this.methodParam); if (StringUtils.hasLength(paramValue)) { String method = paramValue.toUpperCase(Locale.ENGLISH); if (ALLOWED_METHODS.contains(method)) { requestToUse = new HttpMethodRequestWrapper(request, method); } } } filterChain.doFilter(requestToUse, response); }
配置
在SpringMVC的配置文件中对过滤器重新配置
/** * Spring MVC 配置WebMvcConfigurer */ @Configuration public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
过滤器代码如下:
@Bean public HiddenHttpMethodFilter hiddenHttpMethodFilter() { return new OrderedHiddenHttpMethodFilter(){ @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { filterChain.doFilter(request, response); } }; }
总结
搞明白流方式获取请求参数的原理以及SpringBoot默认的配置对这种情况的处理。
参考
https://blog.csdn.net/jianggujin/article/details/86644914
到此,相信大家对“如何解决SpringBoot读取不到request请求中的InputStream的问题”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
网站标题:如何解决SpringBoot读取不到request请求中的InputStream的问题
链接地址:http://myzitong.com/article/iejehh.html