转换spring mvc 为 spring boot
原来的老项目基于spring mvc,使用jsp网页文件。当前为了方便开发和维护,需要转换为spring boot。中间遇到一些坑。在此整理出来,供大家参考。
原来的老项目基于spring mvc,使用jsp网页文件。当前为了方便开发和维护,需要转换为spring boot。中间遇到一些坑。在此整理出来,供大家参考。
1、修改pom.xml文件
删除spring相关依赖jar,添加spring boot相关依赖jar。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot-version}</version>
<exclusions>
<!-- 与log4j冲突,排除自带的logback依赖 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--引入spring security相关jar组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-version}</version>
<exclusions>
<!-- 与log4j冲突,排除自带的logback依赖 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <!-- 引入log4j2依赖 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot-version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring-boot-version}</version>
<optional>true</optional>
</dependency>
<!--junit test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot-version}</version>
<scope>test</scope>
</dependency>
这里特别要注意,引入spring-boot-starter及spring-boot-starter-web时,要排除spring-boot-starter-logging,否则会一直提醒:slf4j的两个实现log4j与logback冲突。spring boot 中默认内嵌的tomcat对jsp的支持不够理想。需要添加内嵌tomcat的增强jar包,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>${spring-boot-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>9.0.33</version>
<scope>provided</scope>
</dependency>
其实包spring-boot-starter-web中包含spring-boot-starter-tomcat,而spring-boot-starter-tomcat中又包含tomcat-embed-jasper,所以下面两个包可以不显示引用,而只在web项目中添加tomcat-embed-jasper即可,如下:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
spring boot默认动态网页是/resources目录下的template,而spring mvc动态网页默认路径是webapp/WEB-INF/views。在pom.xml中需要配置资源文件路径src/main/webapp,并通过spring-boot-maven-plugin插件打包:
<build>
<resources>
<!--resource用来编译包括的资源文件和排除的资源文件,但是仅限于class目录下的文件。在编译期和调试期都会执行,把directory中的文件移动到targetPath目录下 -->
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/**</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<!--排除掉war包指定文件(*:文件夹下所有文件;**:文件夹下所有文件,包含子文件夹的文件)-->
<packagingExcludes>
WEB-INF/classes/log4j2.xml,
WEB-INF/classes/*.yml,
WEB-INF/classes/META-INF/resources/**
</packagingExcludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<!--输出资源文件到war包外的文件夹,仅在编译期执行,调试期不执行-->
<outputDirectory>${project.build.directory}/config</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.yml</include>
<include>log4j2.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
另外,对于此spring boot 项目,打包时只能打包成war包,不能打包成jar包,否则执行失败。
<packaging>war</packaging>
此包的运行方式通jar包的运行方式,若配置文件在war包外,则指定文件,若在包内,则不用指定:
java -jar webapplication.war -Dspring.config.location=./config/application.yml
2、新增启动类WebApplication
新增启动类WebApplication,并添加main方法。
@SpringBootApplication(exclude= HibernateJpaAutoConfiguration.class)
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
3、添加配置文件application.yml
spring boot的配置文件默认名称为application.yml,放到resources目录下,内容如下:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://10.74.0.218/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
password: 123456
username: root
type: com.zaxxer.hikari.HikariDataSource
hikari:
connection-test-query: SELECT 1 FROM DUAL
minimum-idle: 1
maximum-pool-size: 5
jpa:
hibernate:
ddl-auto: none
properties:
hibernate:
show_sql: true
format_sql: false
dialect: org.hibernate.dialect.MySQL5Dialect
current_session_context_class: org.springframework.orm.hibernate5.SpringSessionContext
cache:
use_second_level_cache: true
use_query_cache: true
region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
javax.cache:
provider: org.ehcache.jsr107.EhcacheCachingProvider
uri: classpath:ehcache.xml
javax:
persistence:
sharedCache:
mode: ENABLE_SELECTIVE
mvc:
view:
suffix: .jsp
prefix: /WEB-INF/views/
main:
allow-bean-definition-overriding: true
web:
resources:
static-locations: classpath:/resources/,classpath:/static/,./config/
application:
name: test-web
servlet:
multipart:
enabled: true
max-file-size: 10MB
max-request-size: 10MB
logging:
config: classpath:log4j2.xml
# --- server
server:
port: 8090
4、新增配置类
WebSecurityConfig用户登录控制.
package com.test.web.config;
import com.test.web.security.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
private PasswordEncoder passwordEncoder;
private UserAuthenticationSuccessHandler userAuthenticationSuccessHandler;
private UserAuthenticationFailureHandler userAuthenticationFailureHandler;
public WebSecurityConfig(UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder,
UserAuthenticationSuccessHandler userAuthenticationSuccessHandler,
UserAuthenticationFailureHandler userAuthenticationFailureHandler){
this.userDetailsService = userDetailsService;
this.passwordEncoder = passwordEncoder;
this.userAuthenticationSuccessHandler = userAuthenticationSuccessHandler;
this.userAuthenticationFailureHandler = userAuthenticationFailureHandler;
}
@Override
public void configure(WebSecurity web) throws Exception {
//被忽略的路径是不经过权限认证的,也不能获取权限信息。
web.ignoring().antMatchers("/webjars/**","/resources/**","/getValidateCode","/login");
web.httpFirewall(httpFirewall());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
final String rememberMeKey = "cJAvjSVcKbsBOCfOmTLayw==";
//配置授权认证,允许匿名访问的路径配置要放在最前面,否则无效。
http.authorizeRequests()
.antMatchers("/loginCheck","/login")
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/**")
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/loginCheck")
.defaultSuccessUrl("/")
.successHandler(userAuthenticationSuccessHandler)
.failureHandler(userAuthenticationFailureHandler)
.permitAll()
.and()
.rememberMe().key(rememberMeKey)
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
public HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setUnsafeAllowAnyHttpMethod(true);
firewall.setAllowBackSlash(true);
firewall.setAllowUrlEncodedDoubleSlash(true);
return firewall;
}
}
HibernateConfig:Hibernate相关控制.
package com.test.web.config;
import org.hibernate.SessionFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.*;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.test.dao","com.test.service"})
public class HibernateConfig {
@Bean
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
@Bean
@ConfigurationProperties(prefix = "spring.jpa.properties")
public Properties properties(){
Properties properties = new Properties();
return properties;
}
@Bean
public LocalSessionFactoryBean sessionFactory(DataSource dataSource){
Properties properties = properties();
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setHibernateProperties(properties);
sessionFactoryBean.setPackagesToScan("com.test.model");
return sessionFactoryBean;
}
}
到此基本完成转换spring boot工作。
5、问题总结
生成的war包,可以直接通过java -jar test.war直接运行,在windows中运行,一切正常,但是若是在Linux中运行,就会发现,打开网页的速度特别慢,具体原因见:Springboot 第一次访问慢的问题研究&解决方案。我根据网上查询的解决办法都试过了(包括修改随机数生成器和替换servlet容器为jetty),但是成效并不明显。最后只能使用外部servlet容器,即使用外部的tomcat或jetty服务器。
更多推荐
所有评论(0)