基于SpringBoot+vue+gradle搭建框架(IDEA)

我们在软件开发的时候,为了快速开发必须搭建框架,搭建好开发就会更快,更迅速。接下来我们使用idea搭建框架。

开发工具:IDEA

开发环境:jdk1.8,gradle,springBoot,JPA,hibernate,element-ui 2.11.0等。

接下来开始搭建了。可以参考使用IDEA开发的SpringBoot项目(集成JPA并且能够自动生成javabean)

第一步:创建内容结构

结构如下:

                  图1:架构结构图

其中1是存储dao,entity。

其中2是存储service,controller.

其中3是存储页面。

第二步:准备相应的jdk应用包

                               图2:jar包

由于我们使用的是gradle,所以图2中4就是使用初始化的jar包。

apply plugin: 'java'

sourceSets {
    main {
        java {
            srcDirs = ['src/main/java']
        }
        resources {
            srcDirs = ['src/main/resources']
        }
    }
    test {
        java {
            srcDirs = ['src/test/java']
        }
        resources {
            srcDirs = ['src/test/resources']
        }
    }
}

compileJava {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

compileJava.options*.compilerArgs = [
        "-Xlint:unchecked", "-Xlint:options"
]

compileTestJava {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

compileTestJava.options*.compilerArgs = [
        "-Xlint:unchecked", "-Xlint:options"
]

[compileJava, compileTestJava, javadoc]*.options*.encoding = "UTF-8"

configurations {
    all { config ->
        config.exclude group: "org.apache.geronimo.specs"
        config.exclude group: "org.jboss.spec.javax.transaction"
        config.exclude group: "org.springframework.boot", module:"spring-boot-starter-logging"
        config.exclude group: "org.apache.tomcat", module:"tomcat-jdbc"
        config.exclude group: "com.vaadin.external.google"
        config.exclude group: "com.google.code.findbugs"
        resolutionStrategy.eachDependency { details ->
            println details.requested.group + ":" + details.requested.name + ":" + details.requested.version
            if (details.requested.group == 'org.ow2.asm' && details.requested.name == 'asm') {
                details.useVersion asm_version
            } else if (details.requested.group == 'org.codehaus.mojo' && details.requested.name == 'animal-sniffer-annotations') {
                details.useVersion animal_sniffer_annotations_version
            } else if (details.requested.group == 'org.aspectj') {
                details.useVersion aspectj_version
            } else if (details.requested.group == 'net.bytebuddy') {
                details.useVersion bytebuddy_version
            } else if (details.requested.group == 'org.checkerframework') {
                details.useVersion checker_version
            } else if (details.requested.group == 'com.fasterxml' && details.requested.name == 'classmate') {
                details.useVersion classmate_version
            } else if (details.requested.group == 'commons-codec' && details.requested.name == 'commons-codec') {
                details.useVersion commons_codec_version
            } else if (details.requested.group == 'commons-collections' && details.requested.name == 'commons-collections') {
                details.useVersion commons_collections_version
            } else if (details.requested.group == 'commons-lang' && details.requested.name == 'commons-lang') {
                details.useVersion commons_lang_version
            } else if (details.requested.group == 'org.apache.commons') {
                if(details.requested.name == 'commons-collections4') {
                    details.useVersion commons_collections4_version
                } else if(details.requested.name == 'commons-compress') {
                    details.useVersion commons_compress_version
                } else if(details.requested.name == 'commons-lang3') {
                    details.useVersion commons_lang3_version
                } else if (details.requested.name == 'commons-pool2') {
                    details.useVersion commons_pool2_version
                }
            } else if (details.requested.group == 'com.github.virtuald' && details.requested.name == 'curvesapi') {
                details.useVersion curvesapi_version
            } else if (details.requested.group == 'org.dom4j' && details.requested.name == 'dom4j') {
                details.useVersion dom4j2_version
            } else if (details.requested.group == 'com.alibaba' && details.requested.name.startsWith('druid')) {
                details.useVersion druid_version
            } else if (details.requested.group == 'com.google.errorprone') {
                details.useVersion errorprone_version
            } else if (details.requested.group == 'org.hibernate') {
                if(details.requested.name == 'hibernate-validator') {
                    details.useVersion hibernate_validator_version
                } else {
                    details.useVersion hibernate_version
                }
            } else if (details.requested.group == 'org.apache.httpcomponents') {
                if(details.requested.name == 'httpclient') {
                    details.useVersion httpclient_version
                } else if (details.requested.name == 'httpcore' || details.requested.name == 'httpcore-nio') {
                    details.useVersion httpcore_version
                }
            } else if (details.requested.group == 'com.ibm.icu') {
                details.useVersion icu_version
            } else if (details.requested.group.startsWith('com.fasterxml.jackson')) {
                details.useVersion jackson_version
            } else if (details.requested.group == 'org.javassist') {
                details.useVersion javassist_version
            } else if (details.requested.group == 'org.jboss' && details.requested.name == 'jandex') {
                details.useVersion jboss_jandex_version
            } else if (details.requested.group == 'org.jboss.logging') {
                details.useVersion jboss_logging_version
            } else if (details.requested.group == 'org.jdom' && details.requested.name == 'jdom2') {
                details.useVersion jdom2_version
            } else if (details.requested.group == 'com.google.j2objc') {
                details.useVersion j2objc_version
            } else if (details.requested.group == 'org.apache.logging.log4j') {
                details.useVersion log4j2_version
            } else if (details.requested.group == 'com.google.code.gson') {
                details.useVersion gson_version
            } else if (details.requested.group == 'com.google.guava') {
                details.useVersion guava_version
            } else if (details.requested.group == 'org.mapstruct') {
                details.useVersion mapstruct_version
            } else if (details.requested.group == 'org.slf4j') {
                details.useVersion slf4j_version
            } else if (details.requested.group == "org.yaml" && details.requested.name == "snakeyaml") {
                details.useVersion snakeyaml_version
            } else if (details.requested.group == 'org.springframework') {
                details.useVersion spring_version
            } else if (details.requested.group == 'org.springframework.boot') {
                details.useVersion spring_boot_version
            } else if (details.requested.group == 'org.springframework.data') {
                if(details.requested.name == 'spring-data-commons') {
                    details.useVersion spring_data_commons_version
                } else if (details.requested.name == 'spring-data-jpa') {
                    details.useVersion spring_data_jpa_version
                } else if (details.requested.name == 'spring-data-redis') {
                    details.useVersion spring_data_redis_version
                }
            } else if (details.requested.group == 'org.springframework.session') {
                details.useVersion spring_session_version
            } else if (details.requested.group == "io.swagger") {
                details.useVersion swagger_version
            } else if (details.requested.group == 'com.geewit.core') {
                if(details.requested.name == 'gw-core-utils') {
                    details.useVersion gw_core_utils_version
                } else if (details.requested.name == 'gw-core-okhttp') {
                    details.useVersion gw_core_okhttp_version
                } else if (details.requested.name == 'gw-core-jackson') {
                    details.useVersion gw_core_jackson_version
                }
            }
        }
    }
}

然后图2中5是dao层中使用的jar包。

project(':dao') {
       //初始化的jar包
    apply from: "${rootDir}/gradle/java.gradle"

    dependencies {
        compileOnly("org.springframework.boot:spring-boot-starter:$spring_boot_version")
        compileOnly("org.springframework.boot:spring-boot-starter-data-jpa:$spring_boot_version")
        compileOnly("org.springframework.boot:spring-boot-starter-log4j2:$spring_boot_version")
        compile("org.apache.commons:commons-collections4:$commons_collections4_version")
        compile("org.apache.commons:commons-lang3:$commons_lang3_version")

        compile group: 'org.apache.directory.studio', name: 'org.apache.commons.io', version: '2.4'
        runtime("com.alibaba:druid:1.1.9")
        compile("com.alibaba:druid-spring-boot-starter:1.1.9")
        compile("com.alibaba:fastjson:1.2.36")
        compile("commons-codec:commons-codec:1.11")
        compile("commons-io:commons-io:2.6")
        compile("com.squareup.okhttp3:okhttp:3.10.0")
        compile("org.springframework.boot:spring-boot-starter-jersey:$spring_boot_version")
        compile("org.apache.poi:poi:$poi_version")
        compile("org.apache.poi:poi-ooxml:$poi_version")
        compile("com.squareup.okhttp3:okhttp:$okhttp_version")
        compile group: 'org.apache.directory.studio', name: 'org.apache.commons.io', version: '2.4'

        compile("org.hibernate:hibernate-envers:$hibernate_version")
        compile("org.hibernate:hibernate-core:$hibernate_version")
        compile("org.hibernate:hibernate-ehcache:$hibernate_version")
        compileOnly("io.springfox:springfox-swagger2:$springfox_version")
        compileOnly("io.springfox:springfox-swagger-ui:$springfox_version")
      /*  compile("us.codecraft:webmagic-extension:0.7.3")
        compile("us.codecraft:webmagic-core:0.7.3")*/
    }
    sourceSets {
        main {
            java {
                srcDirs = ['src/main/java']
            }
            resources {
                srcDirs = ['src/main/resources']
            }
        }
    }
}

图2中3是service层和controller层中的jar包。

buildscript{
    repositories {
        mavenLocal()
        //mavenCentral()
        //jcenter()
        maven { url "http://repo1.maven.org/maven2" }
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.13.RELEASE")
    }
}
project(':server'){
    apply plugin: 'org.springframework.boot'

    apply from: "${rootDir}/gradle/java.gradle"

    dependencies {
        compile(project(":dao"))
        runtime("com.alibaba:druid:1.1.9")
        compile("com.alibaba:druid-spring-boot-starter:1.1.9")
        compile("com.alibaba:fastjson:1.2.36")
        compile("commons-codec:commons-codec:1.11")
        compile("org.apache.commons:commons-collections4:4.1")
        compile("commons-io:commons-io:2.6")
        compile("org.apache.commons:commons-lang3:3.7")
        compile("com.google.guava:guava:23.6-jre")
        compile("com.squareup.okhttp3:okhttp:3.10.0")
        compile('org.springframework.boot:spring-boot-starter')
        compile('org.springframework.boot:spring-boot-starter-cache')
        compile('org.springframework.boot:spring-boot-starter-data-jpa')
        compile('org.springframework.boot:spring-boot-starter-data-redis')
        compile('org.springframework.boot:spring-boot-starter-log4j2')
        compile('org.springframework.boot:spring-boot-starter-web')
        compile('org.springframework.boot:spring-boot-starter-validation')
        compile('org.springframework.boot:spring-boot-starter-mail:1.5.13.RELEASE')
        compile("io.springfox:springfox-swagger2:2.9.2")
        compile("io.springfox:springfox-swagger-ui:2.9.2")
        compile("org.hibernate:hibernate-envers:5.2.17.Final")
        compile("org.hibernate:hibernate-core:5.2.17.Final")
        //compile("org.hibernate:hibernate-core:4.1.2.Final")
        compile("org.hibernate:hibernate-ehcache:5.2.17.Final")
        compile("org.antlr:antlr4:4.7.1")
        runtime("mysql:mysql-connector-java")
        //用于生成验证码
        compile("com.github.penggle:kaptcha:2.3.2")
        //下面两个POI和pdfbox的jar包,是进行excel导入导出操作
        compile("org.apache.poi:poi:$poi_version")
        compile("org.apache.poi:poi-ooxml:$poi_version")
        compile("org.apache.pdfbox:pdfbox:$pdfbox_version")
        compile("org.apache.pdfbox:pdfbox-tools:$pdfbox_version")
        compile group: 'org.apache.velocity', name: 'velocity', version: '1.7'
        compile group: 'commons-configuration', name: 'commons-configuration', version: '1.10'
        //该jar包是使用jwt来生辰token
        compile group: 'com.auth0', name: 'java-jwt', version: '3.3.0'
        compile group: 'org.apache.commons', name: 'commons-text', version: '1.8'
        //該jar包是处理根据ip查询物理地址
        compile group: 'org.lionsoul', name: 'ip2region', version: '1.7.2'

    }


    jar {
        destinationDir = file("${rootProject.buildDir}")
        archiveName = "${rootProject.name}.jar"
        if(file("${rootDir}/ui/dist").exists()) {
            from("${rootDir}/ui/dist") {
                into 'META-INF/resources'
            }
        }
    }


    bootRun.systemProperty 'spring.profiles.active', 'development'

    springBoot {
        backupSource = false
        executable = false
    }
}

图2中2整个系统启动时候使用的jar包

allprojects{
    group 'com.zhm'
    version '1.0'
    buildDir='target'
}
apply plugin: "idea"

subprojects{
    configurations{
        repositories{
            maven { url "http://repo1.maven.org/maven2" }
            maven { url "https://plugins.gradle.org/m2/" }
        }
    }
    idea{
        module{
            excludeDirs=[file(".gradle")]
            excludeDirs+=file("gradle")
            excludeDirs+=file(".idea")
        }
    }
}
task run{
    doFirst{
        println 'run start'
    }
    doLast{
        println 'run last'
    }
}
run.dependsOn(':ui:runDev')
run.dependsOn(':server:bootRun')

task build{
    doFirst{
        println 'build start'
    }
    doLast{
        println 'build last'
    }
}
build.dependsOn(':server:bootRepackage')



图2中1是使用jar包的版本


version=1.0.0
systemProp.file.encoding=UTF-8
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
#quiet, warn, lifecycle, info, or debug
org.gradle.logging.level = info
org.gradle.jvmargs=-Xms512M -Xmx512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

gradle_node_version = 1.2.0

animal_sniffer_annotations_version = 1.16
antlr4_version = 4.7.1
asm_version = 6.1.1
aspectj_version = 1.9.1

bytebuddy_version = 1.8.11
checker_version = 2.5.1
classmate_version = 1.4.0
curvesapi_version = 1.06

commons_codec_version = 1.11
commons_collections_version = 3.2.2
commons_collections4_version = 4.1
commons_compress_version = 1.16.1
commons_lang_version = 2.6
commons_lang3_version = 3.7
commons_pool2_version = 2.5.0
commons_io_version = 2.6

dom4j2_version = 2.1.0
druid_version = 1.1.9

ehcache_version = 2.10.5

errorprone_version = 2.3.1

glassfish_javax_json_version = 1.1.2
guava_version = 25.0-jre

hibernate_version = 5.2.17.Final
hibernate_validator_version = 5.4.2.Final

hk2_version = 2.5.0-b61

httpclient_version = 4.5.5
httpcore_version = 4.4.9

icu_version = 61.1
javax_ws_rs_api_version=2.1
jackson_version = 2.9.5
javassist_version = 3.22.0-GA
javax_servlet_api_version = 3.1.0
jboss_jandex_version = 2.0.5.Final
jboss_logging_version = 3.3.2.Final
jboss_threads_version = 2.3.2.Final
jboss_xnio_version = 3.6.3.Final
jdom2_version = 2.0.6
jersey_version = 2.27
junit_version = 4.12
j2objc_version = 1.3

log4j2_version = 2.11.0
mapstruct_version = 1.2.0.Final
mysql_version = 5.1.46

okhttp_version = 3.10.0
okio_version = 1.14.1

slf4j_version = 1.7.25
snakeyaml_version = 1.21

spring_version = 4.3.17.RELEASE
spring_boot_version = 1.5.13.RELEASE
spring_data_commons_version = 1.13.12.RELEASE
spring_data_jpa_version = 1.11.12.RELEASE
spring_data_redis_version = 1.8.12.RELEASE
spring_session_version = 1.3.3.RELEASE
springfox_version = 2.9.2
swagger_version = 1.5.19
fastjson_version = 1.2.47
commons_fileupload_version = 1.3.3
pdfbox_version = 2.0.8
gw_core_jackson_version = 1.0.9
gw_core_okhttp_version = 1.1.0
gw_core_utils_version = 1.0.33
essential_jpa_version = 1.3.10
spring_boot_oss_version = 2.4.0
spring_data_envers_version = 1.1.20
spring_boot_starter_authority_version = 1.3.12
spring_boot_starter_aliyun_oss_version = 1.3.17
spring_boot_http_version=4.5.3
spring_boot_starter_jdbc_version = 1.0.4
spring_boot_starter_jpa_version = 1.3.24
spring_boot_starter_nashorn_version = 1.0.5
spring_boot_starter_stringtemplate_version = 1.0.6

module_actionlog_version = 1.0.0
module_attachment_version = 1.0.3

undertow_version = 2.0.7.Final

unbescape_version = 1.1.6.RELEASE
wildfly_common_version = 1.4.0.Final
poi_version = 3.17

joda_time_version = 2.9.9

如上面,这样jar包就准备好了。

第三步:准备相应的配置

其中config是配置文件,包括接口配置,定时任务,Redis配置,参数配置,验证码配置。

KaptchaConfig是验证码的配置,这个需要相应的kaptcha的jar包。

  compile("com.github.penggle:kaptcha:2.3.2") 

KaptchaConfig.java



import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.Properties;

/**
 * 验证码
 */
@Component
public class KaptchaConfig {
    @Bean
    public DefaultKaptcha getDefaultKaptcha(){
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "yes");
        properties.setProperty("kaptcha.border.color", "105,179,90");
        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        properties.setProperty("kaptcha.image.width", "110");
        properties.setProperty("kaptcha.image.height", "40");
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        properties.setProperty("kaptcha.session.key", "code");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);

        return defaultKaptcha;
    }
}

MvcConfig是配置,如图片地址参数,分页设置等


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.data.web.SortHandlerMethodArgumentResolver;
import org.springframework.web.filter.CommonsRequestLoggingFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

/**
 * Created by 赵红明 on 2019/6/14.
 */
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    private static Logger logger= LoggerFactory.getLogger(MvcConfig.class);
    @Autowired
    private Environment environment;

    /**
     * 分页设置
     * @param argumentResolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        SortHandlerMethodArgumentResolver sortArgumentResolver = new SortHandlerMethodArgumentResolver();
        sortArgumentResolver.setPropertyDelimiter(",");
        argumentResolvers.add(sortArgumentResolver);
        PageableHandlerMethodArgumentResolver pageableArgumentResolver = new PageableHandlerMethodArgumentResolver(sortArgumentResolver);
        pageableArgumentResolver.setPageParameterName("page");
        pageableArgumentResolver.setSizeParameterName("size");
        pageableArgumentResolver.setOneIndexedParameters(true);
        argumentResolvers.add(pageableArgumentResolver);
        super.addArgumentResolvers(argumentResolvers);
    }

    /**
     *图片等地址映射
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        logger.info("pdfURL="+environment.getProperty("service.addrss"));
        registry.addResourceHandler("/pdf/**").addResourceLocations("file:"+environment.getProperty("service.addrss"));
        super.addResourceHandlers(registry);
    }

    @Bean
    public CommonsRequestLoggingFilter requestLoggingFilter() {
        CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
        loggingFilter.setMaxPayloadLength(2048);
        loggingFilter.setIncludeClientInfo(true);
        loggingFilter.setIncludeQueryString(true);
        loggingFilter.setIncludePayload(true);
        loggingFilter.setIncludeHeaders(true);
        return loggingFilter;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

RedisConfig是Redis的配置

package com.zhm.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;

/**
 * @author huangfang
 * @since 2017-04-07
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    private final static Logger logger = LoggerFactory.getLogger(RedisConfig.class);

    private static String generate(Object target, Method method, Object... params) {
        StringBuilder sb = new StringBuilder();
        sb.append(target.getClass().getSimpleName());
        sb.append('.');
        sb.append(method.getName());
        for (Object param : params) {
            sb.append('.');
            sb.append(param.toString());
        }
        return sb.toString();
    }


    @Bean
    public KeyGenerator wiselyKeyGenerator(){
        return RedisConfig::generate;
    }

    @Bean
    public CacheManager cacheManager(@Qualifier("redisTemplate") RedisTemplate<String, Object> redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        //cacheManager.setDefaultExpiration(3000);
        return cacheManager;
    }

    /**
     * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类
     * @param factory
     * @return
     */
    @Bean("redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory, ObjectMapper existsObjectMapper) {

        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = existsObjectMapper.copy();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();

        return redisTemplate;

    }
}
ScheduledConfig是定时任务的配置
package com.zhm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Created by 赵红明 on 2019/5/30.
 * 配置定时任务,如果不配置,设置的定时任务就没法启动
 */
@Configuration
@EnableScheduling
public class ScheduledConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    /**ScheduleTimer
     * 设置定时任务的线程(四种线程池)
     * @return
     */
    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
        //1:固定大小线程池: 设置固定值会造成高并发线程排队等待空闲线程,尤其是当读取大数据量时线程处理时间长而不释放线程,导致无法创建新线程。
        //Executors.newFixedThreadPool(10);
        //2:可缓存线程池 线程池无限大,而系统资源(内存等)有限,会导致机器内存溢出OOM。
        //Executors.newCachedThreadPool();
        //3:定长且可定时、周期线程池
        //Executors.newScheduledThreadPool(5);
        //4:单线程线程池
        //Executors.newSingledThreadPool();
        return Executors.newScheduledThreadPool(5);

    }
}
Swagger2Config是swagger-ui的配置
package com.zhm.config;

import com.google.common.base.Predicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * 查看接口Swagger-ui设置
 * Created by 赵红明 on 2019/5/27.
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Autowired
    private Environment environment;

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(selector())
                .paths(PathSelectors.any())
                .build();
    }

    private Predicate<RequestHandler> selector() {
//        return RequestHandlerSelectors.withMethodAnnotation(RequestMapping.class);
        return RequestHandlerSelectors.basePackage("com.zhm.controller");
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot中使用Swagger2构建RESTful APIs")
                .description(environment.getProperty("spring.application.name", "spring boot application"))
                .termsOfServiceUrl("http://www.zhaohongming.cn")
                .contact(new Contact("赵红明", "http://www.zhaohongming.cn", "hongming.zhao@seedeer.com"))
                .version(environment.getProperty("spring.application.version", "1.0.0"))
                .build();
    }
}
LoginFilter是过滤器,过滤掉一些接口需要处理的问题。如什么样接口要校验等
package com.zhm.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.zhm.util.*;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.util.ResourceUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.WebUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by 赵红明 on 2019/6/27.
 *
 * filterName的首字母一定要小写!!!小写!!!小写!!!
 * 如果不小写,会导致配置的多个过滤器拦截url都失效了
 */
@WebFilter(urlPatterns = {"/api/*"}, filterName = "loginFilter")
public class LoginFilter implements Filter {

    private static Logger logger= LoggerFactory.getLogger(LoginFilter.class);
    private final Environment environment;
    private final StringRedisTemplate redisTemplate;

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    /**
     * 记录那些方法需要token
     */
    private Map<RequestMappingInfo, HandlerMethod> ignoredRequestMappingInfoMap;

    private String HTML_403;

    public LoginFilter(Environment environment,StringRedisTemplate redisTemplate){
        this.environment=environment;
        this.redisTemplate=redisTemplate;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("LoginFilter----init----");
       /* Map<RequestMappingInfo, HandlerMethod> allRequestMappingInfoMap = requestMappingHandlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : allRequestMappingInfoMap.entrySet()) {
            HandlerMethod handlerMethod = entry.getValue();
            boolean hasIgnoreFilter = handlerMethod.hasMethodAnnotation(TokenFilter.class);
            if (hasIgnoreFilter) {
                if (ignoredRequestMappingInfoMap == null) {
                    ignoredRequestMappingInfoMap = Maps.newConcurrentMap();
                }
                ignoredRequestMappingInfoMap.put(entry.getKey(), entry.getValue());
            }
        }*/
        logger.info("getFilterName:"+filterConfig.getFilterName());//返回<filter-name>元素的设置值。
        logger.info("getServletContext:"+filterConfig.getServletContext());//返回FilterConfig对象中所包装的ServletContext对象的引用。
        logger.info("getInitParameter:"+filterConfig.getInitParameter("cacheTimeout"));//用于返回在web.xml文件中为Filter所设置的某个名称的初始化的参数值
        logger.info("getInitParameterNames:"+filterConfig.getInitParameterNames());//返回一个Enum

        try {
            HTML_403 = FileUtils.readFileToString(ResourceUtils.getFile("classpath*:403.html"), StandardCharsets.UTF_8);
        } catch (IOException e) {
            logger.warn(e.getMessage());
            HTML_403 = "<!DOCTYPE html><html><head><title>403 Forbidden</title></head><body><div style=\"text-align: center;\"><h1>403 Forbidden</h1></div><hr><div style=\"text-align: center;\">Permission denied</div></body></html>";
        }

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        logger.info("LoginFilter----doFilter----");
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        String servletPath = httpServletRequest.getServletPath();


      /*  HandlerExecutionChain handlerExecutionChain = null;
        try {
            handlerExecutionChain = requestMappingHandlerMapping.getHandler(httpServletRequest);
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }*/
        logger.debug("servletPath : " + servletPath);
        //如果是登录页面则不需要拦截
        if(servletPath.contains("/api/login")){
            chain.doFilter(request, response);
            return;
        }
        //验证码不需要拦截
        if(servletPath.contains("/api/defaultKaptcha")){
            chain.doFilter(request, response);
            return;
        }
        //接口类不拦截 但是要校验token是否存在
        if(servletPath.contains("/api/interface")){
            /*boolean isIgnore = ignore(handlerExecutionChain);
            if (!isIgnore) {
                chain.doFilter(request, response);
                return;
            }else{
                String token = httpServletRequest.getHeader("access_token");
                //token不存在
                if (null != token) {
                    //验证token是否正确
                    boolean result = JwtUtil.verify(token);
                    if (!result) {
                        logger.info("jwt token 没有校验失败!");
                        this.sendTokenJson(response,JSONObject.parseObject(JSONObject.toJSONString(Result.failure("jwt token 没有校验失败!"))));
                        return;
                    }
                }else{
                    logger.info("jwt token 不存在!");
                    this.sendTokenJson(response,JSONObject.parseObject(JSONObject.toJSONString(Result.failure("jwt token 不存在!"))));
                    return;
                }
            }*/
            chain.doFilter(request, response);
            return;
        }

        //登录页面
        String loginUrl=environment.getProperty("systemmodel.authority.login_url");
        //cookie
        String cookieName= environment.getProperty("systemmodel.authority.default.cookie_name");

        Cookie cookie = WebUtils.getCookie(httpServletRequest, cookieName);
        if(cookie!=null){
            logger.info("cookie found");
        }else{
            logger.info("cookie not found");
            httpServletResponse.sendRedirect(loginUrl);
            return;
        }

        String loginToken = cookie.getValue();
        logger.debug("loginToken : " + loginToken);
        Map<String, Object> userInfo=new HashMap<String, Object>();
        String redisName=environment.getProperty("systemmodel.user.info")+loginToken;
        try {
            userInfo = this.getUserInfo(redisName);
            LoginUser loginUser=new LoginUser();
            loginUser.setUserId(Integer.parseInt(userInfo.get("userId").toString()));
            loginUser.setUserName(userInfo.get("userName").toString());
            if(userInfo.get("avataUrl")!=null){
                loginUser.setAvataUrl(userInfo.get("avataUrl").toString());
            }else{
                loginUser.setAvataUrl("");
            }
            loginUser.setExpires(userInfo.get("expires").toString());
            AuthorityUtils.setCurrentUser(loginUser);
        } catch (Exception e) {
            logger.info("redisName not exist");
            httpServletResponse.sendRedirect(loginUrl);
            return;
        }
        if (userInfo == null) {
            logger.info("user info not exist");
            httpServletResponse.sendRedirect(loginUrl);
            return;
        }
        chain.doFilter(request, response);
    }


    public Map<String,Object> getUserInfo(String loginToken){
        String userInfoJson = redisTemplate.opsForValue().get(loginToken);
        logger.debug("redis.userInfoJson : " + userInfoJson);
        if(userInfoJson!=null){
            Map<String,Object> map= JsonUtil.fromJson(userInfoJson, new com.fasterxml.jackson.core.type.TypeReference<Map<String, Object>>() {});
            if(map!=null){
                return map;
            }
        }
        return null;
    }

    private void TokenErrorHtml(HttpServletResponse response) throws IOException {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType(MediaType.TEXT_HTML_VALUE);
        response.getWriter().write(HTML_403);
    }

    private boolean ignore(HandlerExecutionChain handlerExecutionChain) {
        HandlerMethod handler;
        try {
            if(handlerExecutionChain == null) {
                return false;
            }
            handler = (HandlerMethod) handlerExecutionChain.getHandler();
            if (handler == null) {
                return false;
            }
        } catch (Exception ignore) {
            return false;
        }
        if(ignoredRequestMappingInfoMap != null && !ignoredRequestMappingInfoMap.isEmpty()) {
            Collection<HandlerMethod> handlerMethods = ignoredRequestMappingInfoMap.values();
            for (HandlerMethod handlerMethod : handlerMethods) {
                if (handler.getBeanType().equals(handlerMethod.getBeanType()) && handler.getMethod().equals(handlerMethod.getMethod())) {
                    return true;
                }
            }
        }
        return false;
    }
    @Override
    public void destroy() {
        logger.info("LoginFilter----destroy----");
    }

    private void sendTokenJson(ServletResponse response, JSONObject menuJson) throws IOException {
        PrintWriter out = setPrintWriter(response);
        out.print(menuJson);
        out.flush();
        out.close();
    }
    private PrintWriter setPrintWriter(ServletResponse response) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setCharacterEncoding("UTF-8");
        httpResponse.setContentType("application/json; charset=utf-8");
        httpResponse.setStatus(HttpServletResponse.SC_OK);
        return response.getWriter();
    }
}
InitParamStartupRunner是项目正在启动的时候启动的一些内容。
package com.zhm.interceptor;

import com.alibaba.fastjson.JSON;
import com.zhm.dto.AddressDto;
import com.zhm.entity.ParamDetail;
import com.zhm.entity.Params;
import com.zhm.service.ParamService;
import com.zhm.service.SysAreaService;
import com.zhm.util.Constants;
import com.zhm.util.DateUtil;
import com.zhm.util.JsonUtil;
import com.zhm.util.PropertiesUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Created by 赵红明 on 2019/6/24.
 * 项目启动数据初始化拦截器
 *
 */
@Component
public class InitParamStartupRunner implements CommandLineRunner {

    private static Logger logger= LoggerFactory.getLogger(InitParamStartupRunner.class);

    @Autowired
    private ParamService paramService;

    @Autowired
    private StringRedisTemplate rt;

    @Autowired
    private SysAreaService sysAreaService;

    @Override
    public void run(String... args) throws Exception {

        /**
         * 用于项目启动的时候一些数据的初始化,比如系统参数存储在redis中。
         */
        //所有主参数
        List<Params> paramsList = paramService.findAll();
        logger.info("主参数"+ JsonUtil.toJson(paramsList));
        saveParamsToRedis(paramsList);
        // 所有子参
        List<ParamDetail> paramDetails = paramService.findAllDetails();
        logger.info("子参数"+ JsonUtil.toJson(paramDetails));
        saveParamsDetailToRedis(paramDetails);

        //省市县信息初始化
        List<AddressDto> addressDtos=sysAreaService.getAddress();
        logger.info("地址信息"+ JsonUtil.toJson(addressDtos));
        saveAddress(addressDtos);

        logger.info("当前项目启动时间是: {}", DateUtil.dateToString(new Date()));
    }

    /**
     * 总参 存在redis中
     *
     * @return void
     * @throws
     * @author bob
     * @Param [paramsList]
     * @date 2018/6/15 16:20
     */
    private void saveParamsToRedis(List<Params> paramsList) {
        if (CollectionUtils.isNotEmpty(paramsList)) {
            HashMap<String, String> map = new HashMap<>(paramsList.size());
            Params params;
            for (int i = 0; i < paramsList.size(); i++) {
                params = paramsList.get(i);
                map.put(params.getParamCode(), JSON.toJSONString(params));
            }
            rt.opsForHash().putAll(PropertiesUtil.getRedisPrefixKey() + Constants.PARENT_PARAMS, map);
        }
    }

    private  void saveAddress(List<AddressDto> addressDtos){
        if (CollectionUtils.isNotEmpty(addressDtos)) {
            String redisKey = PropertiesUtil.getRedisPrefixKey() + Constants.address_local;
            rt.opsForValue().set(redisKey, JSON.toJSONString(addressDtos));
        }
    }
    /**
     * 子参 存在redis中
     *
     * @return void
     * @throws
     * @author bob
     * @Param [paramDetails]
     * @date 2018/6/15 16:20
     */
    private void saveParamsDetailToRedis(List<ParamDetail> paramDetails) {
        if (CollectionUtils.isNotEmpty(paramDetails)) {
            ParamDetail paramDetail;
            Map<String, Map<String, String>> mapHashMap = new HashMap<>();
            Map<String, String> map;
            String detailCode;
            String redisKey;
            for (int i = 0; i < paramDetails.size(); i++) {
                paramDetail = paramDetails.get(i);
                detailCode = paramDetail.getParamDetailCode();
                redisKey = PropertiesUtil.getRedisPrefixKey() + Constants.SON_PARAMS +  paramDetail.getParamCode();
                map = mapHashMap.get(redisKey);
                if (MapUtils.isEmpty(map)) {
                    map = new LinkedHashMap<>();
                }
                map.put(detailCode, JSON.toJSONString(paramDetail));
                mapHashMap.put(redisKey, map);
            }

            saveMapToRedis(mapHashMap);
        }
    }

    /**
     * 先清缓存再插入
     * @author      bob
     * @Param       [mapHashMap]
     * @return      void
     * @exception
     * @date        2018/6/15 17:59
     */
    private void saveMapToRedis(Map<String,Map<String,String>> mapHashMap) {
        mapHashMap.forEach((key, value) ->{
            rt.delete(key);
            rt.opsForHash().putAll(key, value);
        });
    }

}

最后,还需要Bootstrap的启动类。

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.web.config.EnableSpringDataWebSupport;
import org.springframework.scheduling.annotation.EnableAsync;

/**
 * Created by 赵红明 on 2019/6/25.
 */
@SpringBootApplication(scanBasePackages = {"com.zhm"})//扫描包
@EnableJpaRepositories(basePackages = {"com.zhm.**.dao"})//扫描dao层
@EntityScan(basePackages = {"com.zhm.**.entity"})
@PropertySource("classpath:env/${spring.profiles.active}/application.properties")//启动后饮用参数
@EnableSpringDataWebSupport
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableAsync
@ServletComponentScan//Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
public class Bootstrap {
    public static void main(String[] args){
        SpringApplication.run(Bootstrap.class);
    }
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值