价值不言而喻,SSM项目升级springBoot复盘,又是一个极小的细节

简介: 价值不言而喻,SSM项目升级springBoot复盘,又是一个极小的细节

原来一直使用SSM 觉得也够用了,但是目前主流都是SpringBoot,于是计划着把自己的项目也来个升级,当中当然是各种坑不断。

花费两天时间,基础坑都趟了一遍。记录一下~

原项目:

SSM -> SpringBoot2.3 + Maven

jar包管理升级->Maven

旧项目依旧使用老的lib方式管理。但是为了利用Jenkins自动构建,简单升级为Maven导入本地jar的方式构建项目

1.Maven 导入本地lib(很多老项目升级时用的办法)lib置于${project.basedir}/src/main/webapp/WEB-INF/lib

<defaultGoal>compile</defaultGoal>
<plugins>
     <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.8.1</version>
         <configuration>
            <skip>true</skip>
            <source>8</source>
            <target>8</target>
            <encoding>UTF-8</encoding>
            <compilerArgs>
                <verbose />
                <!-- windows下使用分号(;)分隔,linux/mac下使用冒号(:)分隔 为了避免环境引起的问题,推荐使用${path.separator}-->
<!--                        <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar</bootclasspath>-->
<!--                        <etxdir>${project.basedir}/web/WEB-INF/lib</etxdir>-->
                <arg>-verbose</arg>
                <arg>-Xlint:unchecked</arg>
                <arg>-Xlint:deprecation</arg>
                <arg>-bootclasspath</arg>
                <arg>${java.home}/lib/rt.jar${path.separator}${java.home}/lib/jce.jar</arg>
                <arg>-extdirs</arg>
                <arg>${project.basedir}/src/main/webapp/WEB-INF/lib</arg>
            </compilerArgs>
        </configuration>
     </plugin>
<plugins>

2.jar包升级为Maven依赖(这是一个大工程~)

1)利用IDEA提示,前提需要知道应该要导入哪个包,有些可能就是没有。

39a173d1f6872c2262c9b226fd16f13.png

b448a23d914d3965f4bc4322c9d6fba.png

2)定位到类,然后去maven仓库自己搜索相关的包。

查看原来的项目,定位到具体jar,然后进行搜索

1.关于仓库无法搜索到jar的处理方案。

a.利用1当中的,建立lib文件夹,并引入。

b.利用maven中的scope为system的jar,进行本地引入。缺点如果是打成war包可能会有些问题

<dependency>
    <groupId>com.baidu.ueditor</groupId>
     <artifactId>ueditor</artifactId>
     <version>1.1.2</version>
     <scope>system</scope>
     <systemPath>${project.basedir}/lib/ueditor-1.1.2.jar</systemPath>
</dependency>

c.自己建立一个maven仓库。

SpringBoot

1.搭建脚手架

写博客居然遇上官网挂掉~

bcc74308783d1bd68a7433011de5995.png

官方提供的搭建工具非常棒,可以满足绝大部分需求。

https://start.spring.io/

按需填写,以及引入相关依赖,下载即可

7722da8e33a51b86a9f1ba8d11174a8.png

2.Mybatis迁移

迁移到springBoot只需要几个配置项即可

#配置扫描实体类
mybatis.type-aliases-package=com.ls.entity,com.ls.domain
#配置原来的配置文件
mybatis.config-location=classpath:sqlMapConfig.xml
#配置xml位置
mybatis.mapper-locations=classpath:mapper/*.xml
#数据库四要素
spring.datasource.url=xxx
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

配置文件主要是配置了plugin

<plugins>
        <!--分页过滤器-->
        <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
        <!--自定义sql过滤器-->
        <plugin interceptor="com.ls.interceptors.MybatisInterceptors"/>
</plugins>

如果顺便升级了mybatis的版本,可能会遇到以下问题:

StatementHandler 出现异常,原因是作者修改了参数,导致拦截器配置出现问题。

@Intercepts({
    // 之前 @Signature(method = "prepare", type = StatementHandler.class, args = {Connection.class})
        @Signature(method = "prepare", type = StatementHandler.class, args = {Connection.class,Integer.class})})

3.FreeMarker迁移

FreeMarker Only

抛弃原来的配置文件,都走向了参数化

## 是否允许HttpServletRequest属性覆盖(隐藏)控制器生成的同名模型属性。
#spring.freemarker.allow-request-override=true
## 是否允许HttpSession属性覆盖(隐藏)控制器生成的同名模型属性。
#spring.freemarker.allow-session-override=true
## 是否启用模板缓存。
#spring.freemarker.cache=false
## 模板编码。
#spring.freemarker.charset=UTF-8
## 是否检查模板位置是否存在。
#spring.freemarker.check-template-location=true
## Content-Type value.
#spring.freemarker.content-type=text/html
## 是否启用freemarker
#spring.freemarker.enabled=true
## 设定所有request的属性在merge到模板的时候,是否要都添加到model中.
#spring.freemarker.expose-request-attributes=true
## 是否在merge模板的时候,将HttpSession属性都添加到model中
#spring.freemarker.expose-session-attributes=true
## 设定是否以springMacroRequestContext的形式暴露RequestContext给Spring’s macro library使用
#spring.freemarker.expose-spring-macro-helpers=false
## 是否优先从文件系统加载template,以支持热加载,默认为true
#spring.freemarker.prefer-file-system-access=true
## 设定模板的后缀.
#spring.freemarker.suffix=.ftl
## 设定模板的加载路径,多个以逗号分隔,默认:
#spring.freemarker.template-loader-path=classpath:/templates/ftl/
## 设定FreeMarker keys.
#spring.freemarker.settings.template_update_delay=0
#spring.freemarker.settings.default_encoding=UTF-8
#spring.freemarker.settings.classic_compatible=true
#spring.freemarker.request-context-attribute=request

依赖:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

JSP Only

因为一些特殊原因、我需要引入JSP

如果不引入模板,只引入JSP可以这么配置

#配置jsp相关解析功能
spring.mvc.view.prefix =classpath:/templates/jsp/
spring.mvc.view.suffix =.jsp

这些依赖必不可少,否则无法解析jsp

<!--        jstl依赖      (jsp)  -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>
<!--        jasper依赖    (jsp)   -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>
<!--     -->
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>

JSP + FreeMarker

我需要同时解析JSP与FTL

依据官方提供的一种方案,此时我们不能再通过配置进行编写,而是需要通过编写对应类来注入。配置文件中的配置需要进行屏蔽。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
@Configuration
public class FreeMarkerAndJspConfiguration {
    @Bean
    public ViewResolver getJspViewResolver() {
        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
        internalResourceViewResolver.setSuffix(".jsp");
        internalResourceViewResolver.setOrder(2);
        return internalResourceViewResolver;
    }
    @Bean
    public FreeMarkerViewResolver getFreeMarkerViewResolver() {
        FreeMarkerViewResolver freeMarkerViewResolver = new FreeMarkerViewResolver();
        freeMarkerViewResolver.setCache(false);
        freeMarkerViewResolver.setSuffix(".ftl");
        freeMarkerViewResolver.setRequestContextAttribute("request");
        freeMarkerViewResolver.setOrder(1);
        freeMarkerViewResolver.setContentType("text/html;charset=UTF-8");
        freeMarkerViewResolver.setAllowRequestOverride(true);
        freeMarkerViewResolver.setAllowSessionOverride(true);
        freeMarkerViewResolver.setExposeRequestAttributes(true);
        freeMarkerViewResolver.setExposeSpringMacroHelpers(false);
        freeMarkerViewResolver.setRequestContextAttribute("request");
        freeMarkerViewResolver.setViewClass(org.springframework.web.servlet.view.freemarker.FreeMarkerView.class);
        return freeMarkerViewResolver;
    }
    @Bean
    public FreeMarkerConfigurer getFreeMarkerConfigurer(){
        FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
        freeMarkerConfigurer.setTemplateLoaderPath("classpath:/templates/ftl/");
        freeMarkerConfigurer.setDefaultEncoding("UTF-8");
        freeMarkerConfigurer.setPreferFileSystemAccess(true);
        return freeMarkerConfigurer;
    }
}

这里需要特别注意的一点,就是jsp存放位置

/src/main/resources/META-INF/resources/WEB-INF/jsp/controller.jsp

找了好半天问题,因为基本都说是在WEB-INF 绝大部分都说明是在webapp下,结果试了,还是不行。此处应该还是与springBoot版本有关。我目前直接使用的为2.3


3ce63ed03446cf945e1501a7b6ce2f3.png

4.外置Jetty 转 内置Tomcat

磁盘映射

其实主要就是涉及到原来磁盘静态文件的读取,俗称磁盘映射。

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //意思就是,前端浏览器访问路径带有/file/**就转到对应磁盘下读取图片,
        //类似前端访问tomcat webapp下file文件夹中文件
        //**注意/结尾 否则可能出现无法匹配
        registry.addResourceHandler("/resource/**").addResourceLocations("file:" + EnvConfig.getConfig(EnvConfig.PathConfig.RESOURCE_PATH) + File.separator);
    }
}

RealPath路径获取

其中jsp中包含下面一句

application.getRealPath("/")

如果经过测试,可以发现此路径是一个private开头,但是里面什么内容都没有的路径。说明并没有获取到项目真正的路径

此时需要我们在主项目根目录下,可以创建一个public文件夹,然后该代码就可以找到正确的绝对路径了。

可以参考:

SpringBoot 内置tomcat 的 request.getServletContext().getRealPath(“/”) 问题与tomat­-docbase 和 basedir的关系

5.其他问题

关于动态加载的静态参数问题

例如此静态属性:

//其具体值是通过java启动进过condition计算得出的
    public static final String DOCUMENT_HTML_BASE_PAHT = EnvConfig.getConfig(EnvConfig.PathConfig.BASE_PATH)+ File.separator+"document"+File.separator+"html";

关于springBoot devTool不同类加载器的问题

如果springBoot在加载应用代码的时候 使用

org.springframework.boot.devtools.restart.classloader.RestartClassLoader

类加载器,但是加载某些jar包的时候,又会使用

sun.misc.Launcher$AppClassLoader

可能某些代码会破坏单例性质,也可能像我遇到了一个静态属性类被初始化了2次,原因是我调用某个jar包,此jar包的类又被我重写调用了,然后就出现这个情况了。

此类问题解决办法:

1.关闭devTools

spring.devtools.restart.enabled=false

2.把这个jar包加入配置,让jar包中的类加载也通过RestartClassLoader加载

ffd6d06ddb384784942024f5a51ccf9.png

restart.include.companycommonlibs=/ueditor-[\\w-]+\\.jar
restart.include.projectcommon=/cxxz/core/

可以参考:

Springboot之devtools类加载问题研究

SpringBoot配置devtools实现热部署

写在最后

自己的项目也不是什么大项目,花费了2天时间,终于调整完毕,但是后续加入Jenkins集成,还有好多路要走。

产生这种改变的想法原因是在将项目部署到阿里云的时候,需要先布置jetty,配置映射。再上传war。感觉就一个小项目,却要四处配置。

而springBoot 的jar形式,则更像java宣传的,一次编译,到处跑。

当然这种约定优先,感觉还是需要先去熟悉他的默认配置,否则就是从一个坑进入另一个坑~

如果有天遇到一个问题,解决不了,试试官网文档,也许会有你想要的答案~

目录
相关文章
|
10天前
|
Java 容器
如何在SpringBoot项目中使用过滤器和拦截器
过滤器和拦截器是日常开发中常用技术,用于对特定请求进行增强处理,如插入自定义代码以实现特定功能。过滤器在请求到达 `servlet` 前执行,而拦截器在请求到达 `servlet` 后执行。`SpringBoot` 中的拦截器依赖于 `SpringBoot` 容器,过滤器则由 `servlet` 提供。通过实现 `Filter` 接口并重写 `doFilter()` 方法可实现过滤器;通过实现 `HandlerInterceptor` 接口并重写相应方法可实现拦截器。两者的主要区别在于执行时机的不同,需根据具体场景选择使用。
如何在SpringBoot项目中使用过滤器和拦截器
|
3天前
|
Java 关系型数据库 MySQL
创建一个SpringBoot项目,实现简单的CRUD功能和分页查询
【9月更文挑战第6天】该内容介绍如何使用 Spring Boot 实现具备 CRUD 功能及分页查询的项目。首先通过 Spring Initializr 创建项目并选择所需依赖;其次配置数据库连接,并创建实体类与数据访问层;接着构建服务层处理业务逻辑;最后创建控制器处理 HTTP 请求。分页查询可通过添加 URL 参数实现。
|
13天前
|
XML 前端开发 Java
还不会SpringBoot项目模块分层?来这手把手教你
本文详细介绍了如何为SpringBoot项目创建模块并进行合理的分层设计。通过逐步演示,从创建项目到构建各功能模块,再到具体代码实现,手把手教你实现整洁的代码分层。主要内容包括:创建依赖层、主启动层、模块层及其子模块(如共通层、控制器层、数据持久层等),并通过实例演示了从前端请求到后台服务调用的实际流程。适合SpringBoot初学者及有一定经验但需优化项目结构的开发者参考。
58 2
还不会SpringBoot项目模块分层?来这手把手教你
|
13天前
|
小程序 前端开发 Java
SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
JavaDog Chat v1.0.0 是一款基于 SpringBoot、MybatisPlus 和 uniapp 的简易聊天软件,兼容 H5、小程序和 APP,提供丰富的注释和简洁代码,适合初学者。主要功能包括登录注册、消息发送、好友管理及群组交流。
36 0
SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
|
22天前
|
JavaScript 前端开发 Java
SpringBoot + Vue 前端后分离项目精进版本
这篇文章详细介绍了一个基于SpringBoot + Vue的前后端分离项目的搭建过程,包括前端Vue项目的初始化、依赖安装、页面创建和路由配置,以及后端SpringBoot项目的依赖添加、配置文件修改、代码实现和跨域问题的解决,最后展示了项目运行效果。
SpringBoot + Vue 前端后分离项目精进版本
|
23天前
|
Java
SpringBoot项目配置热部署启动 及 热部署失效的问题解决
这篇文章介绍了如何在SpringBoot项目中配置热部署启动,包括在pom文件中添加热部署依赖、在IDEA中进行设置、修改配置文件以及IDEA启动设置,以解决热部署失效的问题。
SpringBoot项目配置热部署启动 及 热部署失效的问题解决
|
13天前
|
小程序 前端开发 JavaScript
【项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序
【避坑宝】是一款企业黑红名单吐槽小程序,旨在帮助打工人群体辨别企业优劣。该平台采用SpringBoot+MybatisPlus+uniapp+uview2等技术栈构建,具备丰富的注释与简洁的代码结构,非常适合实战练习与学习。通过小程序搜索“避坑宝”即可体验。
34 0
【项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序
|
13天前
|
JavaScript 前端开发 小程序
【项目实战】SpringBoot+vue+iview打造一个极简个人博客系统
这是一个基于 SpringBoot+MybatisPlus+Vue+Iview 技术栈构建的个人极简博客系统,适合初学者实战练习。项目包含文章分类、撰写文章、标签管理和用户管理等功能,代码简洁并配有详细注释,易于上手。此外,该项目也可作为毕业设计的基础进行二次开发。
53 0
【项目实战】SpringBoot+vue+iview打造一个极简个人博客系统
|
20天前
|
安全 Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+jsp实现的健身房管理系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术实现的健身房管理系统。随着健康生活观念的普及,健身房成为日常锻炼的重要场所,高效管理会员信息、课程安排等变得尤为重要。该系统旨在通过简洁的操作界面帮助管理者轻松处理日常运营挑战。技术栈包括:JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Shiro、Spring Boot 2.0等。系统功能覆盖登录、会员管理(如会员列表、充值管理)、教练管理、课程管理、器材管理、物品遗失管理、商品管理及信息统计等多方面。
|
18天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
在数字化时代背景下,本文详细介绍了如何使用Spring Boot框架结合Vue.js技术栈,实现一个前后端分离的考试管理系统。该系统旨在提升考试管理效率,优化用户体验,确保数据安全及可维护性。技术选型包括:Spring Boot 2.0、Vue.js 2.0、Node.js 12.14.0、MySQL 8.0、Element-UI等。系统功能涵盖登录注册、学员考试(包括查看试卷、答题、成绩查询等)、管理员功能(题库管理、试题管理、试卷管理、系统设置等)。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)