Authored by hugufei

添加controller层的拦截器

  1 +package com.yoho.search.interceptor;
  2 +
  3 +import java.text.SimpleDateFormat;
  4 +
  5 +import javax.servlet.http.HttpServletRequest;
  6 +import javax.servlet.http.HttpServletResponse;
  7 +
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.core.NamedThreadLocal;
  11 +import org.springframework.web.servlet.HandlerInterceptor;
  12 +import org.springframework.web.servlet.ModelAndView;
  13 +
  14 +import com.yoho.search.utils.HttpServletRequestUtils;
  15 +
  16 +public class ControllerInterceptor implements HandlerInterceptor {
  17 +
  18 + private static final Logger logger = LoggerFactory.getLogger(ControllerInterceptor.class);
  19 +
  20 + private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("ThreadLocal StartTime");
  21 +
  22 + @Override
  23 + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle) throws Exception {
  24 + long beginTime = System.currentTimeMillis();// 1、开始时间
  25 + startTimeThreadLocal.set(beginTime); // 线程绑定变量(该数据只有当前请求的线程可见)
  26 + return true;
  27 + }
  28 +
  29 + @Override
  30 + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) throws Exception {
  31 +
  32 + }
  33 +
  34 + @Override
  35 + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) throws Exception {
  36 + long beginTime = startTimeThreadLocal.get();// 1、得到线程绑定的局部变量(开始时间)
  37 + long endTime = System.currentTimeMillis(); // 2、结束时间
  38 + long cost = endTime - beginTime;
  39 + if (cost > 200) {
  40 + logger.info("run more than 200ms:{} cost:{}ms uri: {}, param:{}",new SimpleDateFormat("yyyy-HH-MM hh:mm:ss").format(endTime), cost, request.getRequestURI(),HttpServletRequestUtils.transParamType(request));
  41 + }
  42 + }
  43 +
  44 +}
1 package com.yoho.search.restapi; 1 package com.yoho.search.restapi;
2 2
3 import java.util.HashMap; 3 import java.util.HashMap;
4 -import java.util.Iterator;  
5 import java.util.Map; 4 import java.util.Map;
6 5
7 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletRequest;
@@ -20,6 +19,7 @@ import com.yoho.search.service.SearchService; @@ -20,6 +19,7 @@ import com.yoho.search.service.SearchService;
20 import com.yoho.search.service.SearchShopService; 19 import com.yoho.search.service.SearchShopService;
21 import com.yoho.search.service.SearchSortSizeService; 20 import com.yoho.search.service.SearchSortSizeService;
22 import com.yoho.search.service.SearchSuggestService; 21 import com.yoho.search.service.SearchSuggestService;
  22 +import com.yoho.search.utils.HttpServletRequestUtils;
23 import com.yoho.search.utils.JsonUtil; 23 import com.yoho.search.utils.JsonUtil;
24 import com.yoho.search.vo.SearchApiResult; 24 import com.yoho.search.vo.SearchApiResult;
25 import com.yoho.search.vo.SizeSortReqBO; 25 import com.yoho.search.vo.SizeSortReqBO;
@@ -265,19 +265,8 @@ public class SearchController { @@ -265,19 +265,8 @@ public class SearchController {
265 /** 265 /**
266 * 将HttpServletRequest中被锁定的ParameterMap转化为普通的HashMap 266 * 将HttpServletRequest中被锁定的ParameterMap转化为普通的HashMap
267 * */ 267 * */
268 - @SuppressWarnings("unchecked")  
269 private Map<String, String> transParamType(HttpServletRequest request) { 268 private Map<String, String> transParamType(HttpServletRequest request) {
270 - Map<String, Object> paramMap = request.getParameterMap();  
271 - Map<String, String> resultMap = new HashMap<String, String>();  
272 - Iterator<String> itKeys = paramMap.keySet().iterator();  
273 - while (itKeys.hasNext()) {  
274 - String key = itKeys.next();  
275 - String val = ((String[]) paramMap.get(key))[0];  
276 - resultMap.put(key, val);  
277 - }  
278 - resultMap.put("Referer", request.getHeader("Referer"));  
279 - resultMap.put("User-Agent", request.getHeader("User-Agent"));  
280 - return resultMap; 269 + return HttpServletRequestUtils.transParamType(request);
281 } 270 }
282 271
283 private Map<String, Object> errorReturn(final String funName, final Map<String, ?> paramMap, final Exception e) { 272 private Map<String, Object> errorReturn(final String funName, final Map<String, ?> paramMap, final Exception e) {
  1 +package com.yoho.search.utils;
  2 +
  3 +import java.util.HashMap;
  4 +import java.util.Iterator;
  5 +import java.util.Map;
  6 +
  7 +import javax.servlet.http.HttpServletRequest;
  8 +
  9 +public class HttpServletRequestUtils {
  10 +
  11 + @SuppressWarnings("unchecked")
  12 + public static Map<String, String> transParamType(HttpServletRequest request) {
  13 + Map<String, Object> paramMap = request.getParameterMap();
  14 + Map<String, String> resultMap = new HashMap<String, String>();
  15 + Iterator<String> itKeys = paramMap.keySet().iterator();
  16 + while (itKeys.hasNext()) {
  17 + String key = itKeys.next();
  18 + String val = ((String[]) paramMap.get(key))[0];
  19 + resultMap.put(key, val);
  20 + }
  21 + resultMap.put("IP", getIpAddress(request));
  22 + return resultMap;
  23 + }
  24 +
  25 + public static String getIpAddress(HttpServletRequest request){
  26 + String ip = request.getHeader("x-forwarded-for");
  27 + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  28 + ip = request.getHeader("Proxy-Client-IP");
  29 + }
  30 + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  31 + ip = request.getHeader("WL-Proxy-Client-IP");
  32 + }
  33 + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  34 + ip = request.getHeader("HTTP_CLIENT_IP");
  35 + }
  36 + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  37 + ip = request.getHeader("HTTP_X_FORWARDED_FOR");
  38 + }
  39 + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  40 + ip = request.getRemoteAddr();
  41 + }
  42 + return ip;
  43 + }
  44 +
  45 +}
@@ -31,17 +31,18 @@ @@ -31,17 +31,18 @@
31 </property> 31 </property>
32 </bean> 32 </bean>
33 33
34 -  
35 - <!-- 服务错误码异常处理 -->  
36 - <bean class="com.yoho.error.exception.handler.ServiceGlobalExceptionHandler" />  
37 -  
38 - <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->  
39 - <mvc:annotation-driven>  
40 - <mvc:message-converters>  
41 - <ref bean="stringConverter" />  
42 - <ref bean="jsonConverter" />  
43 - </mvc:message-converters>  
44 - </mvc:annotation-driven> 34 + <!-- controller耗时的监听器 -->
  35 + <bean id="controllerInterceptor" class="com.yoho.search.interceptor.ControllerInterceptor"/>
  36 + <mvc:interceptors>
  37 + <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
  38 + <mvc:interceptor>
  39 + <mvc:mapping path="/**"/>
  40 + <!-- 需排除拦截的地址 -->
  41 + <mvc:exclude-mapping path="/" />
  42 + <mvc:exclude-mapping path="/test" />
  43 + <ref bean="controllerInterceptor"/>
  44 + </mvc:interceptor>
  45 + </mvc:interceptors>
45 46
46 <mvc:interceptors> 47 <mvc:interceptors>
47 <ref bean="threadProfileInterceptor"/> 48 <ref bean="threadProfileInterceptor"/>
@@ -57,7 +58,6 @@ @@ -57,7 +58,6 @@
57 </property> 58 </property>
58 </bean> 59 </bean>
59 60
60 -  
61 <!-- json转换器 application/json --> 61 <!-- json转换器 application/json -->
62 <bean id="jsonConverter" 62 <bean id="jsonConverter"
63 class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> 63 class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
@@ -65,23 +65,26 @@ @@ -65,23 +65,26 @@
65 <array value-type="com.alibaba.fastjson.serializer.SerializerFeature"> 65 <array value-type="com.alibaba.fastjson.serializer.SerializerFeature">
66 <value>DisableCircularReferenceDetect</value> 66 <value>DisableCircularReferenceDetect</value>
67 <value>WriteMapNullValue</value> 67 <value>WriteMapNullValue</value>
68 -  
69 </array> 68 </array>
70 </property> 69 </property>
71 </bean> 70 </bean>
72 71
  72 + <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
  73 + <mvc:annotation-driven>
  74 + <mvc:message-converters>
  75 + <ref bean="stringConverter" />
  76 + <ref bean="jsonConverter" />
  77 + </mvc:message-converters>
  78 + </mvc:annotation-driven>
  79 +
73 <!--service接口调用拦截器--> 80 <!--service接口调用拦截器-->
74 - <bean id="serviceMethodInterceptor" class="com.yoho.core.common.monitor.interceptor.MethodProfileInterceptor">  
75 - </bean> 81 + <bean id="serviceMethodInterceptor" class="com.yoho.core.common.monitor.interceptor.MethodProfileInterceptor"/>
76 <aop:config> 82 <aop:config>
77 - <aop:pointcut id="serviceMethodPoint"  
78 - expression="(execution(* com.yoho.*.*.service.*.*(..))) or (execution(* com.yoho.*.*.service.impl.*.*(..))) or (execution(* com.yoho.*.*.restapi.*.*(..)))  
79 - "/> 83 + <aop:pointcut id="serviceMethodPoint" expression="(execution(* com.yoho.*.*.service.*.*(..))) or (execution(* com.yoho.*.*.service.impl.*.*(..))) or (execution(* com.yoho.*.*.restapi.*.*(..)))"/>
80 <aop:advisor pointcut-ref="serviceMethodPoint" advice-ref="serviceMethodInterceptor"/> 84 <aop:advisor pointcut-ref="serviceMethodPoint" advice-ref="serviceMethodInterceptor"/>
81 </aop:config> 85 </aop:config>
82 86
83 - <bean id="applicationContextUtil" class="com.yoho.search.utils.ApplicationContextUtil">  
84 - </bean>  
85 - <!-- Redis 配置 end --> 87 + <bean id="serviceGlobalExceptionHandler" class="com.yoho.error.exception.handler.ServiceGlobalExceptionHandler" />
  88 + <bean id="applicationContextUtil" class="com.yoho.search.utils.ApplicationContextUtil"></bean>
86 89
87 </beans> 90 </beans>