Authored by hugufei

添加controller层的拦截器

package com.yoho.search.interceptor;
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.yoho.search.utils.HttpServletRequestUtils;
public class ControllerInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(ControllerInterceptor.class);
private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("ThreadLocal StartTime");
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle) throws Exception {
long beginTime = System.currentTimeMillis();// 1、开始时间
startTimeThreadLocal.set(beginTime); // 线程绑定变量(该数据只有当前请求的线程可见)
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) throws Exception {
long beginTime = startTimeThreadLocal.get();// 1、得到线程绑定的局部变量(开始时间)
long endTime = System.currentTimeMillis(); // 2、结束时间
long cost = endTime - beginTime;
if (cost > 200) {
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));
}
}
}
... ...
package com.yoho.search.restapi;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
... ... @@ -20,6 +19,7 @@ import com.yoho.search.service.SearchService;
import com.yoho.search.service.SearchShopService;
import com.yoho.search.service.SearchSortSizeService;
import com.yoho.search.service.SearchSuggestService;
import com.yoho.search.utils.HttpServletRequestUtils;
import com.yoho.search.utils.JsonUtil;
import com.yoho.search.vo.SearchApiResult;
import com.yoho.search.vo.SizeSortReqBO;
... ... @@ -265,19 +265,8 @@ public class SearchController {
/**
* 将HttpServletRequest中被锁定的ParameterMap转化为普通的HashMap
* */
@SuppressWarnings("unchecked")
private Map<String, String> transParamType(HttpServletRequest request) {
Map<String, Object> paramMap = request.getParameterMap();
Map<String, String> resultMap = new HashMap<String, String>();
Iterator<String> itKeys = paramMap.keySet().iterator();
while (itKeys.hasNext()) {
String key = itKeys.next();
String val = ((String[]) paramMap.get(key))[0];
resultMap.put(key, val);
}
resultMap.put("Referer", request.getHeader("Referer"));
resultMap.put("User-Agent", request.getHeader("User-Agent"));
return resultMap;
return HttpServletRequestUtils.transParamType(request);
}
private Map<String, Object> errorReturn(final String funName, final Map<String, ?> paramMap, final Exception e) {
... ...
package com.yoho.search.utils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
public class HttpServletRequestUtils {
@SuppressWarnings("unchecked")
public static Map<String, String> transParamType(HttpServletRequest request) {
Map<String, Object> paramMap = request.getParameterMap();
Map<String, String> resultMap = new HashMap<String, String>();
Iterator<String> itKeys = paramMap.keySet().iterator();
while (itKeys.hasNext()) {
String key = itKeys.next();
String val = ((String[]) paramMap.get(key))[0];
resultMap.put(key, val);
}
resultMap.put("IP", getIpAddress(request));
return resultMap;
}
public static String getIpAddress(HttpServletRequest request){
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
... ...
... ... @@ -30,19 +30,20 @@
</list>
</property>
</bean>
<!-- 服务错误码异常处理 -->
<bean class="com.yoho.error.exception.handler.ServiceGlobalExceptionHandler" />
<!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
<mvc:annotation-driven>
<mvc:message-converters>
<ref bean="stringConverter" />
<ref bean="jsonConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<!-- controller耗时的监听器 -->
<bean id="controllerInterceptor" class="com.yoho.search.interceptor.ControllerInterceptor"/>
<mvc:interceptors>
<!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!-- 需排除拦截的地址 -->
<mvc:exclude-mapping path="/" />
<mvc:exclude-mapping path="/test" />
<ref bean="controllerInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<mvc:interceptors>
<ref bean="threadProfileInterceptor"/>
</mvc:interceptors>
... ... @@ -57,7 +58,6 @@
</property>
</bean>
<!-- json转换器 application/json -->
<bean id="jsonConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
... ... @@ -65,23 +65,26 @@
<array value-type="com.alibaba.fastjson.serializer.SerializerFeature">
<value>DisableCircularReferenceDetect</value>
<value>WriteMapNullValue</value>
</array>
</property>
</bean>
<!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
<mvc:annotation-driven>
<mvc:message-converters>
<ref bean="stringConverter" />
<ref bean="jsonConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<!--service接口调用拦截器-->
<bean id="serviceMethodInterceptor" class="com.yoho.core.common.monitor.interceptor.MethodProfileInterceptor">
</bean>
<bean id="serviceMethodInterceptor" class="com.yoho.core.common.monitor.interceptor.MethodProfileInterceptor"/>
<aop:config>
<aop:pointcut id="serviceMethodPoint"
expression="(execution(* com.yoho.*.*.service.*.*(..))) or (execution(* com.yoho.*.*.service.impl.*.*(..))) or (execution(* com.yoho.*.*.restapi.*.*(..)))
"/>
<aop:pointcut id="serviceMethodPoint" expression="(execution(* com.yoho.*.*.service.*.*(..))) or (execution(* com.yoho.*.*.service.impl.*.*(..))) or (execution(* com.yoho.*.*.restapi.*.*(..)))"/>
<aop:advisor pointcut-ref="serviceMethodPoint" advice-ref="serviceMethodInterceptor"/>
</aop:config>
<bean id="applicationContextUtil" class="com.yoho.search.utils.ApplicationContextUtil">
</bean>
<!-- Redis 配置 end -->
<bean id="serviceGlobalExceptionHandler" class="com.yoho.error.exception.handler.ServiceGlobalExceptionHandler" />
<bean id="applicationContextUtil" class="com.yoho.search.utils.ApplicationContextUtil"></bean>
</beans>
\ No newline at end of file
... ...