您好,登錄后才能下訂單哦!
本篇內容主要講解“如何解決SpringBoot讀取不到request請求中的InputStream的問題”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何解決SpringBoot讀取不到request請求中的InputStream的問題”吧!
采用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; }
出現這種情況,首先懷疑輸入流已經被使用了,由于請求輸入流是不帶緩存的,使用一次后流就無效了,通常觸發解析輸入流就是調用了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的問題”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。