Spring项目迁移SpringBoot注意事项
-
@PathVariable不可用问题
- 在spring中使用@PathVariable使URL变为restful风格,前端使用post的表单提交,spring中使用正常
- 在SpringBoot v2.5.6版本同样代码执行时,只能使用get表单提交,否则就会报以下错误
org.springframework.web.HttpRequestMethodNotSupportedException: Request method ‘POST‘ not supported
,前端控制台则会输出Failed to load resource: the server responded with a status of 405 ()
- 在这个报错下,无论你SpringBoot中controller层的接口上是否标明
method = RequestMethod.POST
或者直接使用@PostMapping
注解都没办法解决问题- 解决:
- 使用ajax请求,而不用表单提交
- 使用get表单提交
- 解决:
- 在这个报错下,无论你SpringBoot中controller层的接口上是否标明
-
SpringMVCxml配置问题
- SpringBoot中推荐方式为开箱即用,自动配置.故应该采用0xml的方式配置SpringMVC,该方式下的配置存在多个配置类可以配置.在SpringBoot2.0以上版本,推荐使用实现WebMvcConfigurer配置类接口方式来实现
- https://blog.csdn.net/zhangpower1993/article/details/89016503
- 该链接为WebMvcConfigurer配置类接口内方法的说明,常用的用:
- addViewControllers:页面跳转,用于实现欢迎页和一下url隐藏功能
- addResourceHandlers:静态资源,实现静态资源访问权限功能
- configureViewResolvers:视图解析器,实现controller层中便捷的转发
- addCorsMappings:跨域,跨域问题配置
- addInterceptors:拦截器,实现见下方链接
- 该链接为WebMvcConfigurer配置类接口内方法的说明,常用的用:
- https://blog.csdn.net/zhangpower1993/article/details/89016503
- SpringBoot中推荐方式为开箱即用,自动配置.故应该采用0xml的方式配置SpringMVC,该方式下的配置存在多个配置类可以配置.在SpringBoot2.0以上版本,推荐使用实现WebMvcConfigurer配置类接口方式来实现
-
欢迎页问题
-
在spring项目中,因为web.xml的存在,只需要在xml中添加
<welcome-file>
标签指定主页即可 -
SpringBoot项目中因为没有web.xml,所以只能使用其他方法解决
-
SpringBoot默认能处理欢迎页请求,只需要将index.html,只需要将index.html文件防止SpringBoot默认支持的静态资源路径下即可.
-
注意:该方式在SpringBoot配置文件中配置了
spring:web:resources:static-locations:
(低版本SpringBoot为spring:resources:static-locations:
)静态资源访问前缀属性时,欢迎页支持不生效.SpringBoot底层代码如下WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) { if (welcomePage != null && "/**".equals(staticPathPattern)) { logger.info("Adding welcome page: " + welcomePage); setRootViewName("forward:index.html"); } else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) { logger.info("Adding welcome page template: index"); setRootViewName("index"); } }
- 但我的项目中该方法不生效,没有找到原因
-
-
mvc配置类配置
@Override public void addViewControllers(ViewControllerRegistry registry) { WebMvcConfigurer.super.addViewControllers(registry); registry.addViewController("/").setViewName("index"); }
- 代码示例中的setViewName()方法参数需要添加视图解析器
-
-
-
静态资源访问权限问题
-
SpringBoot项目快捷创建后,默认会创建templates文件夹用于存放HTML等页面文件,但是templates文件夹不是SpringBoot的默认支持的静态资源访问路径,因此需要添加/templates文件夹的静态资源访问权限
-
方法:
-
WebMvcConfigurer配置实现类中重写addResourceHandlers方法
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { WebMvcConfigurer.super.addResourceHandlers(registry); registry.addResourceHandler("/**") .addResourceLocations("classpath:/static/") .addResourceLocations("classpath:/templates/"); }
-
SpringBoot配置文件添加以下配置
spring: web: resources: static-locations: classpath:/templates/,classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ #SpringBoot低版本为spring:resources:static-locations: mvc: static-path-pattern: /**
- 但music项目没有生效,另一个demo项目生效了.搜索引擎获得的答案是WebMvcConfigurer配置实现类添加了拦截器的原因,两个项目也确实一个有拦截器一个没有,但有拦截器的项目也没有拦截页面.故不推荐该方案,直接使用1方案即可
-
-
-
web.xml迁移及其中Filter问题
-
迁移问题
- SpringBoot0xml配置,故web.xml也打多被SpringBoot启动器自动配置了,如全局监听器ContextLoaderListener和SpringMVC前端控制器DispatcherServlet都不需要我们单独配置,需要单独配置的只有web.xml中的欢迎页设置和filter配置
-
Filter问题
-
乱码过滤器
-
方法1:SpringBoot配置文件添加一下内容
spring: http: encoding: charset: utf-8 force: true enabled: true #以上三条配置高版本中已被废弃,被下面的server配置的三条替换了,但不冲突,都能写进配置内 server: servlet: encoding: charset: utf-8 force: true enabled: true tomcat: uri-encoding: UTF-8
-
添加配置类,配置类中自定义CharacterEncodingFilter
//字符集utf-8 @Bean public FilterRegistrationBean characterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setEncoding("UTF-8"); characterEncodingFilter.setForceEncoding(true); filterRegistrationBean.setFilter(characterEncodingFilter); filterRegistrationBean.addUrlPatterns("/*"); //filterRegistrationBean.addInitParameter("encoding", "UTF-8"); // filterRegistrationBean.addInitParameter("ForceEncoding", "true"); filterRegistrationBean.setOrder(1); filterRegistrationBean.setName("characterEncodingFilter"); return filterRegistrationBean; }
-
但该方式在SpringBoot项目启动时会打印以下信息提示
DynamicRegistrationBean.java:110 - Filter characterEncodingFilter was not registered (possibly already registered?)
- 原因可能是SpringBoot启动器自带的CharacterEncodingFilter已经注册过bean了,自定义的CharacterEncodingFilter不知道是否生效
-
-
-
SimplePageCachingFilter
-
虽然已经在SpringBoot配置文件中集成了ehcache,但其中的SimplePageCachingFilter并没有进行路径配置,因此需要通过配置类添加路径映射
-
步骤
-
配置EhCacheManagerFactoryBean依赖,并注入
@Bean public EhCacheManagerFactoryBean getEhCacheManagerFactoryBean(){ EhCacheManagerFactoryBean ehCacheManagerFactoryBean=new EhCacheManagerFactoryBean(); ehCacheManagerFactoryBean.setShared(true);//关键 return ehCacheManagerFactoryBean; }
-
如果不进行EhCacheManagerFactoryBean的Shared属性配置,启动SpringBoot时会报以下错误
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ehCacheCacheManager' defined in class path resource [org/springframework/boot/autoconfigure/cache/EhCacheCacheConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [net.sf.ehcache.CacheManager]: Factory method 'ehCacheCacheManager' threw exception; nested exception is net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
-
-
配置类中配置SimplePageCachingFilter
@Bean public FilterRegistrationBean pageCacheRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); SimplePageCachingFilter SimplePageCachingFilter = new SimplePageCachingFilter(); filterRegistrationBean.setFilter(SimplePageCachingFilter); filterRegistrationBean.addUrlPatterns("*.html"); filterRegistrationBean.addUrlPatterns("*.css"); filterRegistrationBean.addUrlPatterns("*.js"); filterRegistrationBean.addUrlPatterns("*.jpg"); filterRegistrationBean.addUrlPatterns("*.png"); filterRegistrationBean.addUrlPatterns("*.gif"); return filterRegistrationBean; }
-
-
-
-
-
事务配置见我的另一篇文章:https://www.cnblogs.com/jancy2265/p/15524504.html
-
@RequestBody
问题- 在spring项目中 , 直接使用alibaba的fastjson包内的JSONObject解析前端传递的Json , 如
@RequestBody JSONObject json
方式即可 . 但在SpringBoot中这个方法就不可行了 , 会报Content type 'application/json;charset=UTF-8' not supported
错误 .- 解决 : 将JSONObject对象换为String对象 , 在通过
JSONObject jsonObject=JSONObject.parseObject(json);
转换为JSONObject对象即可
- 解决 : 将JSONObject对象换为String对象 , 在通过
- 在spring项目中 , 直接使用alibaba的fastjson包内的JSONObject解析前端传递的Json , 如
-
其他细节
- mybatis占位符使用 :
#{}
内直接使用实体类中的属性的名称即可 , 不需要与数据库表的字段对应 - insert操作时最好列与字段一一对应 , 即sql语句中使用两个
()
, 保证不是满属性列插入时不报错
- mybatis占位符使用 :