springmvc中HandlerInterceptorAdapter拦截器的使用

在preHandle中,可以进行编码、安全控制等处理;
在postHandle中,有机会修改ModelAndView;
在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。
以下例子用来拦截/local/**的url,并验证签名,只有验证通过的才能进行下一步流程。
在LocalAuthRequestInterceptor中:

package com.zqsign.app.privatearbitrate.interceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zqsign.app.privatearbitrate.model.viewmodel.Response;
import com.zqsign.app.privatearbitrate.util.RsaSign;
import com.zqsign.app.privatearbitrate.util.UrlParamUtil;
import com.zqsign.app.privatearbitrate.util.constants.ZqConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.TreeMap;

public class LocalAuthRequestInterceptor extends HandlerInterceptorAdapter {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 验证签名,签名通过放行,否则返回203
     * 用客户公钥解密
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("********************服务端请求:{}******************************", request.getRequestURI());

        String paramStr = null;
        String sign = null;
        if (HttpMethod.GET.toString().equals(request.getMethod())) {
            TreeMap<String, String> paramMap = UrlParamUtil.paramMap2TreeMap(request.getParameterMap());
            paramStr = UrlParamUtil.Map2Str(paramMap);
            sign = paramMap.get("sign");
        } else {
            RepeatedlyReadRequestWrapper requestWrapper = (RepeatedlyReadRequestWrapper) request;
            sign = request.getHeader(HttpHeaders.AUTHORIZATION);
            if (sign != null) {
                Object jsonObject = JSON.parse(this.getBodyString(requestWrapper));
                paramStr = JSONObject.toJSONString(jsonObject, SerializerFeature.MapSortField);
            }

        }
        boolean result = verifySign(paramStr, sign);
        if (!result) {
            response.getWriter().print(JSON.toJSON(Response.error(100,"Request sign error!")));
        }
        return result;
    }

    private boolean verifySign(String paramStr,  String sign) {
        try {
            if (sign == null) {
                return false;
            }
            if (paramStr != null && sign != null) {
                boolean result = RsaSign.verify(paramStr, sign, ZqConfig.ZQ_PUBLIC_KEY);
                return result;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取请求Body
     *
     * @param request
     * @return
     */
    private 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>
     */
    private 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;
    }

}

在spring-mvc.xml的配置:

<mvc:interceptors>
<mvc:interceptor>
			<mvc:mapping path="/local/**"/>
			<bean class="com.zqsign.app.privatearbitrate.interceptor.LocalAuthRequestInterceptor" autowire="byType">	</bean>
		</mvc:interceptor>
</mvc:interceptors>

在web.xml的配置:

 <servlet>
    <servlet-name>appServlet</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>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

说明:此实现是对/local/**的url进行请求拦截,只能签名通过的才能进行请求。

猜你喜欢

转载自blog.csdn.net/shidebin/article/details/82907711