前后端分离之Spring&Vue单页面开发(2)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 前言     需求: 最近本人在学习SpringBoot,希望自己能搭一个简单的Demo应用出来,但是搭到前端的时候遇到了困惑,因为网络上大部分教程前端都是应用模板引擎thymeleaf生成的,它给我的感觉就是一个进化版的JSP,但是很明显这种开发方式已经有些落后了。

前言

    需求: 最近本人在学习SpringBoot,希望自己能搭一个简单的Demo应用出来,但是搭到前端的时候遇到了困惑,因为网络上大部分教程前端都是应用模板引擎thymeleaf生成的,它给我的感觉就是一个进化版的JSP,但是很明显这种开发方式已经有些落后了。现在前端越来越工程化,Angular/Vue/React等框架非常流行,所以我希望搭建一个更符合技术进步方向的前端应用(我选择了相对容易入门的Vue)。

    问题: 在查阅资料过程,我发现SpringBoot和Vue相关的入门材料非常的多,但是关于两者结合的相对较少,导致踩了不少坑。在不断得试错之下,终于成功搭建了一个Demo应用,并实现一个登陆实例,因此在此总结巩固。

    项目架构  服务端以SpringBoot框架为核心,除提供转发到首页外,只提供RESTful接口,通过Json格式消息进行交互;前端以Vue全家桶为核心,实现SPA单页面应用,以ajax方式与服务端进行通信;前后端分离开发,因此会建两个项目,通过npm run build 打包项目(复制进)项目进行整合。

    阅读者有一定的Java基础,SpringBoot基础,同时有一定的前端基础,Vue基础。

好吧,这篇博客其实主要是写给我自己的

开发环境介绍

  • JDK1.8
  • Node v8.9.3
  • npm v5.5.1
  • 开发工具IDEA(安装Vue.js插件)
  • 数据库MySQL 57
  • 版本管理工具 Git

都是一些基础的开发环境,具体搭建过程略。

服务端搭建

    利用Spring Initializr 创建一个SpinrgBoot模板
image
    组名及项目名随意,添加依赖的话视需求而定,这里就添加了Web的核心依赖和一些数据库的依赖
image
    pom.xml 文件 核心依赖

    <dependencies>
        <!-- JPA 默认实现为Hibernate -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- 核心依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 可以实现热部署,在IDEA上实现热部署还需一些额外的配置,请查阅资料 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- JDBC for mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- 测试框架 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    然后,添加配置文件,在这里我用yml进行配置,感觉比较优雅
    application.xml 放置在resources根目录下 记得把数据库username和password和url改为自己的

# set server port
server:
  port: 8888  # 配置端口
  context-path: / # 项目启动地址为 localhost:8888/

spring:
  datasource: # set database config
    url: jdbc:mysql://localhost:3306/***?useUnicode=true&characterEncoding=utf8&useSSL=false
    username: *****
    password: *****
    driver-class-name: com.mysql.jdbc.Driver
  jpa: # set jpa
    database: MYSQL # specify ths DBMS
    show-sql: true # show or not log for each sql query
    hibernate:
      ddl-auto: update # Hibernate ddl auto(create, create-drop, update)
      naming: # naming strategy
        strategy: org.hibernate.cfg.ImprovedNamingStrategy
    properties:
      hibernate: # stripped before adding them to entity manager
        dialect: org.hibernate.dialect.MySQL5Dialect
  aop: #设置aop,aop依赖添加后默认是启用的
    proxy-target-class: true

    创建目录仅结构,目录结构参考了网络上的案例和自己的习惯,供参考
image

 

    Demo项目仅实现登陆实例,因此数据实体只需要一个User就好,User类上需加 @Entity 注解,代表这是实体类,交由Hibernate进行管理;同时,我使用了spring boot核心依赖之一的validation作为参数验证框架,验证方法会在controller中实现;详细代码参阅 entity/SysUser 如果全贴代码的话,篇幅会非常的长,所以详细代码请到github上看源码,都带有详细的注释

github_spring-vue-demo

    顺便把SysUser的Dao层接口实现

/**
 * 用户Dao层
 * 继承JapRepository,可以实现一些默认方法,如save/findAll/findOne/delete/count/exists 等
 * Created by bekey on 2017/12/9.
 */
public interface SysUserRepository extends JpaRepository<SysUser,Integer> {
    //...
}

    我们在SysUserRepository中只添加一个findFirstByNameAndPassword方法就够了,详细源码参见 repository/SysUserRepository

    接着,搭建服务层,服务层遵循服务接口 + 实现 的模式,我们现在还没有创建用户,那么就提供 saveUser 和 checkLogin 两个服务好啦,详细代码参阅 service/SysUserService 和 service/SysUserServiceImpl

    服务层实现方式都比较简单粗暴,通过修改实现类可以增加密码加密等更多功能

    然后,该搭建控制层了,为控制类添加 @RestController 就可以实现该类下所有方法都会自动以Json格式返回数据啦!

/**
 *  用户控制层
 * . @RestController 该类下所有返回值默认以json格式进行返回  
 * . @RequestMapping 匹配url地址 /user  
 * . @Validated 代表该类启用参数验证,通过添加注解可以验证参数
 * Created by bekey on 2017/12/20.
 */
@RestController
@RequestMapping("/user")
@Validated
public class SysUserController {
    //...
}

    现在还不急着实现控制层,因为我们先要约定前后端交互的格式,下面是一个简易的格式 ,code是状态码200代表正常,message是消息通常应该是简单的一句话,data是额外的内容
消息格式及生成大量参考了 github传送门 的代码,在此表示感谢

{
    "code":200,
    "message":"附带的消息",
    "data":{}
}

    为此,在entity下创建class RestResult 和 enum ResultCode 约定消息格式及状态码,因为RestResult十分常用,设置却比较麻烦,为防止错误返回,建议采用工厂模式生成,所以要在utils下添加一个生成类ResultGenerator 相关代码参阅 entity/RestResult  entity/ResultCode  utils/ResultGenerator

    好啦,这些搭完终于可以写controller了 /(ㄒoㄒ)/~~ java啰嗦果然名不虚传
现在我们只提供两个接口 分别是 register/login ,但是要添加参数验证

     /**
     * 匹配 /user/register 地址
     * .在实体前添加 @Valid 注解代表要对这个实体进行验证,如果验证不通过就会报异常
     * bindingResult是对异常信息的包装,不过这里我们不用,而是交由异常处理器进行处理
     * @return 注册成功会将注册信息返回(!因为是demo所以没有考虑安全性)
     */
    @RequestMapping("/register")
    public RestResult register(@Valid SysUser user, BindingResult bindingResult) {
        return generator.getSuccessResult("用户注册成功",userService.saveUser(user));
    }

    /**
     * 匹配 /user/login 地址 ,限定POST方法
     * 。@NotNull 在字段前添加注解代表验证该字段,如果为空则报异常
     * @return 登陆成功则返回相关信息,否则返回错误提示
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public RestResult login(@NotNull(message = "用户名不能为空") String name,@NotNull(message = "密码不能为空") String password, HttpSession session) {
        SysUser user = userService.checkLogin(name, password);
        if(user != null) {
                //储存到session中
            session.setAttribute("user",user);
            return generator.getSuccessResult("登陆成功",user);
        }
        return generator.getFailResult("用户名/密码错误");
    }

    这样我们的接口就写好了,但是如果参数没通过验证怎么办呢?程序报异常但是用户却得不到反馈是明显不可以的,所以我们添加一个exceptionHandler

        /**
     * 为参数验证添加异常处理器
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public RestResult handleConstraintViolationException(ConstraintViolationException cve) {
        //这里简化处理了,cve.getConstraintViolations 会得到所有错误信息的迭代,可以酌情处理
        String errorMessage = cve.getConstraintViolations().iterator().next().getMessage();
        return generator.getFailResult(errorMessage);
    }

    完整版代码请参阅 controller/SysUserController

    项目跑一下,访问localhost:8888 ... 嗯 404 我们没有主页,那在resources/static 下创建一个index.html,将就一下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>这是主页</title>
</head>
<body>
    <h1>这是主页</h1>
</body>
</html>

    ok 在缺省配置下,框架会自动找到static下index.html 作为主页的 访问

http://localhost:8888/user/register?name=myadmin&password=123456

    看是不是返回一个json,告诉你注册成功了呢?

{"code":200,"message":"用户注册成功","data":{"id":1,"name":"myadmin","password":"123456"}}

    好,那再访问一次

http://localhost:8888/user/register?name=myadmin&password=1234

    看是不是返回一个json,告诉你密码应设为6至18位了呢?

{"code":400,"message":"密码应设为6至18位","data":null}

    再来一次

http://localhost:8888/user/register?name=myadmin&password=456789

    看是不是返回一个json,告诉你违反主键/唯一约束条件了呢?

    试着登陆一下

http://localhost:8888/user/login?name=myadmin&password=123456

    应该是一个404,因为只接受post请求,如果要验证可以通过其它方法
配置还没有结束 因为前后端分离,为了开发的方便,我们需要配置一下跨域,关于跨域问题,不理解的话可以去查阅一下资料 在config下新建一个CorsConfig

/**
 * 设置允许跨域
 */
@Configuration
public class CorsConfig {
    /**
     允许任何域名使用  
     允许任何头  
     允许任何方法(post、get等)
     */
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1
        corsConfiguration.addAllowedHeader("*"); // 2
        corsConfiguration.addAllowedMethod("*"); // 3
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); 
        return new CorsFilter(source);
    }
}

    服务端的工作基本就完成大部分了,目前我们仅创建了两个接口,和一个临时主页,稍后完成前端项目之后才能继续。

    完整体源码 -> github_spring-vue-demo

前端项目搭建

    后续内容 前后端分离 Spring Boot + Vue 开发单页面应用 个人总结(二)

项目展示及源码

以后可能完善,谢谢。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
人工智能 JavaScript 前端开发
毕业设计|基于Spring Boot和Vue.js的前后端分离商城系统(二)
毕业设计|基于Spring Boot和Vue.js的前后端分离商城系统
|
2月前
|
安全 Java 数据库
【Spring Security】Spring Security 前后端分离认证
【Spring Security】Spring Security 前后端分离认证
65 0
|
6天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
1月前
|
存储 JavaScript 前端开发
Spring Boot + Vue: 实现文件导入导出功能
本文介绍了使用Spring Boot和Vue实现文件导入导出的步骤。在后端,Spring Boot通过`MultipartFile`接收上传文件,保存至服务器,并使用`ResponseEntity`提供文件下载。前端部分,Vue项目借助`axios`发送HTTP请求,实现文件选择、上传及下载功能。这种前后端分离的实现方式提高了应用的可维护性和可扩展性。
36 2
|
1月前
|
Web App开发 前端开发 JavaScript
Spring Boot整合 mybatisplus(后端) Vue+echarts+Element UI+axios(前端)---前后端项目实例demo
Spring Boot整合 mybatisplus(后端) Vue+echarts+Element UI+axios(前端)---前后端项目实例demo
27 1
|
1月前
|
JavaScript 安全 Java
Spring Boot 和 Vue.js 实现的前后端分离的用户权限管理系统
Spring Boot 和 Vue.js 实现的前后端分离的用户权限管理系统
53 0
|
1月前
|
JavaScript Java 数据库连接
Spring Boot 2.0+Mybatis+Vue的轻量级后台管理系统
Spring Boot 2.0+Mybatis+Vue的轻量级后台管理系统
|
3月前
|
人工智能 前端开发 JavaScript
毕业设计|基于SpringBoot+Vue的前后端分离的电影购票系统(二)
毕业设计|基于SpringBoot+Vue的前后端分离的电影购票系统
|
3月前
|
前端开发 Java 关系型数据库
毕业设计|基于SpringBoot+Vue的前后端分离的电影购票系统(一)
毕业设计|基于SpringBoot+Vue的前后端分离的电影购票系统
|
3月前
|
监控 JavaScript Java
毕业设计|基于Spring Boot和Vue.js的前后端分离商城系统(一)
毕业设计|基于Spring Boot和Vue.js的前后端分离商城系统