SpringBoot 3 SpringBoot+VUE案例

3 SpringBoot+VUE案例开发

经过对SpringBoot及VUE的学习,我们已经对他们的开发流程有了一定的了解,我们将这两个框架进行整合,并实现一个简单的前后的开发案例“HelloWorld”。这个案例我们主要实现:(1)系统的登陆、退出;(2)用户的查询、新增、修改、删除。系统架构如下图所示:
SpringBoot 3 SpringBoot+VUE案例_第1张图片

从架构图中可以看到前端UI采用VUE框架开发, vue框架整合了mock、validator、vuex等组件。后端包括:控制层、业务服务层和数据访问层,基于SpringBoot2开发,控制层主要实现了rest的http服务以及权限控制;业务服务层主要用于实现业务逻辑,同时也具备了日志、事物、缓存等功能;数据访问层采用mybatis框架实现。本节案例开发采用mysql作为数据库。

3.1 后端开发

3.1.1 创建工程

后端框架采用SpringBoot2+mybatis+redis整合框架开发,可以参照我们在SpringBoot开发的第一个工程,我们创建一个helloworld的后端工程。结构如下:
SpringBoot 3 SpringBoot+VUE案例_第2张图片

3.1.2 工程配置

SpringBoot工程的主要配置文件包括maven的POM文件和application.properties配置文件。

pom文件内容为:



<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>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.1.5.RELEASEversion>
        <relativePath/>
    parent>
    <modelVersion>4.0.0modelVersion>
    <artifactId>helloworldartifactId>
    <packaging>jarpackaging>
    <version>1.0.1.RELEASEversion>
    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <java.version>1.8java.version>
        <lombok.version>1.16.18lombok.version>
        <commons-lang3.version>3.8.1commons-lang3.version>
        <commons-collections.version>3.2.1commons-collections.version>

        <redis.version>2.9.0redis.version>
        <fastjson.version>1.2.21fastjson.version>
        <swagger2.version>2.2.2swagger2.version>
        <oracle.version>11.2.0.3oracle.version>
        <mysql.version>8.0.11mysql.version>
        <druid-starte.version>1.1.1druid-starte.version>
        <junit.version>4.12junit.version>
        <log4j.version>1.2.15log4j.version>
        <net.minidev.json-smart.version>2.2.1net.minidev.json-smart.version>
        <net.minidev.asm.version>1.0.2net.minidev.asm.version>
        <httpclient.version>4.5.2httpclient.version>
        <shiro.version>1.4.0shiro.version>
        <shiro-redis.version>3.1.0shiro-redis.version>
        <mybatis-spring.version>1.3.2mybatis-spring.version>
        <mybatis-mapper.version>3.4.0mybatis-mapper.version>
        <mybatis-pagehelper.version>1.2.10mybatis-pagehelper.version>
        <guava.version>18.0guava.version>
        <jwt.verson>0.9.0jwt.verson>

        <docker.host>http://127.0.0.1:2375docker.host>
        <docker.repostory>127.0.0.1:5000docker.repostory>
        <docker.registry.name>zone7docker.registry.name>
        <docker.plugin.version>0.4.13docker.plugin.version>
        <skipDockerBuild>falseskipDockerBuild>
    properties>

    <dependencies>




        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
            <exclusions>
                
                
                
                
                
                
                <exclusion>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-starter-loggingartifactId>
                exclusion>
            exclusions>
        dependency>

        
        
        
        
        
        
        

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-aopartifactId>
        dependency>


        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-cacheartifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-securityartifactId>
            <version>2.1.2.RELEASEversion>
        dependency>
        <dependency>
            <groupId>org.springframework.security.oauthgroupId>
            <artifactId>spring-security-oauth2artifactId>
            <version>2.0.14.RELEASEversion>
        dependency>

        <dependency>
            <groupId>org.springframework.security.oauth.bootgroupId>
            <artifactId>spring-security-oauth2-autoconfigureartifactId>
            <version>2.1.5.RELEASEversion>
         dependency>

        <dependency>
            <groupId>org.springframework.securitygroupId>
            <artifactId>spring-security-jwtartifactId>
            <version>1.0.10.RELEASEversion>
        dependency>
        
        <dependency>
            <groupId>io.jsonwebtokengroupId>
            <artifactId>jjwtartifactId>
            <version>${jwt.verson}version>
        dependency>
        


        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-log4j2artifactId>
        dependency>
        <dependency>
            <groupId>com.lmaxgroupId>
            <artifactId>disruptorartifactId>
            <version>3.4.1version>
        dependency>
        

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>net.minidevgroupId>
            <artifactId>json-smartartifactId>
            <version>2.2.1version>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>net.minidevgroupId>
            <artifactId>asmartifactId>
            <version>1.0.2version>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>${junit.version}version>
        dependency>
        

        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>${mybatis-spring.version}version>
        dependency>
        

        
        <dependency>
            <groupId>tk.mybatisgroupId>
            <artifactId>mapperartifactId>
            <version>${mybatis-mapper.version}version>
        dependency>
        

        
        <dependency>
            <groupId>com.github.pagehelpergroupId>
            <artifactId>pagehelper-spring-boot-starterartifactId>
            <version>${mybatis-pagehelper.version}version>
        dependency>
        

        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>${druid-starte.version}version>
        dependency>
        

        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <version>${fastjson.version}version>
        dependency>
        

        
        <dependency>
            <groupId>com.oraclegroupId>
            <artifactId>ojdbc6artifactId>
            <version>${oracle.version}version>
        dependency>
        

        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>${mysql.version}version>
        dependency>
        


        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-redisartifactId>
        dependency>
        

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-mongodbartifactId>
        dependency>
        

        
        <dependency>
            <groupId>io.springfoxgroupId>
            <artifactId>springfox-swagger2artifactId>
            <version>${swagger2.version}version>
        dependency>
        <dependency>
            <groupId>io.springfoxgroupId>
            <artifactId>springfox-swagger-uiartifactId>
            <version>${swagger2.version}version>
        dependency>
        

        
        <dependency>
            <groupId>org.apache.shirogroupId>
            <artifactId>shiro-springartifactId>
            <version>${shiro.version}version>
        dependency>
        
        <dependency>
            <groupId>org.crazycakegroupId>
            <artifactId>shiro-redisartifactId>
            <version>${shiro-redis.version}version>
        dependency>
        

        
        <dependency>
            <groupId>org.apache.httpcomponentsgroupId>
            <artifactId>httpclientartifactId>
            <version>${httpclient.version}version>
        dependency>
        



        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>com.google.guavagroupId>
            <artifactId>guavaartifactId>
            <version>${guava.version}version>
        dependency>
        

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-amqpartifactId>
            <version>2.1.0.RELEASEversion>
        dependency>
        

        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>${lombok.version}version>
        dependency>
        

        
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-lang3artifactId>
            <version>${commons-lang3.version}version>
        dependency>
        <dependency>
            <groupId>commons-collectionsgroupId>
            <artifactId>commons-collectionsartifactId>
            <version>${commons-collections.version}version>
        dependency>

        <dependency>
            <groupId>commons-beanutilsgroupId>
            <artifactId>commons-beanutilsartifactId>
            <version>1.9.3version>
        dependency>

        


        <dependency>
            <groupId>dom4jgroupId>
            <artifactId>dom4jartifactId>
            <version>1.6.1version>
        dependency>
        <dependency>
            <groupId>net.sf.ezmorphgroupId>
            <artifactId>ezmorphartifactId>
            <version>1.0.6version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-autoconfigureartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-thymeleafartifactId>
        dependency>


    dependencies>

    <build>
        <finalName>appfinalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-compiler-pluginartifactId>
                <configuration>
                    <source>${java.version}source>
                    <target>${java.version}target>
                    <encoding>${project.build.sourceEncoding}encoding>
                configuration>
            plugin>

            
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-resources-pluginartifactId>
                <version>2.4.3version>
                <executions>
                    <execution>
                        <phase>compilephase>
                    execution>
                executions>
                <configuration>
                    <encoding>${project.build.sourceEncoding}encoding>
                configuration>
            plugin>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <configuration>
                    <fork>truefork>
                configuration>

            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-surefire-pluginartifactId>
                <version>2.20.1version>
                <configuration>
                    
                    <skipTests>trueskipTests>
                configuration>
            plugin>

            <plugin>
                <groupId>com.spotifygroupId>
                <artifactId>docker-maven-pluginartifactId>
                <version>${docker.plugin.version}version>
                <executions>
                    <execution>
                        <id>build-imageid>
                        <phase>packagephase>
                        <goals>
                            <goal>buildgoal>
                        goals>
                    execution>
                    <execution>
                        <id>push-imageid>
                        <phase>deployphase>
                        <goals>
                            <goal>pushgoal>
                        goals>
                        <configuration>
                            <imageName>${docker.repostory}/${docker.registry.name}/${project.artifactId}:${project.version}imageName>
                        configuration>
                    execution>
                executions>
                <configuration>
                    <registryUrl>${docker.repostory}registryUrl>
                    <pushImage>truepushImage>
                    <dockerHost>${docker.host}dockerHost>
                    <dockerDirectory>${project.basedir}/src/main/dockerdockerDirectory>
                    <imageName>${docker.repostory}/${docker.registry.name}/${project.artifactId}:${project.version}imageName>
                    <imageTags>
                        <imageTag>${project.version}imageTag>
                    imageTags>
                    <resources>
                        <resource>
                            <targetPath>/targetPath>
                            <directory>${project.build.directory}directory>
                            <include>${project.build.finalName}.jarinclude>
                        resource>
                    resources>
                configuration>
            plugin>
        plugins>
    build>

project>

application.properties配置文件,在这里我们将其配置为dev模式,同时在resources下增加一个application-dev.properties的配置文件,用于配置开发测试期间的参数。

文件application.properties

spring.profiles.active=dev

文件application-dev.properties

#==================  server  ===================#
server.port=8080
#server.context-path=/springboot

#================== mybatis =====================#
mybatis.mapper-locations=classpath:mappers/**/*.xml
mybatis.configuration.map-underscore-to-camel-case=true
#================ mybatis pagehelper ==============#
pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql

#==================  database  ===================#
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/zone-demo
spring.datasource.username=root
spring.datasource.password=zgq
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#初始化大小,最小,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true 

#==================  redis  ===================#
# redis 单节点地址
spring.redis.host=localhost
# redis 集群
#spring.redis.cluster.nodes=192.168.177.128:7001,192.168.177.128:7002,192.168.177.128:7003
#spring.redis.cluster.max-redirects=3
# Redis 数据库
spring.redis.database=0
# Redis 端口
spring.redis.port=6379
# Redis 密码
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8 
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=3000

#==================  cache ===================#
spring.cache.type=redis

#==================  RabbitMq  ===================#
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin

spring.rabbitmq.listener.concurrency=10
spring.rabbitmq.listener.max-concurrency=20
spring.rabbitmq.listener.prefetch=50
#==================  RabbitMq 队列配置 ===================#
mq.env=local
basic.info.mq.exchange.name=${mq.env}:basic:info:mq:exchange
basic.info.mq.routing.key.name=${mq.env}:basic:info:mq:routing:key
basic.info.mq.queue.name=${mq.env}:basic:info:mq:queue

#==================  mongoDB 配置 ===================#
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=test

#==================  slf4j日志配置 ===================#
# 路径
logging.path=/Users/zgq/logs
logging.file=helloworld.log
#location of config file (default classpath:logback.xml for logback)
#logging.config=
# levels for loggers, e.g. "logging.level.org.springframework=DEBUG" (TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF)
logging.level.com.zone7=INFO

#==================  默认密码  ===================#
system.default.password=123456

#==================  监控  ===================#
#actuator端口
management.server.port=8310
#修改访问路径,2.0之前默认是/,2.0默认是/actuator
management.endpoints.web.base-path=/actuator
#开放所有页面节点 ,默认只开启了health、info两个节点
management.endpoints.web.exposure.include=*
#显示健康具体信息,默认不会显示详细信息
management.endpoint.health.show-details=always

3.1.3 代码开发

3.1.3.1 用户安全验证

首先我们沿用第一章的SpringBoot工程,在 “/src/main/java/com/zone7/demo/helloworld/config/filter”下新增加一个安全过滤器,在实际应用中可以采用Oauth2、SpringSecurity或者Shiro来实现,这里只使用了session保存用户状态,并通过一个Filter的实现类来获取用户是否处于登陆状态来控制系统的安全访问。代码如下所示:

package com.zone7.demo.helloworld.config.filter;

import com.google.common.collect.Sets;
import com.zone7.demo.helloworld.sys.common.RequestHolder;
import com.zone7.demo.helloworld.sys.vo.SysUserVo;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;

/**
 * RequestFilter
 * 请求过滤器
 * 安全认证
 * @author: zone7
 * @time: 2019.02.19
 */
@WebFilter(filterName = "RequestFilter", urlPatterns = "/*")
public class RequestFilter implements Filter {

    private static Set<String> URL_WHITE_LIST = Sets.newHashSet();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //忽略不过旅的路径
        URL_WHITE_LIST.add("/unauth");
        URL_WHITE_LIST.add("/login");
        URL_WHITE_LIST.add("/logout");

        URL_WHITE_LIST.add("/sys/unauth");
        URL_WHITE_LIST.add("/sys/login");
        URL_WHITE_LIST.add("/sys/logout");

        URL_WHITE_LIST.add("/static");
        URL_WHITE_LIST.add("/actuator");
        URL_WHITE_LIST.add("/oauth");//oauth2.0默认接口
        URL_WHITE_LIST.add("/api"); // 外部接口采用oauth进行权限验证
    }

    private boolean isWhiteUrl(String requestUrl){
        if (URL_WHITE_LIST.contains(requestUrl)){
            return true;
        }
        for(String str:URL_WHITE_LIST){

            if(requestUrl.startsWith(str)){
                return true;
            }

        }

        return false;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestUrl = request.getRequestURI();
        if (isWhiteUrl(requestUrl)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        SysUserVo userVo = (SysUserVo) request.getSession().getAttribute("user");
        if (userVo == null) {
            request.getRequestDispatcher("/unauth").forward(request, response);
            return;
        }

        RequestHolder.add(userVo);
        RequestHolder.add(request);


        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

3.2 前端开发
采用vue-cli 命令生成工程脚手架(创建命令:vue init webpack helloworld_web),前端工程的名称为“helloworld_web” 。采用IDEA工具打开工程,默认的结构如下图所示:
SpringBoot 3 SpringBoot+VUE案例_第3张图片

工程目录默认有了router、compotent、assets,我们还需要增加api、views、store、utils目录。api目录用于存放采用mock实现的前后端交互脚本,views用于存放功能页面vue模板,store用于存放采用vuex实现的状态管理功能,utils用于存放通用工具脚本。工程目录结构如下图所示:
SpringBoot 3 SpringBoot+VUE案例_第4张图片

你可能感兴趣的:(java,java,vue.js,node.js,spring,boot)