Springboot使用java -jar启动后过Servlet过滤器失效的问题

@WebServlet@WebFilter@WebListener 使用问题

昨天发现一个问题。在Springboot ,使用 @WebFilter 配置过滤器时。发现jar包和war部署的效果不一样。

使用 war 包部署到 外部的Tomcat 容器, 我们配置的过滤器,会有效果。

但是使用 jar 包,使用 java -jar 命令部署,结果过滤器没有效果。

经过查阅,了解到:

@WebServlet@WebFilter@WebListener 是Servlet 3.0 出现的新规范。

当一个类由 @WebServlet@WebFilter@WebListener 声明时,会被容器能进行处理。

但是,在SpringBoot中,使用 @WebServlet@WebFilter@WebListener 注解时,

我们需要注意:

在 Springboot 内置的容器时,该类注解,需要通过@ServletComponentScan注释,才能被使用。

这是因为 Springboot 不直接执行Servlet 3.0+ javax.servlet.ServletContainerInitializer接口或Springorg.springframework.web.WebApplicationInitializer接口。为了降低第三方库对Spring Boot应用程序破坏的风险。

官方文档如下:

29.4.2 Servlet Context Initialization
Embedded servlet containers do not directly execute the Servlet 3.0+ javax.servlet.ServletContainerInitializer interface or Spring’s org.springframework.web.WebApplicationInitializer interface. This is an intentional design decision intended to reduce the risk that third party libraries designed to run inside a war may break Spring Boot applications.

If you need to perform servlet context initialization in a Spring Boot application, you should register a bean that implements the org.springframework.boot.web.servlet.ServletContextInitializer interface. The single onStartup method provides access to the ServletContext and, if necessary, can easily be used as an adapter to an existing WebApplicationInitializer.

Scanning for Servlets, Filters, and listeners
When using an embedded container, automatic registration of classes annotated with @WebServlet, @WebFilter, and @WebListener can be enabled by using @ServletComponentScan.

代码使用如下:以@WebFilter为例

@WebFilter(filterName="myFilter",urlPatterns="/*")
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("开始进行过滤处理");
        //调用该方法后,表示过滤器经过原来的url请求处理方法
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }
}

如果部署时,使用的是springboot 内置容器。需要使用@ServletComponentScan

@SpringBootApplication
@ServletComponentScan
public class DemoApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

如果使用外部容器时

@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    /**
     * 实现SpringBootServletInitializer可以让spring-boot项目在web容器中运行
     */
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(DemoApplication.class);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值