解決在Filter中讀取Request中的流後, 而後再Control中讀取不到的作法

  1. web.xml中配置過濾器java

    <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是例外項web

  2.  實現TokenCheckFilterredis

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)還可以取得流, 咱們還須要建一個類將其寫出去才行app

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中調用用來讀取流的工具類ReqUtilide

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());
}
相關文章
相關標籤/搜索