记一次spring的版本升级遇到的坑

826 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

1、背景

公司有个产品在客户现场定制化开发,客户看到我们产品用的还是老版本的spring,为了统一版本,立马提出要升级版本到spring5的诉求,领导安排我帮出个方案,下面是曲折的过程。

2、步骤

2.1、将spring当前版本相关jar包升级至5.0.2RELEASE版本

  • Spring-beans
  • Spring-context
  • Spring-jms
  • Spring-web
  • Spring-orm
  • Spring-jdbc
  • Spring-core
  • Spring-webmvc
  • Spring-expression

2.2、Spring完成升级之后启动服务发现

java.lang.NoClassDefFoundError: javax/validation/ParameterNameProvider异常,经排查需要升级hibernate-validator依赖。将hibernate-validator升级至当前最新的稳定版本hibernate-validator.6.2.0.Final

2.3、升级完成之后启动发现异常

提示spring-servlet.xml中配置项org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter已经过期,经查阅文档要改为org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter即可。

image.png

2.4、服务正常启动,但是调用接口出错

出现Input is required错误,跟踪错误信息发现之前使用的防止注入攻击的XssFilter会使用spring提供的htmlUtils来对request相关信息进行转义,而spring5对此工具类进行了改造升级。解决方法是不使用spring5提供的工具类,自己在XssHttpServletRequestWrapper.java中实现htmlEscape方法,同时需要增加HtmlCharacterEntityReferences.java类。

2.5、服务能正常启动,但是调用接口一律出现403问题

经跟踪调用路径,发现最终跳转至了404页面,但是当前access-control-tongyi.xml文件中并未对404页面进行放行,所以报了403没有权限的错误。将404页面加至放行列表中<mvc:exclude-mapping path="/404.html"/>

2.6、此时调用接口又出现404问题

分析springmvc调用流程,经调试源码,发现spring4和spring5的handlerMapping已不同,之前的RequestMappingHandlerMapping是第一个,优先级更高,而spring5的BeanNameUrlHandlerMapping是第一个,而RequestMappingHandlerMapping排在最后一个,此时接口请求已经匹配不到对应的方法,而是匹配到了配置了<mvc:resources location="/" mapping="/**" />的SimpleUrlHandlerMapping,即将/loginAdmin/getAppId 的接口请求当作了静态资源去处理,当然会找不到此资源,所以出现404问题。

Spring4:

image.png

Spring5:

image.png

解决方案是修改spring-servlet.xml中对静态资源放行的策略,去掉<mvc:resources location="/" mapping="/" />,增加按文件类型进行放行<mvc:resources location="/" mapping="/." />、<mvc:resources location="/admin/" mapping="/admin//." />、<mvc:resources location="/agent/" mapping="/agent//." />、<mvc:resources location="/manager/" mapping="/manager//." />

3、总结

这次升级过程还是比较曲折的,期间有些报错确实误导了我,比如途中出现的403和404错误,这些报错只是表现形式,其实真的的原因还是仔细思考探究。