Spring升级后request.getInputStream()无法获取数据流

问题:平台升级Spring3.1.2.RELEASE升级为5.1.12.RELEASE。升级后controller层无法获取request中的数据流。

背景: ajax请求

                   请求格式未设置为默认的 application/x-www-form-urlencoded; charset=UTF-8 

                    请求参数格式 xml

                    请求方式为 post

后台代码:

public static String getDataFromRequest(HttpServletRequest request) throws IOException{
		//获取请求流,并转为字符串,使用DOM4J解析该XML
		ServletInputStream postQueryStream = request.getInputStream();

           //BUFFER_SIZE 为1024		
	    byte[] buffer = new byte[BUFFER_SIZE]; 
	    int length = 0;   
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();   
	   
	    do {   
	        length = postQueryStream.read(buffer);   
	        if (length > 0) {   
	            baos.write(buffer, 0, length);   
	        }   
	    } while (length>0);   
	   
	    String strQueryText = new String(baos.toByteArray(), ENCODING);
		
		return strQueryText;
	}

length的返回值为-1,无法读取request中的数据流。但是request.getParameter()可以获取数据信息。 

首先看一下servlet规范

由上图可得 当满足四个条件后,无法通过request.getInputStream()获取数据流。此时已经满足了前三个条件

下面看一下升级前后关键代码部分对比 (注意代码中注释部分)

Spring5.1.12版本

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        this.logRequest(request);
        Map<String, Object> attributesSnapshot = null;
        if (WebUtils.isIncludeRequest(request)) {
            attributesSnapshot = new HashMap();
            Enumeration attrNames = request.getAttributeNames();
//略...
private void logRequest(HttpServletRequest request) {
        LogFormatUtils.traceDebug(this.logger, (traceOn) -> {
            String params;
            if (this.isEnableLoggingRequestDetails()) {
                params = (String)request.getParameterMap().entrySet().stream().map((entry) -> {
                    return (String)entry.getKey() + ":" + Arrays.toString((Object[])entry.getValue());
                }).collect(Collectors.joining(", "));
            } else {
                //此时触发上图中的第四个条件,servlet调用了getParameter系列方法
                params = request.getParameterMap().isEmpty() ? "" : "masked";
            }

            String queryString = request.getQueryString();
            String queryClause = StringUtils.hasLength(queryString) ? "?" + queryString : "";
//略
 

Spring3.1.2版本(代码中没有getParameter类似方法)

@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (logger.isDebugEnabled()) {
			String requestUri = urlPathHelper.getRequestUri(request);
			logger.debug("DispatcherServlet with name '" + getServletName() + "' processing " + request.getMethod() +
					" request for [" + requestUri + "]");
		}

		// Keep a snapshot of the request attributes in case of an include,
		// to be able to restore the original attributes after the include.
		Map<String, Object> attributesSnapshot = null;
		if (WebUtils.isIncludeRequest(request)) {
			logger.debug("Taking snapshot of request attributes before include");
			attributesSnapshot = new HashMap<String, Object>();
			Enumeration<?> attrNames = request.getAttributeNames();
			while (attrNames.hasMoreElements()) {
				String attrName = (String) attrNames.nextElement();
				if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
					attributesSnapshot.put(attrName, request.getAttribute(attrName));
				}
			}
		}

		// Make framework objects available to handlers and view objects.
		request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
		request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
		request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
		request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());

		FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
		if (inputFlashMap != null) {
			request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
		}
		request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
		request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

		try {
			doDispatch(request, response);
		}
		finally {
			// Restore the original attribute snapshot, in case of an include.
			if (attributesSnapshot != null) {
				restoreAttributesAfterInclude(request, attributesSnapshot);
			}
		}
	}

        由此可见在满足前三个条件的情况下,Spring3版本没有request.getParameter()系列方法,没有满足第四个条件所以升级之前可以通过request.getInputStream()获取数据流。而Spring5版本中存在request.getParameter()系列方,四个条件全部满足,所以无法获取数据流。

        修改:设置ajax请求内容格式

contentType: 'text/xml;charset=UTF-8'

         修改方法:使请求不满足第三个条件。可根据实际情况,对四个条件进行修改。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值