java 某些控制器的 Spring mvc 过滤器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35622002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:22:14  来源:igfitidea点击:

Spring mvc filter for some controllers

javaspringspring-mvccontroller

提问by Tobia

I need to process all request coming to some Spring controllers to get some requester informartion or to throw exceptions like a security filter.

我需要处理来自某些 Spring 控制器的所有请求,以获取一些请求者信息或抛出异常(如安全过滤器)。

I would like if is there something buildin in Spring like a filter for controllers (I need it not for all controller, but only for someone). I don't want to apply this filter by url request but with a class/method extension or annotation.

我想在 Spring 中是否有一些内置的东西,比如控制器的过滤器(我不需要所有控制器,但只需要某个人)。我不想通过 url 请求应用这个过滤器,而是使用类/方法扩展或注释。

This is my actual solution:

这是我的实际解决方案:

@Controller
public class MyFilteredController extends FilterController {

    @RequestMapping("/filtered")
    public void test1(HttpServletRequest req){
        InfoBean infobean=filter(req);
        //... controller job
    }

}

A controller that extends a class with a filter method.

使用过滤器方法扩展类的控制器。

public abstract FilterController{
    protected InfoBean filter(HttpServletRequest req){
        //... filter job
        return infobean;
    }
}

回答by Ali Dehghani

I don't want to apply this filter by url request but with a class/method extension or annotation

我不想通过 url 请求应用这个过滤器,而是使用类/方法扩展或注释

You can register a HandlerInterceptorfor this purpose. For example, you can apply a filter to all handler methods that annotated with SomeAnnotationwith following code:

您可以HandlerInterceptor为此目的注册一个。例如,您可以将过滤器应用于SomeAnnotation使用以下代码注释的所有处理程序方法:

public class CustomHandlerIntercepter extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;

            SomeAnnotation annotation = handlerMethod.getMethodAnnotation(SomeAnnotation.class);
            if (annotation != null) {
                // do stuff
            }
        }
        return true;
    }
}

Also, you should register your interceptor in WebConfig:

此外,您应该在WebConfig以下位置注册您的拦截器:

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CustomHandlerIntercepter());
    }
}

You can read more about interceptors in spring reference documentation.

您可以在spring 参考文档中阅读有关拦截器的更多信息。

回答by Magnus

Take a look at SpringSandwich http://springsandwich.com/

看看 SpringSandwich http://springsandwich.com/

It lets you set filters (Spring Interceptors, actually) directly as controller annotations. Unlike normal servlet filters, you'll also have full access to your Spring context.

它允许您直接将过滤器(实际上是 Spring Interceptors)设置为控制器注释。与普通的 servlet 过滤器不同,您还可以完全访问 Spring 上下文。

Disclosure: I'm the author of this framework :)

披露:我是这个框架的作者:)

回答by Essex Boy

Everything in using the SpringDispatcherServlet is URL based, I don't think you can do it by controller.

使用 SpringDispatcherServlet 的所有内容都是基于 URL 的,我认为您不能通过控制器来完成。

You will need to use a Filter, looks at the API here https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/filter/package-summary.htmlyou will probable want to use a OncePerRequestFilter.

您将需要使用过滤器,在此处查看 API https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/filter/package-summary.html您可能需要使用OncePerRequestFilter。

public class MyFilter extends OncePerRequestFilter{

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // TODO Auto-generated method stub

    }

}

you will then need to add the filter in the web.xml

然后您需要在 web.xml 中添加过滤器

    <filter>
        <filter-name>requestFilter</filter-name>
        <filter-class>com.greg.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>errorHandlerFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Now the hacky bit, if you want to get Spring beans in here you can create a Bridge class with statics in it.

现在有点麻烦,如果你想在这里使用 Spring bean,你可以创建一个包含静态的 Bridge 类。

public class Bridge {

    private static PaymentService paymentService;

    public PaymentService getPaymentService() {
        return paymentService;
    }

    public void setPaymentService(PaymentService paymentService) {
        Bridge.paymentService = paymentService;
    }

}

If you want to inject some spring beans into this class

如果你想在这个类中注入一些 spring beans

<bean id="paymentService" class="net.isban.example.service.PaymentService" />

    <bean class="net.isban.example.util.Bridge">
        <property name="paymentService" ref="paymentService" />
    </bean>

Then in your filter (not spring class).

然后在您的过滤器中(不是 spring 类)。

PaymentService paymentService = new Bridge().getPaymentService();

Happy for someone to show me a less hacky way of doing this.

很高兴有人向我展示了一种不那么笨拙的方法。