美文网首页
最详细SSM+shiro项目转springboot项目教程

最详细SSM+shiro项目转springboot项目教程

作者: 赤色如潮 | 来源:发表于2019-01-14 20:29 被阅读0次

适用场景

这篇文章主要适用于传统ssm+shiro框架向springboot2.0项目转换,去除项目中原有的spring-*.xml 和各种.properties,也是踩了一些坑,记录下来进行分享。其中包括mybatis数据源配置,springmvc配置,以及webservice(soap)配置。


具体流程

ssm框架项目结构

图1

这里使用的项目管理工具是maven,IDE将由myeclipse转换成IDEA,如果有不同,请自行调整,大同小异。

新建项目

在IDEA中新建maven项目

图2

这里新建一个maven项目,也可以选择Spring Iniializer,具体没有什么影响

图3

新建好项目,项目结构如下

图4
图5

有大量关于新建项目的博客,这里不再赘述。

POM文件

父项目itom-all的pom.xml,这里使用的是springboot2.0.4。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <modules>
        <module>itom</module>
        <module>itom-common</module>
        <module>itom-dm</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.dimpt</groupId>
    <artifactId>itom-all</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>itom-all</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <quartz.version>2.3.0</quartz.version>
        <cxf.version>3.1.1</cxf.version>
        <maven.test.skip>true</maven.test.skip>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.dimpt</groupId>
                <artifactId>itom</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.dimpt</groupId>
                <artifactId>itom-all</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.dimpt</groupId>
                <artifactId>itom-common</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.dimpt</groupId>
                <artifactId>itom-dm</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
                <version>3.2.1</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.9</version>
            </dependency>
            <dependency>
                <groupId>com.mchange</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.5.2</version>
            </dependency>
            <!-- 热部署模块 -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-typehandlers-jsr310</artifactId>
                <version>1.0.0</version>
            </dependency>
            <!-- 2.数据库 -->
            <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <version>42.1.1</version>
            </dependency>
            <!-- DAO: MyBatis -->
            <!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-jasper</artifactId>
                <version>9.0.12</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>5.1.2</version>
            </dependency>

            <!-- 3.Servlet web -->
            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp.jstl</groupId>
                <artifactId>jstl-api</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.2</version>
                <scope>provided</scope>
            </dependency>
            <!-- 4.Spring -->           

            <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.16</version>
            </dependency>

            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.3</version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-api</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-api</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-access</artifactId>
                <version>1.2.3</version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-api</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
                <scope>provided</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/net.sf.ezmorph/ezmorph -->
            
            <!-- shiro -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>1.3.2</version>
            </dependency>
            <!--<dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-quartz</artifactId>
                <version>1.3.2</version>
            </dependency>
            -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-ehcache</artifactId>
                <version>1.3.2</version>
            </dependency>
            
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

子项目itom是web主体,itom-common和itom-dm为其他模块,不做描述。itom模块的pom.xml如下

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>itom-all</artifactId>
        <groupId>com.dimpt</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>itom</artifactId>
    <packaging>war</packaging>
    <name>itom</name>
    <version>0.0.1-SNAPSHOT</version>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.test.skip>true</maven.test.skip>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <!--打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。
                相当于compile,但是打包阶段做了exclude操作-->
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
        </dependency>
        <!-- 热部署模块 -->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- 2.数据库 -->
        <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
        </dependency>
        <!-- 日志-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
            <scope>provided</scope>
        </dependency>
        <!-- 3.Servlet web -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- 4.Swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>       
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/webapp</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>true</executable>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <configuration>
                            <classifier>exec</classifier>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>itom</finalName>
    </build>
</project>

这里为主要使用的依赖,根据项目具体添加,打包方式选择war包,也可以选择jar包,这里主要是页面中有jsp页面(后台一些管理页面,项目主要是对外提供api接口),加入了一些jsp相关的依赖,如使用其他模板可选择相应的依赖。日志模块使用的是logback,原先的logback.xml文件,也可以使用springboot application.property进行配置。

去除项目中spring-*.xml,和各种.properties文件

原来项目中各种.properties文件,眼花缭乱(功能以及开发人员不同导致),全部整合进application.properties中


图6
图7

application.properties

spring.profiles.active=dev

application-dev.properties

#打成war包,不起作用
server.port=8080
server.servlet.context-path=/itom
#druid c3p0任选一个使用
spring.datasource.druid.url=jdbc:postgresql://10.100.49.92:5432/itom?useUnicode=true&characterEncoding=utf8&stringtype=unspecified
spring.datasource.druid.driver-class-name=org.postgresql.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=root
spring.datasource.druid.initial-size=50
spring.datasource.druid.max-active=100
spring.datasource.druid.min-idle=20
spring.datasource.druid.max-wait=60000
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
#spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.filters=stat,wall,log4j
#mybatis.type-handlers-package=com.dimpt.watchtower.web.handler
c3p0.jdbcUrl=jdbc:postgresql://10.100.49.92:5432/itom?useUnicode=true&characterEncoding=utf8&stringtype=unspecified
c3p0.user=zt
c3p0.password=123
c3p0.driverClass=org.postgresql.Driver
c3p0.minPoolSize=3
c3p0.maxPoolSize=100
c3p0.maxIdleTime=1800000
c3p0.acquireIncrement=3
c3p0.maxStatements=1000
c3p0.initialPoolSize=3
c3p0.idleConnectionTestPeriod=60
c3p0.acquireRetryAttempts=30
c3p0.acquireRetryDelay=1000
c3p0.breakAfterAcquireFailure=false
c3p0.testConnectionOnCheckout=false

logging.level.root=INFO
logging.level.org.springframework=ERROR
logging.level.org.mybatis=ERROR

spring.jedis.host = 10.100.49.78
spring.jedis.port = 6379
zkHost=10.100.49.78:2181,10.100.49.79:2181,10.100.49.92:2181
solrHost=10.100.49.79
solrPort=8280
#redis property
currentAppStructName=\u77AD\u671B\u58541\u671F
currentCloudResourcePoolStructName=\u4E91\u8D44\u6E90\u6C601\u671F
currentMachineRoomStructName=\u673A\u623F1\u671F

items.error=错误
items.isNULL=字段不能为空

# itom/file/upload config
localDir=/home/tower/upload
tempDir=/home/tower/upload/temp

remoteHost=10.100.49.93
filesvr.username=tower
filesvr.password=tower
remoteDir=/home/tower/upload

# itom/app/upload config
uploadDir=/home/tower/upload
#kafka config
group.id=kafka-websocket
zookeeper.connect=10.100.8.6:2181
serializer.class=kafka.serializer.DefaultEncoder
key.serializer.class=kafka.serializer.StringEncoder
bootstrap.servers=10.100.8.6:9092
acks=1

数据库连接原先项目使用的c3p0连接池,如何选择看自己喜好,spring项目会自动加载application.properties文件作为启动文件,这里使用-dev,-dep,-prod用于多环境切换。
ssm中各种spring-*文件,都有其作用,这里分开进行拆解。


图8
  • spring-dao为数据库连接池配置,新建DataSourceConfig.java类


    图9
package com.dimpt.common.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * Created by x250-thinkpad on 2019/1/2.
 */
@Configuration
@MapperScan(basePackages = "com.dimpt.watchtower.web.dao",sqlSessionTemplateRef  = "adminSqlSessionTemplate")
public class DataSourceConfig {
    /*@Bean(name = "adminDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid")
    @Primary
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(DruidDataSource.class).build();
    }*/
    @Bean(name = "adminDataSource")
    @ConfigurationProperties(prefix = "c3p0")
    @Primary
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(ComboPooledDataSource.class).build();
    }

    @Bean(name = "adminSqlSessionFactory")
    @Primary
    public SqlSessionFactory adminSqlSessionFactory(@Qualifier("adminDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //分页插件
        //PageHelper pageHelper = new PageHelper();
        //PagePlugin pagePlugin = new PagePlugin();
//        Properties props = new Properties();
//        props.setProperty("reasonable", "true");
//        props.setProperty("supportMethodsArguments", "true");
//        props.setProperty("returnPageInfo", "check");
//        props.setProperty("params", "count=countSql");
//        pageHelper.setProperties(props);
        //添加插件
        //bean.setPlugins(new Interceptor[]{pagePlugin});
        // 添加mybatis配置文件
        bean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-config.xml"));
        // 添加mybatis映射文件
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "adminTransactionManager")
    @Primary
    public DataSourceTransactionManager adminTransactionManager(@Qualifier("adminDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "adminSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate adminSqlSessionTemplate(@Qualifier("adminSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

这里注释了druid连接池,可以选择使用,mybatis-config.xml中为mybatis相关配置以及分页插件,也可选择其他方式进而删除这个文件。

  • spring-web.xml,springmvc相关配置,新建WebAppConfig.java类
package com.dimpt.common.config;

import com.dimpt.watchtower.web.common.interceptor.AppVisitInterceptor;
import com.dimpt.watchtower.web.common.interceptor.UserLogsAndScoresInteceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * Created by x250-thinkpad on 2019/1/2.
 */
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
    @Bean
    public AppVisitInterceptor appVisitInterceptor(){
        return new AppVisitInterceptor();
    }
    @Bean
    public UserLogsAndScoresInteceptor userLogsAndScoresInteceptor(){
        return new UserLogsAndScoresInteceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(userLogsAndScoresInteceptor())
                .addPathPatterns("/**");
        registry.addInterceptor(appVisitInterceptor())
                .addPathPatterns("/app/{ztWtAppId}");
    }
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
        //super.addResourceHandlers(resourceHandlerRegistry);
        resourceHandlerRegistry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        resourceHandlerRegistry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        resourceHandlerRegistry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
    /**
     * 配置请求视图映射
     * @return
     */
    @Bean
    public InternalResourceViewResolver resourceViewResolver()
    {
        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        //请求视图文件的前缀地址
        internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
        //请求视图文件的后缀
        internalResourceViewResolver.setSuffix(".jsp");
        return internalResourceViewResolver;
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.viewResolver(resourceViewResolver());
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index").setViewName("/index");
        registry.addViewController("/admin").setViewName("/login");
    }

    @Bean
    public  ReloadableResourceBundleMessageSource messageSource(){
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasenames("ValidationMessages","org/hibernate/validator/ValidationMessages");
        messageSource.setUseCodeAsDefaultMessage(false);
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setCacheSeconds(60);
        return  messageSource;
    }
    @Override
    public Validator getValidator() {
        LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setProviderClass(org.hibernate.validator.HibernateValidator.class);
        localValidatorFactoryBean.setValidationMessageSource(messageSource());
        return localValidatorFactoryBean;
    }
    @Bean
    public CommonsMultipartResolver multipartResolver(){
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(209715200);
        multipartResolver.setDefaultEncoding("utf-8");
        return  multipartResolver;
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT")
                .maxAge(3600);
    }
}

spring2.0之后springmvc相关配置通过实现WebMvcConfigure.java 类,对静态文件等等进行配置,根据自己需要自行配置。

  • spring-redis.xml
package com.dimpt.common.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Created by x250-thinkpad on 2019/1/2.
 */
@Configuration
public class JedisConfig {
    @Value("${spring.jedis.host}")
    String host;
    @Bean
    @Primary
    public JedisPoolConfig jedisPoolConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(30);
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setNumTestsPerEvictionRun(1024);
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(30000);
        jedisPoolConfig.setMinEvictableIdleTimeMillis(1800000);
        jedisPoolConfig.setSoftMinEvictableIdleTimeMillis(10000);
        jedisPoolConfig.setMaxWaitMillis(1500);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestWhileIdle(true);
        jedisPoolConfig.setBlockWhenExhausted(false);
        return jedisPoolConfig;
    }
    @Bean
    @Primary
    public JedisPool jedisPool(JedisPoolConfig jedisPoolConfig){
        return  new JedisPool(jedisPoolConfig,host,6379,5000);
    }
}

  • spring-shiro.xml
package com.dimpt.common.config;

import com.dimpt.common.shiro.CustomShiroSessionDAO;
import com.dimpt.common.shiro.cache.JedisManager;
import com.dimpt.common.shiro.cache.JedisShiroSessionRepository;
import com.dimpt.common.shiro.cache.impl.JedisShiroCacheManager;
import com.dimpt.common.shiro.filter.*;
import com.dimpt.common.shiro.listenter.CustomSessionListener;
import com.dimpt.common.shiro.service.ShiroManager;
import com.dimpt.common.shiro.service.impl.ShiroManagerImpl;
import com.dimpt.common.shiro.session.CustomSessionManager;
import com.dimpt.common.shiro.token.SampleRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler;
import org.apache.shiro.session.mgt.SessionValidationScheduler;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by x250-thinkpad on 2019/1/2.
 */
@Configuration
public class ShiroConfiguration {
    //@Value("${spring.redis.host}")
    //private String host;

    //@Value("${spring.redis.port}")
    //private int port;
    @Autowired
    private JedisPool jedisPool;
    //@Value("${spring.redis.timeout}")
    //private int timeout;
    @Bean
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public SessionIdGenerator sessionIdGenerator() {
        return  new JavaUuidSessionIdGenerator();
    }
    @Bean(name="sessionIdCookie")
    public Cookie simpleCookie() {
        SimpleCookie simpleCookie = new SimpleCookie("itom");
        simpleCookie.setHttpOnly(true);
        simpleCookie.setMaxAge(-1);
        return simpleCookie;
    }
    @Bean
    public SessionListener customSessionListener(JedisShiroSessionRepository jedisShiroSessionRepository){
        CustomSessionListener customSessionListener = new CustomSessionListener();
        customSessionListener.setShiroSessionRepository(jedisShiroSessionRepository);
        return  customSessionListener;
    }
    @Bean
    public JedisShiroSessionRepository jedisShiroSessionRepository(JedisManager jedisManager){
        JedisShiroSessionRepository jedisShiroSessionRepository = new JedisShiroSessionRepository();
        jedisShiroSessionRepository.setJedisManager(jedisManager);
        KickoutSessionFilter.setShiroSessionRepository(jedisShiroSessionRepository);
        return  jedisShiroSessionRepository;
    }
    @Bean(name="rememberMeCookie")
    public SimpleCookie rememberMeCookie() {
        SimpleCookie rememberMeCookie = new SimpleCookie("itom-re");
        rememberMeCookie.setHttpOnly(true);
        rememberMeCookie.setMaxAge(2592000);
        return  rememberMeCookie;
    }
    @Bean(name="rememberMeManager")
    public CookieRememberMeManager rememberMeManager(SimpleCookie rememberMeCookie){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
        cookieRememberMeManager.setCookie(rememberMeCookie);
        return  cookieRememberMeManager;
    }
    @Bean
    public CustomShiroSessionDAO customShiroSessionDAO(JedisShiroSessionRepository jedisShiroSessionRepository,SessionIdGenerator sessionIdGenerator) {
        CustomShiroSessionDAO customShiroSessionDAO = new CustomShiroSessionDAO();
        customShiroSessionDAO.setShiroSessionRepository(jedisShiroSessionRepository);
        customShiroSessionDAO.setSessionIdGenerator(sessionIdGenerator);
        return  customShiroSessionDAO;
    }
    @Bean
    public CustomSessionManager customSessionManager(CustomShiroSessionDAO customShiroSessionDAO,JedisShiroSessionRepository jedisShiroSessionRepository){
        CustomSessionManager customSessionManager = new CustomSessionManager();
        customSessionManager.setCustomShiroSessionDAO(customShiroSessionDAO);
        customSessionManager.setShiroSessionRepository(jedisShiroSessionRepository);
        return customSessionManager;
    }
    @Bean
    public SessionValidationScheduler sessionValidationScheduler(DefaultWebSessionManager sessionManager){
        ExecutorServiceSessionValidationScheduler serviceSessionValidationScheduler = new ExecutorServiceSessionValidationScheduler();
        serviceSessionValidationScheduler.setInterval(18000000);
        serviceSessionValidationScheduler.setSessionManager(sessionManager);
        return serviceSessionValidationScheduler;
    }
    @Bean
    public ShiroManager shiroManager(){
        return  new ShiroManagerImpl();
    }
    @Bean(name="login")
    public AccessControlFilter loginFilter(){
        return  new LoginFilter();
    }
    @Bean(name="role")
    public AccessControlFilter roleFilter(){
        return  new RoleFilter();
    }
    @Bean(name="permission")
    public AccessControlFilter permissionFilter(){
        return  new PermissionFilter();
    }
    @Bean(name="simple")
    public AccessControlFilter simpleFilter(){
        return  new SimpleAuthFilter();
    }

    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,因为在
     * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
     * <p>
     * Filter Chain定义说明
     * 1、一个URL可以配置多个Filter,使用逗号分隔
     * 2、当设置多个过滤器时,全部验证通过,才视为通过
     * 3、部分过滤器可指定参数,如perms,roles
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        System.out.println("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/");
        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/noPermission");
        //拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        //配置过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/swagger-ui.html", "anon");
        //<!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->

        //filterChainDefinitionMap.put("/**", "user");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSessionManager sessionManager(CustomShiroSessionDAO customShiroSessionDAO, SessionListener customSessionListener,
                                                   Cookie sessionIdCookie) {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionValidationInterval(18000000);
        sessionManager.setGlobalSessionTimeout(18000000);
        sessionManager.setSessionDAO(customShiroSessionDAO);
        List<SessionListener> sessionListeners = new ArrayList<SessionListener>();
        sessionListeners.add(customSessionListener);
        sessionManager.setSessionListeners(sessionListeners);
        sessionManager.setSessionValidationScheduler(sessionValidationScheduler(sessionManager));
        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setDeleteInvalidSessions(true);
        sessionManager.setSessionIdCookie(sessionIdCookie);
//        sessionManager.setSessionDAO(redisSessionDAO());
        return sessionManager;
    }

    @Bean
    public SecurityManager securityManager(DefaultWebSessionManager sessionManager, Realm sampleRealm, CookieRememberMeManager rememberMeManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置realm.
        securityManager.setRealm(sampleRealm);
        // 自定义缓存实现 使用redis
        //securityManager.setCacheManager(cacheManager());
        // 自定义session管理 使用redis
        securityManager.setSessionManager(sessionManager);
        SecurityUtils.setSecurityManager(securityManager);
        securityManager.setRememberMeManager(rememberMeManager);
        return securityManager;
    }

    @Bean
    public SampleRealm sampleRealm(){
        SampleRealm sampleRealm = new SampleRealm();
//        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return sampleRealm;
    }
    /**
     * 配置shiro redisManager
     * 使用的是shiro-redis开源插件
     * @return
     */
    @Bean
    public JedisManager jedisManager() {
        JedisManager jedisManager = new JedisManager();
        jedisManager.setJedisPool(jedisPool);
        // redisManager.setPassword(password);
        return jedisManager;
    }
    @Bean
    public JedisShiroCacheManager jedisShiroCacheManager(JedisManager jedisManager){
        JedisShiroCacheManager jedisShiroCacheManager = new JedisShiroCacheManager();
        jedisShiroCacheManager.setJedisManager(jedisManager);
        return  jedisShiroCacheManager;
    }
    @Bean
    public KickoutSessionFilter kickoutSessionFilter(){
        KickoutSessionFilter kickoutSessionFilter =  new KickoutSessionFilter();
        kickoutSessionFilter.setKickoutUrl("login");
        return  kickoutSessionFilter;
    }
}

这里方法上的参数会自动注入,等同于@Autowired的作用,所以不需要进行指定名称
其他类似spring-*文件也按照这种方式进行初始化,这里就不一一列出。

  • webservice soap服务启动配置,这里使用的cxf
package com.dimpt.common.config;

import com.dimpt.webservices.emp.SBEIPEIPImportEmpInfoSrv;
import com.dimpt.webservices.org.SBEIPEIPImportOrgInfoSrv;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.xml.ws.Endpoint;
import java.util.Properties;


/**
 * Created by x250-thinkpad on 2019/1/7.
 */
@Configuration
public class WebserviceConfig {
    @Autowired
    private SBEIPEIPImportEmpInfoSrv sbEIPEIPImportEmpInfoSrvImpl;
    @Autowired
    private SBEIPEIPImportOrgInfoSrv sbEIPEIPImportOrgInfoSrvImpl;
    @Bean
    public ServletRegistrationBean cfxServlet(){
        return new ServletRegistrationBean(new CXFServlet(),"/services/*");//发布服务名称
    }
    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }
    @Bean
    public Endpoint SB_EIP_EIP_ImportOrgInfoSrv(){
        Properties props = System.getProperties();
        props.setProperty("org.apache.cxf.stax.allowInsecureParser", "1");
        props.setProperty("UseSunHttpHandler", "true");
        EndpointImpl endpoint = new EndpointImpl(springBus(),sbEIPEIPImportOrgInfoSrvImpl);
        endpoint.publish("SB_EIP_EIP_ImportOrgInfoSrv");
        //endpoint.setWsdlLocation("classpath:WEB-INF/wsdl/SB_EIP_EIP_ImportOrgInfoSrv/SB_EIP_EIP_ImportOrgInfoSrv.wsdl");
        return  endpoint;
    }
    @Bean
    public Endpoint SB_EIP_EIP_ImportEmpInfoSrv(){
        Properties props = System.getProperties();
        props.setProperty("org.apache.cxf.stax.allowInsecureParser", "1");
        props.setProperty("UseSunHttpHandler", "true");
        EndpointImpl endpoint = new EndpointImpl(springBus(),sbEIPEIPImportEmpInfoSrvImpl);
        endpoint.publish("SB_EIP_EIP_ImportEmpInfoSrv");
        //endpoint.setWsdlLocation("classpath:WEB-INF/wsdl/SB_EIP_EIP_ImportEmpInfoSrv/SB_EIP_EIP_ImportEmpInfoSrv.wsdl");
        return  endpoint;
    }
}

网上关于cxf创建soap服务的文章很多,这里不讲解具体实现,主要是配置,
Properties props = System.getProperties();
props.setProperty("org.apache.cxf.stax.allowInsecureParser", "1");
这句代码的含义是创建服务时先加载相应类,不然可能会出现ClassNotFound,这里也是借鉴网上经验。
*项目启动类

package com.dimpt;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication(scanBasePackages={"com.dimpt"})
@MapperScan("org.dimpt.watchtower.web.dao")
@EnableAspectJAutoProxy
@EnableTransactionManagement
@EnableScheduling
public class ItomApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
        return application.sources(ItomApplication.class);
    }
    public static void main(String[] args) {
        SpringApplication.run(ItomApplication.class, args);
    }

}

这里继承SpringBootServletInitializer ,是因为打包成war包启动的原因,如果不打包成war包可不继承该类。


总结

选择使用springboot重构项目原因是多方面的,不管是迭代速度,社区活跃度,还是对spring-cloud,springdata 等的支持,spingboot对模块化项目也很友好,学习成本相对低,对新人友好,等等。
花了差不多3天的时间,排了很多坑,pom.xml中有一些细节大家可以自行体会,分享出来也是给大家一个借鉴。

相关文章

网友评论

      本文标题:最详细SSM+shiro项目转springboot项目教程

      本文链接:https://www.haomeiwen.com/subject/qbvjdqtx.html