SporingBoot项目JAR包部署转WAR包部署@WebFilter问题解决

问题出现背景

        最近项目上要求国产化,麒麟V10、达梦V8等等;其中一个要求就需要使用应用服务器TongWeb,不能使用SpringBoot内嵌的Tomcat;TongWeb是以war包进行部署管理的,那就基于现有的JAR部署改呗;

一、jar转war适配

1.修改pom.xml

将打包方式由jar改成war

<artifactId>com.idto.project</artifactId>
<artifactId>chinese</artifactId>
<packaging>war</packaging>

排除tomcat,引入servlet-api

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

新增一个maven插件用于打war包

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>

2.修改启动类

启动类集成SpringBootServletInitializer 重写configure方法

@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class})
@EnableScheduling
@EnableAsync
@EnableTransactionManagement
@EnableRetry
public class Application extends SpringBootServletInitializer {
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(Application .class);
  }
  public static void main(String[] args) {
    SpringApplication.run(Application .class, args);
  }
}

至此,项目jar部署转war部署改造完成,配置tomcat启动项目调试

二、@WebFilter问题

提前剧透:

@WebFilter使用外置tomcat无法通过@Resource从容器中获取bean,但使用内置tomcat则无此问题

 如果tomcat启动日志乱码,先修改tomcat编码方式:

打开配置文件apache-tomcat-8.5.81/conf/logging.properties
搜索关键字:.encoding = UTF-8
并替换成为:.encoding = GBK

tomcat启动项目调试时始终报错,关键信息如下:

错误关键信息1:

18-Jun-2022 15:26:30.818 严重 [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal 一个或多个筛选器启动失败。完整的详细信息将在相应的容器日志文件中找到
18-Jun-2022 15:26:30.818 严重 [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal 由于之前的错误,Context[/Chinese_server_war]启动失败

 错误关键信息2:

..........
18-Jun-2022 15:44:58.271 严重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.filterStart 启动过滤器异常
	javax.naming.NamingException: 无法创建资源实例
		at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:98)
		at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
		at org.apache.naming.NamingContext.lookup(NamingContext.java:846)
		at org.apache.naming.NamingContext.lookup(NamingContext.java:157)
		at org.apache.naming.NamingContext.lookup(NamingContext.java:834)
		at org.apache.naming.NamingContext.lookup(NamingContext.java:171)
		at org.apache.catalina.core.DefaultInstanceManager.lookupFieldResource(DefaultInstanceManager.java:576)
..........

根据关键信息2提示,在NamingManager.java 321行前面下断点进行debug

最后发现是因为安全模块CsrfFilter在启动时无法通过@Resource获取bean,原始代码如下:

@Slf4j
@Component
@WebFilter(filterName = "CsrfFilter", urlPatterns = "/*")
public class CsrfFilter implements Filter {

    // 病根所在
    @Resource
    private CsrfProperties csrfProperties;

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

估计问题是springboot启动时的先后顺序所致,那我们就手动从容器中去获取bean,修改代码如下:
 

@Slf4j
@Component
@WebFilter(filterName = "CsrfFilter", urlPatterns = "/*")
public class CsrfFilter implements Filter {

    private static CsrfProperties csrfProperties;


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 若csrfProperties为空,则手动去容器中获取bean
        if (Objects.isNull(csrfProperties)) {
            ServletContext context = filterConfig.getServletContext();
            ApplicationContext ctx =    WebApplicationContextUtils.getWebApplicationContext(context);
            csrfProperties = ctx.getBean(CsrfProperties.class);

        }

//******
    }

修改完成后debug,发现可以获取到csrfProperties的属性值,服务提供不报错了。

完美收官~~~


 总结:在适配过程有些问题问题,通过打印的日志不能直接定位到问题所在,所以可以通过关键位置debug,根据上下文进行分析判断解决。

 tips:网上也有其他解决方案,因为我这是已经功能代码,为了减少代码的改动,故手动获取bean的方式,以尽可能少的改动去解决问题,避免产生其他连带问题。

其他解决方案传送门:Springboot @WebFilter无法注入其他Bean_954L的博客-CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值