解决在Filter中读取Request中的流后, 然后再Control中读取不到的做法

  1. web.xml中配置过滤器

    <filter>
		<filter-name>TokenCheckFilter</filter-name>
		<filter-class>XXX.token.TokenCheckFilter</filter-class>
		<init-param>
		   <param-name>excludedPages</param-name>
		   <param-value>/mobile/login,/mobile/register,/mobile/errorPermission</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>TokenCheckFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

       备注:/mobile/login,/mobile/register,/mobile/errorPermission是例外项

  2.  实现TokenCheckFilter

public class TokenCheckFilter implements Filter {

   // private static final Logger logger = LoggerFactory.getLogger(TokenCheckFilter.class);
   // private static final String redisServer = Global.getConfig("redis.server");
    
    private String excludedPages;       
    private String[] excludedPageArray;
    
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
             //如果请求在web.xml配置的例外项之内,则直接转发到目的地址
		if (isExcludedPage((HttpServletRequest) req)) {
			chain.doFilter(req, resp);
		} else {
			try {
			// 防止流读取一次后就没有了, 所以需要将流继续写出去
				TokenHttpRequestWrapper tokenHttpRequestWrapper = 
				       new TokenHttpRequestWrapper((HttpServletRequest) req);
				String requestBody = tokenHttpRequestWrapper.getBody();
				
                  //拿到流之后,就可以做自己的处理了
                   *
                   *
                   *
                                
                 // 下面/*  */中的代码可以忽略不计
			       /*JSONObject object = JSON.parseObject(requestBody);
				String token = (String) object.get("token");

				if (StringUtils.isEmpty(token)) {
					sendRedirectToError((HttpServletRequest) req,
							(HttpServletResponse) resp);
					return;
				}

				@SuppressWarnings("resource")
				Jedis jedis = new Jedis(redisServer);
				String moblie = jedis.get(token);
				if (StringUtils.isEmpty(moblie)) {
					sendRedirectToError((HttpServletRequest) req,
							(HttpServletResponse) resp);
					return;
				}*/
				
				
                       //做完自己的处理后,跳转到目的地址
				chain.doFilter(tokenHttpRequestWrapper, resp);

			} catch (Exception e) {
				sendRedirectToError((HttpServletRequest) req,
						(HttpServletResponse) resp);
				return;
			}

		}
    	
    }

    public void init(FilterConfig config) throws ServletException {
		excludedPages = config.getInitParameter("excludedPages");
		if (StringUtils.isNotEmpty(excludedPages)) {
			System.out.println(excludedPages);
			excludedPageArray = excludedPages.split(",");
		}
		return;
    }
    
    private boolean sendRedirectToError(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		StringBuffer sb = new StringBuffer(req.getContextPath());
		sb.append("/mobile/errorPermission");
		resp.sendRedirect(sb.toString());
		//logger.info(Messages.ERROR_PERMISSION);
		return false;
	} 
    
    private boolean isExcludedPage(HttpServletRequest req){
		boolean isExcludedPage = false;
		for (String page : excludedPageArray) {// 判断是否在过滤url之外
			if ((req).getServletPath().equals(page)) {
				isExcludedPage = true;
				break;
			}
		}
		return isExcludedPage;
    }
}

   3. 因为流只能读一次就没有了, 为了后面的代码(Controller)还能够取得流, 我们还需要建一个类将其写出去才行

public class TokenHttpRequestWrapper extends HttpServletRequestWrapper {

    private String body;

    public TokenHttpRequestWrapper(HttpServletRequest request) {
        super(request);
        body = ReqUtil.getRequestBody(request);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    public String getBody(){
        return body;
    }
}

   4. 实现TokenHttpRequestWrapper中调用用来读取流的工具类ReqUtil

public class ReqUtil {

	public static String getRequestBody(HttpServletRequest request){
		StringBuilder buffer = new StringBuilder();
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(
			                 new InputStreamReader(request.getInputStream(), "UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != reader) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return buffer.toString();
	}	
}

   5. 然后在Controller中的方法中就可以读取流了

@RequestMapping(value = "/moblie/login",method = RequestMethod.POST)
@ResponseBody
public Object login(@RequestBody User user) {
    //System.out.println(user.getName());
}


转载于:https://my.oschina.net/u/2416019/blog/532213

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值