Restful Api 的拦截

本文详细探讨了JavaEE提供的过滤器Filter与Spring框架的Interceptor的区别及应用,包括自定义拦截器的实现、配置与测试,以及在异常处理和运行时异常情况下的行为。同时介绍了AOP切片在获取拦截方法参数中的作用。
摘要由CSDN通过智能技术生成

过滤器 Filter(javaee提供)

定义时间拦截器

在这里插入图片描述

/**
 * @Package com.whale.web.filter
 * @Description: 时间拦截器
 * @date 2019/2/11 13:18
 */
@Component//使拦截器生效
public class TimeFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("TimeFilter init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("TimeFilter start");
        long start = new Date().getTime();
        filterChain.doFilter(servletRequest,servletResponse);
        long end = new Date().getTime();
        System.out.println("TimeFilter耗时(毫秒) : " +(end-start));
        System.out.println("TimeFilter finish");
    }

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

请求方法

 /**
     * @param idxx
     * @return
     */
    @GetMapping("{id:\\d++}")
    @JsonView(User.UserSimpleView.class)
    public User getInfo4( @PathVariable(name = "id") String idxx){
        System.out.println("=================");

        //throw new UserNotExistException(idxx);
        //System.out.println(idxx);
        System.out.println("进入getInfo服务");
        User u = new User();
        u.setUsername("tom");
        return u;
    }

运行测试

拦截器在运行的时候就已经初始化

访问 http://127.0.0.1:8080/user/1

控制台如下
在这里插入图片描述

第三方拦截器的使用

以前我们使用拦截器时只需要在web.xml里面定义好
在spring boot 中需要再拦截器上加@Component注解

那如何使用第三方注解呢(不能使用注解了)

  • 注释掉TimeFilter的@Component注解
    在这里插入图片描述
  • 创建配置类
    在这里插入图片描述
@Configuration
public class WebConfig implements Serializable {
    @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;

    }
}


  • 测试ok

拦截器 Interceptor(spring 框架本身提供)

自定义拦截器

在这里插入图片描述

@Component
public class TimeInterceptor implements HandlerInterceptor {

    @Override
    public  boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        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 startTime = (Long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗时:"+(new Date().getTime()-startTime));
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) throws Exception {
        System.out.println("afterCompletion");
        Long startTime = (Long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗时:"+(new Date().getTime()-startTime));
        System.out.println("ex is" +ex);
    }
}

配置拦截器

在这里插入图片描述

@SuppressWarnings("deprecation")
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private TimeInterceptor timeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }
}

测试1

 /**
     * @param idxx
     * @return
     */
    @GetMapping("{id:\\d++}")
    @JsonView(User.UserSimpleView.class)
    public User getInfo4( @PathVariable(name = "id") String idxx){
        System.out.println("=================");

        //throw new UserNotExistException(idxx);
        //System.out.println(idxx);
        System.out.println("进入getInfo服务");
        User u = new User();
        u.setUsername("tom");
        return u;
    }

访问 http://127.0.0.1:8080/user/1
在这里插入图片描述

测试2 服务抛出异常

    /**
     * @param idxx
     * @return
     */
    @GetMapping("{id:\\d++}")
    @JsonView(User.UserSimpleView.class)
    public User getInfo4( @PathVariable(name = "id") String idxx){
        System.out.println("=================");

        throw new UserNotExistException(idxx);
        //System.out.println(idxx);
        //System.out.println("进入getInfo服务");
        //User u = new User();
        //u.setUsername("tom");
        //return u;
    }

500错误

{"messsage":"user not exists ! ","id":"1"}

控制台
在这里插入图片描述
这次没有打印出postHandle,ex 仍然为空

这是因为异常UserNotExistException被 controller异常处理器吞掉了

在这里插入图片描述

测试三 服务抛出运行时异常

  /**
     * @param idxx
     * @return
     */
    @GetMapping("{id:\\d++}")
    @JsonView(User.UserSimpleView.class)
    public User getInfo4( @PathVariable(name = "id") String idxx){
        System.out.println("=================");

        //throw new UserNotExistException(idxx);
        throw  new RuntimeException("user is not exists");
        //System.out.println(idxx);
        //System.out.println("进入getInfo服务");
        //User u = new User();
        //u.setUsername("tom");
        //return u;
    }

在这里插入图片描述
在这里插入图片描述
拦截器会拦截所有控制器

切片 Aspect

拦截器不能拿到拦截方法参数中的值

如果需要知道拦截方法中的参数,就需要切片

aop介绍

在这里插入图片描述

加入aop依赖

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <!--<version>2.1.2.RELEASE</version>-->
        </dependency>

自定义切片

在这里插入图片描述

@Aspect
@Component
public class TimeAspect{

    //@Before() 相当于 拦截器的 preHandle
    //@After()
    //@AfterThrowing 抛出异常时调用

    //@Around()      切入点 覆盖了上面三种 我们一般用这个

    //第一个*  可以是任何返回值
    //第二个*  类中的任何一个方法
    //(..)    方法中的任意参数

    //参考aop表达式语法
    // https://docs.spring.io/spring/docs/4.3.22.RELEASE/spring-framework-reference/htmlsingle/#aop-pointcuts-examples
    @Around("execution(* com.whale.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;
    }
}

测试

 /**
     * @param idxx
     * @return
     */
    @GetMapping("{id:\\d++}")
    @JsonView(User.UserSimpleView.class)
    public User getInfo4( @PathVariable(name = "id") String idxx){
        System.out.println("=================");

        //throw new UserNotExistException(idxx);
        //throw  new RuntimeException("user is not exists");
        System.out.println(idxx);
        System.out.println("进入getInfo服务");
        User u = new User();
        u.setUsername("tom");
        return u;
    }

访问 http://127.0.0.1:8080/user/1
控制台如下

在这里插入图片描述

总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值