RESTful API

特点:

1.用URL描述资源

2.使用HTTP方法描述行为。使用HTTP状态码来表示不同的结果

3.使用json交互数据

4.RESTful只是一种风格,并不是强制标准

restful API 的拦截

过滤器(Filter)

@Component
public class TimeFilter implements Filter {

    @Override
    public void destroy() {
        System.out.println("time filter destroy");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("time filter start");
        long start = new Date().getTime();
        chain.doFilter(request, response);
        System.out.println("time filter 耗时:"+(new Date().getTime() - start));
        System.out.println("time filter finish");
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("time filter init");
    }

}

SpringBoot将第三方过滤器filter(没有@Component注解)加入自己项目:

@Configuration
public class WebConfig {
    //以TimeFilter作为第三方过滤器为例
    @Bean
    public FilterRegistrationBean timeFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        TimeFilter timeFilter = new TimeFilter();
        registrationBean.setFilter(timeFilter);
        
        List<String> urls = new ArrayList<>();
        urls.add("/*");
        registrationBean.setUrlPatterns(urls);
        
        return registrationBean;
    }
}

filter局限性:只能获取http的请求和响应以及它们的参数,不知由哪个控制器和方法处理的,因为Filter接口是由JavaEE规范定义的并不知跟Spring相关任何东西。这时需要Spring框架提供的机制Interceptor。

拦截器(Interceptor)

@Component
public class TimeInterceptor implements HandlerInterceptor {
    //控制器某个方法被调用之前此方法先被调用
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
        System.out.println(((HandlerMethod)handler).getMethod().getName());
        request.setAttribute("startTime", new Date().getTime());
        return true;
    }

    //控制器方法被调用之后此方法被调用,如果控制器方法抛异常此方法不被调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
        System.out.println("postHandle");
        Long start = (Long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗时:" + (new Date().getTime() - start));
    }
    
    //不管控制器方法是否正常被调用此方法都被调用
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e)
            throws Exception {
        System.out.println("afterHandle");
        Long start = (Long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗时:" + (new Date().getTime() - start));
        System.out.println("Exception is " + e);
    }
}

还需要额外配置

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Autowired
    private TimeInterceptor timeInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }
}

Interceptor局限性:无法获取获取控制器被调用方法参数的值。这时需要AOP面向切面编程Aspect。

切片(Aspect)

切片简介:

1.切入点 ( 注解 ):在哪些方法上起作用,在什么时候起作用

2.增强 ( 方法 ):起作用时执行的业务逻辑

@Aspect
@Component
public class TimeAspect {

    @Around("execution(* com.hclz.web.controller.UserController.*(..))")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("time aspect start");
        //获取控制器别调用方法的参数
        Object[] args = pjp.getArgs();
        for(Object arg : args) {
            System.out.println("arg is " + arg);
        }
        long start = new Date().getTime();
        Object object = pjp.proceed();
        System.out.println("time aspect 耗时:" + (new Date().getTime() - start));
        System.out.println("time aspect end");
        return object;
    }
    
}

aspect局限性:无法获取原始http和http响应的对象

restful API 起作用的顺序

原文地址:https://www.cnblogs.com/tripleDemo/p/11327672.html