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");
        }

    }
}

 

 

 

  

posted @ 2017-06-10 19:00  xu_shuyi  阅读(331)  评论(0)    收藏  举报