web拦截器中读取request中流导致跳转controller失败问题解决方案

来源:互联网 发布:opencv sobel算法实现 编辑:程序博客网 时间:2024/06/05 22:47

请求的URL为:http://localhost:8980/helper/API/toQrcLogin

web.xml中添加过滤器

<filter><filter-name>sessionFilter</filter-name><filter-class>com.Long.api.common.SessionFilter</filter-class></filter><filter-mapping><filter-name>sessionFilter</filter-name><url-pattern>/API/*</url-pattern></filter-mapping>        ...         ...    <servlet>        <servlet-name>SpringMVC</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>classpath:spring-mvc.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>        <async-supported>true</async-supported>    </servlet>    <servlet-mapping>        <servlet-name>SpringMVC</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping>

spring-mvc.xml中增加拦截器的处理,其中会读到request中的inputStream

<!-- 拦截器 -->    <mvc:interceptors>        <mvc:interceptor>            <!-- 对所有的请求拦截使用/** ,对某个模块下的请求拦截使用:/myPath/* -->            <mvc:mapping path="/API/**" />            <ref bean="userAccessInterceptor" />        </mvc:interceptor>    </mvc:interceptors>     <bean id="userAccessInterceptor"        class="com.Long.api.interceptor.UserAccessApiInterceptor">    </bean>
拦截器UserAccessApiInterceptor处理:

import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.nio.charset.Charset;import javax.servlet.ServletInputStream;import javax.servlet.ServletRequest;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;/** * 鉴权操作 */public class UserAccessApiInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// body中前台传入的参数String bodyParam = getBodyString(request);return super.preHandle(request, response, handler);}/** * 获取请求Body * * @param request * @return */public static String getBodyString(final ServletRequest request) {StringBuilder sb = new StringBuilder();InputStream inputStream = null;BufferedReader reader = null;try {inputStream = cloneInputStream(request.getInputStream());reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));String line = "";while ((line = reader.readLine()) != null) {sb.append(line);}}catch (IOException e) {e.printStackTrace();}finally {if (inputStream != null) {try {inputStream.close();}catch (IOException e) {e.printStackTrace();}}if (reader != null) {try {reader.close();}catch (IOException e) {e.printStackTrace();}}}return sb.toString();}/** * Description: 复制输入流</br> *  * @param inputStream * @return</br> */public static InputStream cloneInputStream(ServletInputStream inputStream) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;try {while ((len = inputStream.read(buffer)) > -1) {byteArrayOutputStream.write(buffer, 0, len);}byteArrayOutputStream.flush();}catch (IOException e) {e.printStackTrace();}InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());return byteArrayInputStream;}}
过滤器SessionFilter处理
import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.nio.charset.Charset;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ReadListener;import javax.servlet.ServletException;import javax.servlet.ServletInputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import org.apache.log4j.Logger;/** * 过滤器把请求流保存起来 * */public class SessionFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;// 防止流读取一次后就没有了, 所以需要将流继续写出去ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);chain.doFilter(requestWrapper, response);}@Overridepublic void destroy() {}/** * 保存流 *  * @author lyj 2015年12月16日 */public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {private Logger log = Logger.getLogger(this.getClass());private final byte[] body;public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {super(request);String sessionStream = getBodyString(request);body = sessionStream.getBytes(Charset.forName("UTF-8"));log.debug("保存的流" + sessionStream);}/** * 获取请求Body * * @param request * @return */public String getBodyString(final ServletRequest request) {StringBuilder sb = new StringBuilder();InputStream inputStream = null;BufferedReader reader = null;try {inputStream = cloneInputStream(request.getInputStream());reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));String line = "";while ((line = reader.readLine()) != null) {sb.append(line);}}catch (IOException e) {e.printStackTrace();}finally {if (inputStream != null) {try {inputStream.close();}catch (IOException e) {e.printStackTrace();}}if (reader != null) {try {reader.close();}catch (IOException e) {e.printStackTrace();}}}return sb.toString();}/** * Description: 复制输入流</br> *  * @param inputStream * @return</br> */public InputStream cloneInputStream(ServletInputStream inputStream) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;try {while ((len = inputStream.read(buffer)) > -1) {byteArrayOutputStream.write(buffer, 0, len);}byteArrayOutputStream.flush();}catch (IOException e) {e.printStackTrace();}InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());return byteArrayInputStream;}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream()));}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(body);return new ServletInputStream() {@Overridepublic int read() throws IOException {return bais.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}};}}}

controler中的处理:

import java.io.IOException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import com.Long.api.business.model.QrcPram;/** * Author:Mr.Demen(CPB) Date:2017年4月10日上午10:06:36 </br> * Description: 二维码相关登录逻辑 </br> *     V1.0 新增</br> */@Controllerpublic class QRCodeController {/** * Description: 登录</br> *  * @param request * @param response * @param key * @throws IOException</br> */@RequestMapping(method = RequestMethod.POST, value = "API/toQrcLogin")public @ResponseBody void toQrcLogin(HttpServletRequest request, HttpServletResponse response,@RequestBody QrcPram qrcParm)throws IOException {return;}}

待更新

0 0
原创粉丝点击