ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RESTful API的拦截

2021-06-27 17:00:16  阅读:204  来源: 互联网

标签:registrationBean Object System API println 拦截 RESTful public out



title: RESTful API的拦截
tags: [Spring,restful,filter,aspect,interceptor]
date: 2018/5/12 23:46:25
categories:

  • 开发
  • java

总的来说拦截请求,我们在开发过程中会遇到以下3种方式

  • 自定义过滤器 Servlet Filter
  • Spring Mvc Interceptor
  • Aspect

自定义过滤器

特点和局限

  • 可以拿到原始的http请求和响应的信息

  • 但是拿不到真正处理请求的那个方法的信息,因为真正处理请求的方法信息不是由servlet提供的 ,一般是由mvc框架(如:spring mvc -> controller -> method() ) 提供的

关键代码

@Component
public class XXXFilter implements Filter{
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
			
        System.out.println("doFilter start");
		
		// 对request response 进行拦截处理
		
		// 放行给其它过滤器->处理业务
        chain.doFilter(request, response);
		
        System.out.println("doFilter finish");
    }

    ……
}

配置启用

  • xml(省略)

  • spring boot

    @Configuration
    public class WebConfig {
        @Bean
        public FilterRegistrationBean xxxFiler() {
            FilterRegistrationBean registrationBean = new FilterRegistrationBean();
            XXXFilter xxxFilter = new XXXFilter();
            registrationBean.setFilter(xxxFilter);
            List<String> urls = new ArrayList<>();
    		//url mapping 
            urls.add("/*");
            registrationBean.setUrlPatterns(urls);
            return registrationBean;
        }
    }
    

自定义拦截器

特点和局限

  • 既可以拿到原始的http请求和响应, 也可以拿到真正处理请求的方法的信息

  • 拿不到具体方法被调用时所传入的参数值

关键代码

@Component
public class XXXInterceptor implements HandlerInterceptor{

	// 该方法将在Controller处理之前进行调用
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("拦截 - 方法前置处理");

        System.out.println("处理类名:" + ((HandlerMethod)handler).getBean().getClass().getName());
        System.out.println("方法名:" +((HandlerMethod)handler).getMethod().getName());

		// true 表示放行调用处理方法 
        return true;
    }

	// 需要 preHandle 返回为true 
	// 当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("controller 方法处理完了");
		//我可以在这里对 modelAndView 做点什么  
    }
    // 需要 preHandle 返回为true 
	// 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("拦截 - 请求后置处理");
        System.out.println("异常信息:" + ex);
    }

}

配置启用

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{

    @Autowired
    private XXXInterceptor xxxInterceptor;
	
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
		// 注册拦截器
        registry.addInterceptor(xxxInterceptor);
    }

	/* ---------------------我是分隔线------------------------------ */
    @Bean
    public FilterRegistrationBean xxxFiler() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        XXXFilter xxxFilter = new XXXFilter();
        registrationBean.setFilter(xxxFilter);
        List<String> urls = new ArrayList<>();
		//url mapping 
        urls.add("/*");
        registrationBean.setUrlPatterns(urls);
        return registrationBean;
    }
}

Aspect增强

特点

  • 可以拿到方法被调用时传递进来的参数值
  • 拿不到原始的http请求和响应的对象

关键代码

// 定义一个切面并交给Spring容器管理
@Aspect
@Component
public class MyAspect {
	//定义切入点(1.在哪些方法上起作用 2.什么时候起作用)
    @Around("execution(* com.web.controller.UserController.*(..))")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("aspect into");
        //方法参数的数组
        Object[] args = pjp.getArgs();
		int i = 0;
        for (Object arg : args) {
            System.out.println("方法参数 "+(i++)+" : " + arg);
        }
        //执行实际方法
        Object object = pjp.proceed();
        System.out.println("aspect out");
        return object;
    }

}

3种方式的执行顺序

  • 假如同时存在这3种拦截,在整个请求响应中执行顺序如下:

    -> Filter -> Interceptor -> ControllerAdvice -> Aspect -> Controller

  • 如果发生异常

    检测异常的顺序就反过来了

    -> Controller -> Aspect -> ControllerAdvice -> Interceptor -> Filter -> tomcat

参考文章

CSDN_HCX's RESTful API的拦截

标签:registrationBean,Object,System,API,println,拦截,RESTful,public,out
来源: https://www.cnblogs.com/skystarry/p/14940946.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有