springmvc中HandlerInterceptorAdapter攔截器的使用
阿新 • • 發佈:2018-12-12
在preHandle中,可以進行編碼、安全控制等處理; 在postHandle中,有機會修改ModelAndView; 在afterCompletion中,可以根據ex是否為null判斷是否發生了異常,進行日誌記錄。 在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進行請求攔截,只能簽名通過的才能進行請求。