转换spring mvc 为 spring boot

原来的老项目基于spring mvc,使用jsp网页文件。当前为了方便开发和维护,需要转换为spring boot。中间遇到一些坑。在此整理出来,供大家参考。

1、修改pom.xml文件

        删除spring相关依赖jar,添加spring boot相关依赖jar。

			
				org.springframework.boot
				spring-boot-starter
				${spring-boot-version}
				
					
					
						org.springframework.boot
						spring-boot-starter-logging
					
				
			
            
			
				org.springframework.boot
				spring-boot-starter-security
				${spring-boot-version}
			
			
				org.springframework.boot
				spring-boot-starter-web
				${spring-boot-version}
				
                    
					
						org.springframework.boot
						spring-boot-starter-logging
					
				
			
			 
				org.springframework.boot
				spring-boot-starter-log4j2
				${spring-boot-version}
			
			
				org.springframework.boot
				spring-boot-starter-jdbc
				${spring-boot-version}
			
			
				org.springframework.boot
				spring-boot-starter-data-jpa
				${spring-boot-version}
			
			
				org.springframework.boot
				spring-boot-devtools
				${spring-boot-version}
				runtime
				true
			
			
				org.springframework.boot
				spring-boot-configuration-processor
				${spring-boot-version}
				true
			
			
			
				org.springframework.boot
				spring-boot-starter-test
				${spring-boot-version}
				test
			

这里特别要注意,引入spring-boot-starter及spring-boot-starter-web时,要排除spring-boot-starter-logging,否则会一直提醒:slf4j的两个实现log4j与logback冲突。spring boot 中默认内嵌的tomcat对jsp的支持不够理想。需要添加内嵌tomcat的增强jar包,

			
				org.springframework.boot
				spring-boot-starter-tomcat
				${spring-boot-version}
				provided
			
			
				org.apache.tomcat.embed
				tomcat-embed-jasper
				9.0.33
				provided
			

其实包spring-boot-starter-web中包含spring-boot-starter-tomcat,而spring-boot-starter-tomcat中又包含tomcat-embed-jasper,所以下面两个包可以不显示引用,而只在web项目中添加tomcat-embed-jasper即可,如下:

            
				org.apache.tomcat.embed
				tomcat-embed-jasper
				provided
			

spring boot默认动态网页是/resources目录下的template,而spring mvc动态网页默认路径是webapp/WEB-INF/views。在pom.xml中需要配置资源文件路径src/main/webapp,并通过spring-boot-maven-plugin插件打包:

    
		
            
			
				src/main/webapp
				META-INF/resources
				
					**/**
				
				false
			
		
        
			
				org.springframework.boot
				spring-boot-maven-plugin
				
					true
				
				
					
						
							repackage
						
					
				
			
			
				maven-surefire-plugin
				
					true
				
			
            
				org.apache.maven.plugins
				maven-war-plugin
				
					
					
						WEB-INF/classes/log4j2.xml,
						WEB-INF/classes/*.yml,
						WEB-INF/classes/META-INF/resources/**
					
				
			
			
				maven-resources-plugin
				3.1.0
				
					
						copy-resources
						validate
						
							copy-resources
						
						
                        
					${project.build.directory}/config
							
								
									src/main/resources
									true
									
										**/*.yml
										log4j2.xml
									
								
							
						
					
				
			
        
    

另外,对于此spring boot 项目,打包时只能打包成war包,不能打包成jar包,否则执行失败。

  war

此包的运行方式通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服务器。

你可能感兴趣的:(企业框架,系统开发,java,spring,boot,spring,java)