理解java注解四

通过前面的阅读,想必大家对注解都有了一个简单的理解,能够进行简单的应用了。下面我再给大家讲一种注解的使用。

其实,千变万化,注解还是那样子,就是通过反射获取注解,然后分析注解,从而实现逻辑的处理。

不知道大家有没有遇到过,一个controller类上加上了一个注解,然后所有的方法都会进行权限过滤或者身份验证什么的,我第一次碰到这种的时候,只有一个感觉---------厉害!

心里想的就是不愧是大神,随便搞搞就搞定一切!

其实现在回顾起来,也就是一个拦截加上注解的解析,实现了请求的过滤或者拦截,并没有什么特别高深的知识,还是那句话,会者不难,难者不会,真的深入进去,你就会发现,哦, 原来是这样!

下面我通过Spring中的拦截器处理,实现注解对方法的过滤。

新建一个拦截器。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface TestAnno {

    //多个或者多种过滤,也可以直接使用下面的单种
    String[] values() default {TestConstant.BOSS,TestConstant.STAFF};

//    String value();

}

这个注解很好理解,就是一个数组集合,定义权限为BOSS或者STAFF,为了方便起见,我创建了一个存储常量的接口

package com.example.demoproject.constant;

public interface TestConstant {

    String BOSS = "boss";

    String STAFF = "staff";

}

下面就是构造一个拦截器,当然我需要构造一个拦截器的bean。因为加载拦截器是在加载ApplicationContext之前,直接加@Service或者@Component是无法注入成功的。所以要创建一个配置,把拦截器加载到Spring容器中。

package com.example.demoproject.filter;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport  {

    @Bean
    public TestInterceptor testInterceptor(){
        return new TestInterceptor();
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry){
        // 拦截所以请求
        registry.addInterceptor(this.testInterceptor()).addPathPatterns("/**");
    }
}

这个配置类就是加载了一个TestInterceptor 的 Bean,然后把这个拦截器添加到拦截器集合中去。

接着就是实现这个拦截器了。我们先看下下Controller

package com.example.demoproject.controller;

import com.example.demoproject.annotion.TestAnno;
import com.example.demoproject.constant.TestConstant;
import com.example.demoproject.emun.TestEnum;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@TestAnno(values = TestConstant.BOSS)
public class TestController {

    @PostMapping("/test")
    @TestAnno(values = TestConstant.STAFF)
    public Map<String,String> get(){
       Map<String,String> map = new HashMap();
       map.put("response","success");

        return map;
    }
}

因为这个注解是可以加到方法和类上的,所以我都加了一个示范(@Target({ElementType.TYPE,ElementType.METHOD}))

好,接下来我们看下拦截器的实现:

package com.example.demoproject.filter;

import com.alibaba.fastjson.JSON;
import com.example.demoproject.annotion.TestAnno;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Method;


public class TestInterceptor implements HandlerInterceptor {

    // 在业务处理器处理请求之前被调用
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{

        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod)handler;

            Method method = handlerMethod.getMethod();
            System.out.println(method);
            Class<?> aClass = method.getDeclaringClass();

            TestAnno anno = aClass.getAnnotation(TestAnno.class);
            System.out.println("anno:"+ JSON.toJSONString(anno.values()));
            TestAnno anno1 = method.getAnnotation(TestAnno.class);
            System.out.println("anno1:"+ JSON.toJSONString(anno1.values()));
            System.out.println("--------------");
            String name = request.getParameter("name");
            System.out.println("name:"+name);
        }
//        System.out.println("输出request"+JSON.toJSON(request));
        return true;
    }
    // 在业务处理器处理请求完成之后,生成视图之前执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception{
    }
    // 在DispatcherServlet完全处理完请求之后被调用,可用于清理资源
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception{
    }

}

拦截器想必大家都有所了解,我就不多做介绍了,在这里主要处理的就是preHandle,在方法之前做处理。这个方法有一个返回值,boolean类型,返回true,继续向下走,返回false,直接被拦截。

从代码中可以看出,我们可以获取请求的方法,类,然后获取他们的注解,然后可以判断这个注解与预期是否一致,接着就是判断逻辑了(这一部分我没写,需要根据实际情况处理),如果校验不通过,返回false,校验通过的话就返回true。

这样的话,一个注解拦截请求或者过滤权限的结构就完成了,是不是不过如此?

感觉还行的话,就给个赞呗~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笔下天地宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值