SSM拦截器校验JSON数据(3) -- 解决拦截器获取json后,controller参数为空

本篇为系列文,不以目的为目的,以学习为目的。旨在学习,重在研究。

上一篇:SSM拦截器校验JSON数据(2) -- 从Request中获取json格式数据

创建AccountWrapper继承HttpServletRequestWrapper

HttpServletRequestWrapper介绍

package sinosoft.project.sso.utils.wrapper;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

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

import org.springframework.util.StreamUtils;

/**
 * @Description:  Account--Request--请求包装类,解决json只能接受一次的问题
 */
public class AccountWrapper extends HttpServletRequestWrapper{

	private byte[] requestBody;
	
	public AccountWrapper(HttpServletRequest request) throws IOException {
		super(request);
		requestBody = StreamUtils.copyToByteArray(request.getInputStream());
	}

	@Override
	public BufferedReader getReader() throws IOException {
		return new BufferedReader(new InputStreamReader(getInputStream(),StandardCharsets.UTF_8));
	}
	
	@Override
	public ServletInputStream getInputStream() throws IOException {
		if(requestBody == null){
			requestBody = new byte[0];
		}
		final ByteArrayInputStream  bais = new ByteArrayInputStream(requestBody);
		return new ServletInputStream() {
			
			@Override
			public int read() throws IOException {
				return bais.read();
			}
			
			@Override
			public void setReadListener(ReadListener readListener) {
				
			}
			
			@Override
			public boolean isReady() {
				return false;
			}
			
			@Override
			public boolean isFinished() {
				return false;
			}
		};
	}
}

修改preHandle的代码

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
	try{
		AccountInfo accountInfo = ssoJsonUtil.getParam(request);
		//省略业务判断逻辑代码
	}catch (Exception e) {
		return false;
	}
}    

/**
*@Description: 解析request里的AccountInfo
*/
public AccountInfo getParam(HttpServletRequest request) throws IOException, SSOException {
	String jsonString = null;
	String submitMethod = request.getMethod();
	if("GET".equals(submitMethod) || submitMethod.equals("get")){
		jsonString = getParamStringByGet(request);
	}else if(submitMethod.equals("POST") || submitMethod.equals("post")){
		jsonString = getParamJsonStringByPost(request);
	}else{
		logger.error("GetRequestJsonUtil解析Request参数错误--"+submitMethod);
	}
	logger.info("解析出来的参数--getParam:{}",jsonString);
	if(StringUtils.isBlank(jsonString)){
		throw new SSOException(new ReturnMsg(EC.RTF_FALSE,EC.ERR_PARAM_NULL_CODE,EC.ERR_PARAM_NULL_MSG));
	}
	AccountInfo parse = JSONObject.parseObject(jsonString, AccountInfo.class);
	return parse;
}

/**
*@Description: 解析post方式提交的json数据
*/
private String getParamJsonStringByPost(HttpServletRequest request) throws IOException {
    //这里修改了
	AccountWrapper aWrapper = new AccountWrapper(request);
	int contentLength = aWrapper.getContentLength();
	if(contentLength<0){
		return null;
	}
	byte buffer[]  = new byte[contentLength];
	for (int i = 0; i < contentLength; i++) {
		int readlen = aWrapper.getInputStream().read(buffer,i,contentLength -i);
		if(readlen == -1){
			break;
		}
		i+=readlen;
	}
	return new String(buffer,"UTF-8");
}

/**
*@Description: 解析get方式提交的request参数
*/
private String getParamStringByGet(HttpServletRequest request) throws IOException {
    //这里修改了
	AccountWrapper aWrapper = new AccountWrapper(request);
	return new String(aWrapper.getQueryString().getBytes("ios-8859-1"),"utf-8").replaceAll("%22", "\"");
}

这样并没有解决问题,因为request中的数据在复制给AccountWrapper 时读取过了(调用了request.getInputstream方法),所以要用AccountWrapper 代替request传到controller中。

这样就需要用过滤器配合

配置过滤器AccountFilter

package sinosoft.project.sso.utils.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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sinosoft.project.sso.utils.wrapper.AccountWrapper;

/**
 * @Description:  过滤器,用于controller可以获取json
 */

public class AccountFilter implements Filter{

	Logger logger = LoggerFactory.getLogger(AccountFilter.class);
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		AccountWrapper accountWrapper = null;
		logger.info("AccountFilter--doFilter");
		if(request instanceof HttpServletRequest){
			accountWrapper = new AccountWrapper((HttpServletRequest)request);
		}
		if(accountWrapper == null){
			chain.doFilter(request, response);
		}else {
			chain.doFilter(accountWrapper, response);//在这里将AccountWrapper代替request去了controller
		}
	}

	@Override
	public void destroy() {
		
	}

}

web.xml配置过滤器


  	ssoAccountFilter
  	sinosoft.project.sso.utils.filter.AccountFilter
  
  
  	ssoAccountFilter
  	/sso/account/*
  

spring-mvc注册拦截器 (如果在第一篇文章时配置了就不需要了)




    
         
        
    

 

大功告成

你可能感兴趣的:(ssm)