解决post请求参数只能获取一次的问题。

环境:Spring 4.2.5.RELEASE ,tomcat:8.5.37
在做微信小程序的时候,前端用的是mpvue+flyio来发送请求,但是后台用request.getParam…获取不到参数值,后来经测试发现,无论前端发送请求的头部Content-Type设置成什么,结果发送的参数都会封装至body中以json字符串的格式发送到后台,后台只能以流的方式接受,但是涉及到登录验证时需要拦截器来验证是否包含登录信息时,需要在此时取出数据验证,但是问题来了,再拦截器中取得了参数信息,到真正执行的业务类中参数全部为空,下面是解决办法!
最后会有问题这种方案产生的问题,请看完!

新增过滤器 HttpServletFilter

package com.......filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import com.....RequestWrapper;

public class HttpServletFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//       System.out.println("过滤器");
    	ServletRequest requestWrapper = null;
        if(request instanceof HttpServletRequest) {
            requestWrapper = new RequestWrapper((HttpServletRequest) request);
        }
        if(requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }
    public void destroy() {

    }
}

新增工具类 RequestWrapper

package com....util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class RequestWrapper extends HttpServletRequestWrapper {
    private final String body;
    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        body = stringBuilder.toString();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            public boolean isFinished() {
                return false;
            }
            public boolean isReady() {
                return false;
            }
            public void setReadListener(ReadListener readListener) {}
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;

    }
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream(),"UTF-8"));
    }
    public String getBody() {
        return this.body;
    }

}

新增拦截器 SessionInterceptor

package com.....interceptor;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.njpp.wxxcx.core.common.ErrCode;
import com.njpp.wxxcx.core.common.Tool;
import com.njpp.wxxcx.util.RequestWrapper;

public class SessionInterceptor implements HandlerInterceptor {

	@Override
	public void afterCompletion(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2, ModelAndView arg3) throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object arg2) throws Exception {
//			System.out.println("拦截器");
//			RequestWrapper myRequestWrapper = new RequestWrapper((HttpServletRequest) request);
	        String body = ((RequestWrapper)request).getBody();
//	        System.out.println(body);
	        JSONObject requestJson = JSONObject.parseObject(body);
			JSONObject res = new JSONObject();
			PrintWriter out = null;
			try {
				if (!Tool.existInRedis(requestJson)) {
					res.put(ErrCode.STATE, ErrCode.INVALID);
					out = response.getWriter();
					out.append(res.toString());
					return false;
				} else {
					return true;
				}
			} catch (Exception e) {
				e.printStackTrace();
				response.sendError(500);
				return false;
			}
	}
}

在service层使用 获取参数

Map paramMap = (Map) JSONObject.parse(((RequestWrapper)request).getBody());

还需要在spring-mvc.xml中添加配置


	<mvc:interceptors>
		<mvc:interceptor>
			
			<mvc:mapping path="/user/**" />
			<mvc:mapping path="/notice/**" />
			<bean class="com.....SessionInterceptor">bean>
		mvc:interceptor>
	mvc:interceptors>

在web.xml中添加配置

  <filter>
    <filter-name>requestFilterfilter-name>
    <filter-class>com.njpp.wxxcx.core.filter.HttpServletFilterfilter-class>
  filter>
  <filter-mapping>
    <filter-name>requestFilterfilter-name>
    <url-pattern>/notice/*url-pattern>
    <url-pattern>/user/*url-pattern>
  filter-mapping>

注意,这两个配置的拦截配置需要相同,不然会报错,,请求必须为POST,还有会有人问为什么不写/*,因为这个方法会影响上传文件,需要把上传文件独立出来不被拦截才行,不拦截的方法需要用如下的POST方式取参:

	/**
	 * 从request中获得参数Map,并返回可读的Map code专用
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Map getParameterMapCode(HttpServletRequest request)
			throws Exception {
		// 获取提交方式(GET/POST)
		String submitMehtod = request.getMethod();
		
		Map<String, Object> paramMap = null;
		
		Map properties = request.getParameterMap();
		if (submitMehtod.equals("GET")) {
			paramMap = getMethod(request);
			// POST
		} else {
			paramMap = postMethod(request);
		}
		if (paramMap == null) {
			paramMap = new HashMap<String, Object>();
		}
		return paramMap;
	}
	
	
	
	
	
	// get请求获取参数
	private static Map getMethod(HttpServletRequest request) {
		// 返回值Map
		Map returnMap = new HashMap();
		// 参数Map
		Map properties = request.getParameterMap();

		Iterator entries = properties.entrySet().iterator();
		Map.Entry entry;
		String name = "";
		String value = "";
		while (entries.hasNext()) {
			entry = (Map.Entry) entries.next();
			name = (String) entry.getKey();
			Object valueObj = entry.getValue();
			if (null == valueObj) {
				value = "";
			} else if (valueObj instanceof String[]) {
				String[] values = (String[]) valueObj;
				for (int i = 0; i < values.length; i++) {
					value = values[i] + ",";
				}
				value = value.substring(0, value.length() - 1);
			} else {
				value = valueObj.toString();
			}
			returnMap.put(name, value);
		}
		return returnMap;
	}

	// 处理POST请求参数
	private static Map postMethod(HttpServletRequest request)
			throws IOException {
		byte buffer[] = getRequestPostBytes(request);
		String charEncoding = request.getCharacterEncoding();
		if (charEncoding == null) {
			charEncoding = "UTF-8";
		}
		String param = new String(buffer, charEncoding);
		if(Tool.isEmpty(param)){
			return null;
		}
		return (Map) JSONObject.parse(param);
		
	}

	/**
	 * 描述:获取 post 请求的 byte[] 数组
	 * 
	 * 
	 * 举例:
	 * 
* * @param request * @return * @throws IOException */
private static byte[] getRequestPostBytes(HttpServletRequest request) throws IOException { int contentLength = request.getContentLength(); if (contentLength < 0) { return null; } byte buffer[] = new byte[contentLength]; for (int i = 0; i < contentLength;) { int readlen = request.getInputStream().read(buffer, i, contentLength - i); if (readlen == -1) { break; } i += readlen; } return buffer; }

你可能感兴趣的:(JAVA,微信,小程序,数据类型转换)