一、自定义注解 定义
- 注解类定义的关键字为 @interface
- @Retention 定义注解的保留策略为 运行时RUNTIME,定义为运行时才能在拦截器、过滤器、切面中获取并处理业务逻辑。
- @Target 定义注解的使用对象为 METHOD类方法。这里还可以指定多个用逗号分隔。其他类型参考查看 java.lang.annotation.ElementType,例如TYPE[@RestController、@Controller]、PARAMETER[@PathVariable]
xml
package org.javatrip.customannotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 小溪
*/
@Retention(RetentionPolicy.RUNTIME) // 定义注解的保留策略,运行时
@Target({ElementType.METHOD}) // 定义注解的类型,在方法上、类上
public @interface PermissionAnnotation {
// 可以定义属性,这里定义了String类型的属性
String permissionName();
String permissionType();
String description() default "这里是描述";
}
二、应用示例场景
xml
package org.javatrip.customannotation;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AnnotationController {
@GetMapping("/list")
@PermissionAnnotation(permissionName = "userlist", permissionType = "get")
public String getmissionName() {
return "test";
}
}
1、过滤器中拦截校验
xml
package org.javatrip.customannotation;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.io.IOException;
import java.lang.reflect.Method;
@WebFilter(filterName = "MyFilter2", urlPatterns = "/*")
@Component
public class MyFilter2 implements Filter {
@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("2MyFilter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("MyFilter");
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
try {
HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(httpServletRequest);
if (handlerExecutionChain != null) {
Object handler = handlerExecutionChain.getHandler();
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
// 检查方法是否有MyCustomAnnotation注解
if (method.isAnnotationPresent(PermissionAnnotation.class)) {
PermissionAnnotation permissionAnnotation = method.getAnnotation(PermissionAnnotation.class);
// 获取注解的值
String name = permissionAnnotation.permissionName();
String type = permissionAnnotation.permissionType();
System.out.println("name="+name+" type="+type);
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
2、拦截器中校验注解
配置拦截器
xml
package org.javatrip.customannotation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.lang.reflect.Method;
public class PermissionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(handler instanceof HandlerMethod){
HandlerMethod handlerMethod = (HandlerMethod) handler;
if(handlerMethod.hasMethodAnnotation(PermissionAnnotation.class)){
PermissionAnnotation permissionAnnotation = handlerMethod.getMethodAnnotation(PermissionAnnotation.class);
String name = permissionAnnotation.permissionName();
String type = permissionAnnotation.permissionType();
System.out.println("name="+name+" type="+type);
}
}
return true;
}
}
注册拦截器
xml
package org.javatrip.customannotation;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new PermissionInterceptor()).addPathPatterns("/**");
}
}
3、AOP切面校验注解
三、总结
在web应用中根据方法注解进行权限校验,推荐使用 2拦截器、3AOP切面的方式。