SpringCloud(8)—— 国寿i动项目经验之(拦截器Interceptors技术)
国寿i动项目经验之(拦截器Interceptors技术):
由于Springcloud框架是对Springmvc 进行的二次封装,可以采用面向切面的方式进行前端请求拦截,具体功能逻辑如下:

WebMvcConfigurer.java
package com.sinosoft.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import java.util.ArrayList; import java.util.List; @Configuration public class WebMvcConfigurer extends WebMvcConfigurerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(WebMvcConfigurer.class); /** * 添加拦截器 目的是拦截前端过来的请求 * * @param registry */ public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new RequestLog()).addPathPatterns("/**"); super.addInterceptors(registry); } /** * 初始化过滤器 */ @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); MyFilter httpBasicFilter = new MyFilter(); registrationBean.setFilter(httpBasicFilter); List<String> urlPatterns = new ArrayList<String>(); urlPatterns.add("*"); registrationBean.setUrlPatterns(urlPatterns); return registrationBean; } /** * 解决前端跨域请求 * <p> * 简单跨域就是GET,HEAD和POST请求,但是POST请求的"Content-Type"只能是application/x-www-form-urlencoded, multipart/form-data 或 text/plain * <p> * 反之,就是非简单跨域,此跨域有一个预检机制,说直白点,就是会发两次请求,一次OPTIONS请求,一次真正的请求 * * @return */ @Bean public CorsFilter corsFilter() { LOGGER.info("开启CorsFilter,解决前后端分离模式接口交互跨域问题"); final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); final CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowCredentials(true);// 允许cookies跨域 corsConfiguration.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin corsConfiguration.addAllowedHeader("*");// #允许访问的头信息,*表示全部 corsConfiguration.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了 corsConfiguration.addAllowedMethod("*");//允许所有的请求方式 urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); return new CorsFilter(urlBasedCorsConfigurationSource); } }
LogRecordAspect.java
package com.sinosoft.config; import com.sinosoft.dto.common.RequestInfo; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; /** * Created by zh on 03/29/17. */ @Aspect //定义一个切面 @Configuration public class LogRecordAspect { /** * 日志打印 */ private static final Logger LOGGER = LoggerFactory.getLogger(LogRecordAspect.class); /** * 定义切点Pointcut * 监控请求对应controller过来接口 */ @Pointcut("execution(* com.sinosoft.controller.*Controller.*(..))") public void excudeService() { } @Around("excudeService()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { LOGGER.info("监控前端请求management应用模块过来的接口..."); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); String url = request.getRequestURL().toString();//获取接口请求详细路径 String method = request.getMethod(); //获取接口请求方法 String uri = request.getRequestURI(); //获取接口请求路径 String queryString = request.getQueryString(); //获取接口请求参数 Object[] args = pjp.getArgs(); try { for (int i = 0; i < args.length; i++) { if (args[i] instanceof RequestInfo<?>) { RequestInfo<?> r = (RequestInfo<?>) args[i]; LOGGER.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, r.toString()); } else { LOGGER.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, args[i]); } } } catch (Exception e) { LOGGER.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString); } // result的值就是被拦截方法的返回值 Object result = pjp.proceed(); //LOGGER.info("请求结束,Controller的返回值是 " + result); return result; } }
RequestLog.java
package com.sinosoft.config; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.time.Instant; public class RequestLog extends HandlerInterceptorAdapter { /** * 前置检查 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String ip = request.getRemoteAddr(); Instant startTime = Instant.now(); request.setAttribute("logrequestStartTime", startTime); HandlerMethod handlerMethod = (HandlerMethod) handler; // 获取用户token Method method = handlerMethod.getMethod(); System.out.println("用户:"+ip+",访问目标:"+method.getDeclaringClass().getName() + "." + method.getName()); return true; } // controller处理完成 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); Instant startTime = (Instant) request.getAttribute("logrequestStartTime"); Instant endTime = Instant.now(); long executeTime = endTime.toEpochMilli()- startTime.toEpochMilli(); // log it if (executeTime > 1000) { System.out.println("[" + method.getDeclaringClass().getName() + "." + method.getName() + "] 执行耗时 : " + executeTime + "ms"); } else { System.out.println("[" + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "] 执行耗时 : " + executeTime + "ms"); } } }

浙公网安备 33010602011771号