JAVA小工具-05-利用springmvc拦截器实现接口调用监控

言于头:在项目中服务中通常我们需要监控服务接口的调用情况,在springboot项目中,我们可以使用 spring-boot-starter-actuator模块进行实现,然而在spring体系中,我们也可以利用mvc拦截器进行简单实现。
下面就是一个利用HandlerInterceptor和WebMvcConfigurer 实现的服务接口调用监控小例子,完整代码整理如下。

/**
* 拦截器策略配置类 
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry interceptorRegistry) {
        InterceptorRegistration registration=interceptorRegistry.addInterceptor(new ControllerInterceptor());
        // 此处添加拦截策略 /**表示全部拦截
        registration.addPathPatterns("/**");
    }
    @Override
    public void configurePathMatch(PathMatchConfigurer pathMatchConfigurer) {}
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer contentNegotiationConfigurer) {}
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer asyncSupportConfigurer) { }
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer defaultServletHandlerConfigurer) {}
    @Override
    public void addFormatters(FormatterRegistry formatterRegistry) {}
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {}
    @Override
    public void addCorsMappings(CorsRegistry corsRegistry) {}
    @Override
    public void addViewControllers(ViewControllerRegistry viewControllerRegistry) {}
    @Override
    public void configureViewResolvers(ViewResolverRegistry viewResolverRegistry) {}
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> list) {}
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> list) {}
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> list) {}
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> list) {}
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {}
    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {}
    @Override
    public Validator getValidator() {return null;}
    @Override
    public MessageCodesResolver getMessageCodesResolver() {return null;}
}

/**
* 拦截后的处理类 
*/
public class ControllerInterceptor implements HandlerInterceptor {
    private static final  Logger LOGGER  = LoggerFactory.getLogger(ControllerInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String method = request.getMethod();
        String url = request.getRequestURL().toString();
        String requestIp = getRequestIp(request);
        StringBuilder sb = new StringBuilder();
        sb .append("【开始请求】:\n-------------------------------------------------------------\n");
        HandlerMethod h = (HandlerMethod) handler;
        sb.append("Controller: ").append(h.getBean().getClass().getName()).append("\n");
        sb.append("Method    : ").append(method).append("\n");
        sb.append("URL       : ").append(url).append("\n");
        sb.append("IP        : ").append(requestIp).append("\n");
        sb .append("-------------------------------------------------------------\n");
        LOGGER.info(sb.toString());
        // 填入当前接口的调用开始时间
        request.setAttribute("startTime",System.currentTimeMillis());
        return true;
  	}
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav) {}
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {
        String method = request.getMethod();
        String url = request.getRequestURL().toString();
        Long startTime=(Long)request.getAttribute("startTime");
        Long expireTime=System.currentTimeMillis()-startTime;
        String requestIp = getRequestIp(request);
        StringBuilder sb = new StringBuilder();
        sb .append("【结束请求】:\n-------------------------------------------------------------\n");
        HandlerMethod h = (HandlerMethod) handler;
        sb.append("Controller: ").append(h.getBean().getClass().getName()).append("\n");
        sb.append("Method    : ").append(method).append("\n");
        sb.append("URL       : ").append(url).append("\n");
        sb.append("IP        : ").append(requestIp).append("\n");
        sb.append("EXPIRETIME: ").append(expireTime).append("(ms)\n");
        sb .append("-------------------------------------------------------------\n");
        LOGGER.info(sb.toString());
    }

    /*  *
      * @description:  获取客户端真实IP
      **/
    private  String getRequestIp(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.getRemoteAddr();
            if(ip.equals("127.0.0.1")){
                //根据网卡取本机配置的IP
                InetAddress inet=null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (Exception e) {
                    LOGGER.error("获取ip异常",e);
                }
                if (inet!=null){
                    ip= inet.getHostAddress();
                }else{
                    ip="";
                }
            }
        }
        // 多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
        if(ip != null && ip.length() > 15 && ip.indexOf(",")>=1){
            ip = ip.substring(0,ip.indexOf(","));
        }
        return ip;
    }
}

项目中加入以上配置后,在接口调用时会输出接口调用类、方法类型、请求的url、客户端IP以及调用完成后本次请求的耗时信息等。调用结果如下:

在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值