我看到使用Spring Boot真的很简单,创建过滤器。只需关注像这样的帖子https://www.baeldung.com/spring-boot-add-filter
我找不到的是如何创建将控制器中的特定端点订阅到一个过滤器的注释。
在Jax-RS中看起来像
@GET
@Path("jax-rs-single")
@Reactive(ttlRequest = 2000)
@Produces(MediaType.APPLICATION_JSON)
public Single getSingle() {
return Single.just("Hello world single");
}
@Reactive
会在每个请求触发ReactiveFilter实现。
我也看到了@WebFlow批注,但这不是我想要的。我想创建一个库,供消费者决定使用哪种过滤器,只需在控制器中添加注释即可。
有人知道如何使用Spring boot / MVC做类似的事情吗?
致谢
答案 0 :(得分:2)
我将在这里尝试描述有关自定义注释和Spring中的处理器的更多信息。
我不知道您想要什么,但我将举一个通用的例子。
您有2个选择:
您基本上需要构建3件事:Annotaton,BeanProcessor和Callback,如果有注释,则执行您的逻辑。这是一个示例及其工作方式:
1-创建注释
className
2-实现BeanPostProcessor
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Documented
public @interface Reactive {
Integer ttlRequest;
}
3-创建方法回调(这是要执行的逻辑)
@Component
public class ReactiveAnnotationProcessor implements BeanPostProcessor {
private ConfigurableListableBeanFactory configurableBeanFactory;
@Autowired
public ReactiveAnnotationProcessor(ConfigurableListableBeanFactory beanFactory) {
this.configurableBeanFactory = beanFactory;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
this.scanReactiveAnnotation(bean, beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
protected void scanReactiveAnnotation(Object bean, String beanName) {
this.configureMethodInjection(bean);
}
private void configureMethodInjection(Object bean) {
Class<?> managedBeanClass = bean.getClass();
MethodCallback methodCallback =
new ReactiveMethodCallback(configurableBeanFactory, bean);
ReflectionUtils.doWithMethod(managedBeanClass, methodCallback);
}
}
这里是有关注释处理的一个很好的资源,它与FieldProcessing有关,但是如果您有疑问,可以更改接口以实现所需的内容:https://www.baeldung.com/spring-annotation-bean-pre-processor
[更新],您也可以改为创建HandlerInterceptor:
public ReactiveMethodCallback implements MethodCallback {
private ConfigurableListableBeanFactory configurableBeanFactory;
private Object bean;
public ReactiveMethodCallback(ConfigurableListableBeanFactory bf, Object bean) {
configurableBeanFactory = bf;
this.bean = bean;
}
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
if (!method.isAnnotationPresent(Reactive.class)){
return;
}
//YOUR LOGIC HERE
}
}
并注册您的处理程序:
public class ReactiveFilterHandlerInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
// Test if the controller-method is annotated with @CustomFilter
Reactive filter = handlerMethod.getMethod().getAnnotation(Reactive.class);
if (filter != null) {
// ... do the filtering, or call the Component for filtering
}
}
return true;
}
}
答案 1 :(得分:0)
如果我正确理解了您想要的内容,则主要问题是如何基于自定义注释应用过滤器。
因此,首先,是的,您可以使用常规的Spring过滤器(对于Spring Webflux,使用WebFilter
;对于Spring MVC,则使用Filter
),但是您需要编写一些自定义逻辑
要基于注释进行过滤,您应该:
RequestMappingHandlerMapping#getHandlerInternal()
方法检索对处理请求的方法的引用(在您的情况下为getSingle()
)HandlerMethod
时,可以检查该方法是否将您的自定义注释与hasMethodAnnotation(Class<A> annotationType)
方法一起应用。chain.doFilter(request, response)
不执行任何操作,或者应用您的自定义逻辑,然后触发其余的过滤器链。