1. 程式人生 > >Vue+SpringBoot 前後端分離小實驗

Vue+SpringBoot 前後端分離小實驗

1、概述

業務模型:員工+部門,多對一,實現增刪改查(CRUD)

後端:Spring Boot + Spring MVC + Spring REST Data

前端:Vue + axios

2、後端開發

POM依賴

<?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>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-rest-hal-browser</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </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.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.1.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-bean-validators -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-bean-validators</artifactId>
            <version>2.7.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-spi -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-spi</artifactId>
            <version>2.7.0</version>
        </dependency>

        <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-core</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

        </plugins>
    </build>


</project>

(1)業務實體

員工(`Employee`)

package com.example.demo.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;

@Entity(name = "tbl_emp")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Employee implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "emp_id")
    private Long id;

    @Column(name = "last_name",length = 100,nullable = false,unique = false)
    @Size(min = 2,max = 50)
    private String lastName;

    @Email(message = "郵箱格式不正確!")
    @Column(name = "email",length = 100,nullable = false,unique = true)
    private String email;

    @Column(name = "phone_number",length = 11, nullable = false,unique = false)
    @Size(min = 11,max = 11)
    private String phoneNumber;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Column(name = "birth")
    private Date birth;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column(name = "create_time",columnDefinition="timestamp default current_timestamp")
    private Timestamp createTime;

    @ManyToOne
    @JoinColumn(name = "dept_id")
    private Department department;
}

部門(`Department`)

package com.example.demo.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.io.Serializable;

/**
 * @author Blessed
 */
@Entity(name = "tbl_dept")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Department implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "department_id")
    private Long id;
    @Column(name = "department_name")
    @Size(min = 2,max = 50)
    private String departmentName;
}

其中用`Lombok`來簡化程式碼長度

(2)資料訪問層

`EmployeeRepository`

package com.example.demo.repository;

import com.example.demo.entity.Employee;
import io.swagger.annotations.Api;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.web.bind.annotation.CrossOrigin;

/**
 * @author Blessed
 */
@Api(tags = "Employee Entity") //Swagger REST API 但是好像目前需要一些外掛,由於版本衝突,不能顯示
@CrossOrigin(origins = {"http://localhost:8090","null"}) //CORS 跨域請求設定
@RepositoryRestResource(path = "emp") //配置生成REST API和對應Controller,path屬性指定訪問路徑,按道理應該是複數(emps)這裡就忽略了
public interface EmployeeRepository extends JpaRepository<Employee,Long> {
}

`DepartmentRepository`

package com.example.demo.repository;

import com.example.demo.entity.Department;
import io.swagger.annotations.Api;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.web.bind.annotation.CrossOrigin;

/**
 *
 * @author Blessed
 */
@Api(tags = "Department Entity")
@CrossOrigin(origins = {"http://localhost:8090","null"})
@RepositoryRestResource(path = "dept")
public interface DepartmentRepository extends JpaRepository<Department,Long> {
}

到此,後端大功告成,打包

mvn clean package

通過`java -jar jarName`來啟動Spring Boot專案

java -jar demo-0.0.1-SNAPSHOT.jar

專案啟動

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.5.RELEASE)

......
: Mapped "{[/{repository}/{id}],methods=[HEAD],produces=[application/hal+json || application/json]}"

Mapped "{[/{repository}/{id}],methods=[OPTIONS],produces=[application/hal+json || application/json]}"

Mapped "{[/{repository}],methods=[GET],produces=[application/hal+json || application/json]}"
//獲取對應實體的所有的記錄,比如傳送GET /emp 獲取資料庫中所有員工資訊,支援分頁

Mapped "{[/{repository}],methods=[OPTIONS],produces=[application/hal+json || application/json]}"

Mapped "{[/{repository}],methods=[GET],produces=[application/x-spring-data-compact+json || text/uri-list]}"

Mapped "{[/{repository}],methods=[HEAD],produces=[application/hal+json || application/json]}"

Mapped "{[/{repository}],methods=[POST],produces=[application/hal+json || application/json]}"
//新增一條記錄,用JSON傳送

Mapped "{[/{repository}/{id}],methods=[PATCH],produces=[application/hal+json || application/json]}"

Mapped "{[/{repository}/{id}],methods=[PUT],produces=[application/hal+json || application/json]}"
//修改實體內容,修改內容放在JSON傳送

Mapped "{[/{repository}/{id}],methods=[GET],produces=[application/hal+json || application/json]}"
//獲取對應id的實體資訊,比如 GET /emp/2 獲取ID為2的員工資訊

Mapped "{[/{repository}/{id}],methods=[DELETE],produces=[application/hal+json || application/json]}"
//刪除對應id的實體,比如 DELETE /emp/2 刪除員工ID為2的記錄

Mapped "{[/{repository}/{id}/{property}],methods=[DELETE],produces=[application/hal+json || application/json]}"
//獲取詳細配置資訊
...

(3)Postman測試

傳送 GET http://localhost:8080/emp

{
    "_embedded": {
        "employees": [
            {
                "lastName": "Blessed",
                "email": "[email protected]",
                "phoneNumber": "15850720606",
                "birth": "1996-03-29T00:00:00.000+0000",
                "createTime": "2018-09-18T15:11:02.000+0000",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/emp/1"
                    },
                    "employee": {
                        "href": "http://localhost:8080/emp/1"
                    },
                    "department": {
                        "href": "http://localhost:8080/emp/1/department"
                    }
                }
            },
            {
                "lastName": "Ryan",
                "email": "[email protected]",
                "phoneNumber": "15850720606",
                "birth": "1996-02-12T00:00:00.000+0000",
                "createTime": "2018-09-18T20:00:00.000+0000",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/emp/2"
                    },
                    "employee": {
                        "href": "http://localhost:8080/emp/2"
                    },
                    "department": {
                        "href": "http://localhost:8080/emp/2/department"
                    }
                }
            },
            {
                "lastName": "Helen",
                "email": "[email protected]",
                "phoneNumber": "12345698725",
                "birth": "1996-05-05T00:00:00.000+0000",
                "createTime": "2018-09-19T00:00:00.000+0000",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/emp/3"
                    },
                    "employee": {
                        "href": "http://localhost:8080/emp/3"
                    },
                    "department": {
                        "href": "http://localhost:8080/emp/3/department"
                    }
                }
            },
            {
                "lastName": "Bob",
                "email": "[email protected]",
                "phoneNumber": "15452368460",
                "birth": "1996-05-05T00:00:00.000+0000",
                "createTime": "2019-09-23T12:00:00.000+0000",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/emp/6"
                    },
                    "employee": {
                        "href": "http://localhost:8080/emp/6"
                    },
                    "department": {
                        "href": "http://localhost:8080/emp/6/department"
                    }
                }
            },
            {
                "lastName": "Jack",
                "email": "[email protected]",
                "phoneNumber": "25136587541",
                "birth": "1996-07-12T00:00:00.000+0000",
                "createTime": "2019-09-24T12:00:00.000+0000",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/emp/7"
                    },
                    "employee": {
                        "href": "http://localhost:8080/emp/7"
                    },
                    "department": {
                        "href": "http://localhost:8080/emp/7/department"
                    }
                }
            }
        ]
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/emp{?page,size,sort}",
            "templated": true
        },
        "profile": {
            "href": "http://localhost:8080/profile/emp"
        }
    },
    "page": {
        "size": 20,
        "totalElements": 5,
        "totalPages": 1,
        "number": 0
    }
}

其他方法就不一一試了

3、前端開發

簡單用Vue腳手架建立專案,就一個helloworld

注意,此Hello專案的在WebStorm中啟動的埠號為:8090

(1)配置代理(PS:才疏學淺,不知道為什麼,不配就可能產生跨域的問題)

在`/config/index.js`中的`proxyTable`配置

    proxyTable: {
      '/api': {
        target: 'http://127.0.0.1:8080',
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    },

以後比如發請求`http://127.0.0.1:8080/emp`,變成`/api/emp`,實際的發的請求就是:`http://localhost:8090/api/emp`

所以在發`POST`、`PUT`,`DELETE`請求的跨域時候就需要匹配後端的跨域設定

在前面後端開發中,在`repository`中配置瞭如下的註解

@CrossOrigin(origins = {"http://localhost:8090","null"})

注意是`8090`,而不是`8080`

接下里就是簡單的`axios`使用了

<template>
  <div>
    <button @click="queryAllEmployees">查詢所有員工</button>
    <button @click="addEmployee">新增員工</button>
    <button @click="deleteEmployee">刪除員工</button>
    <button @click="updateEmployee">更新員工資訊</button>
    <br><br>
    <button @click="deleteDept">刪除部門</button>
    <button @click="addDept">新增部門</button>
    <button @click="updateDept">修改部門</button>
  </div>
</template>

監聽函式的程式碼為:

// import qs from 'qs'
export default {
  name: 'HelloWorld',
  methods: {
    updateEmployee () {
      this.$axios({
        url: '/api/emp/1',
        method: 'PUT',
        data: "{\n" +
          "\t\"lastName\": \"Blessed\",\n" +
          "\t\"email\": \"[email protected]\",\n" +
          "\t\"phoneNumber\": \"12365478985\",\n" +
          "\t\"birth\": \"1996-03-29\",\n" +
          "\t\"createTime\": \"2018-09-24T21:52:52\",\n" +
          "\t\"department\": \"http://localhost:8080/dept/3\"\n" +
          "}",
        headers: {'Content-Type': 'application/json'}
      }).then(res => {console.log(res)}).catch(err => {console.log(err)})
    },
    deleteEmployee () {
      this.$axios({
        url: '/api/emp/3',
        method: 'DELETE'
      }).then(res => {console.log(res)}).catch(err => {console.log(err)})
    },
    updateDept () {
      this.$axios({
        url: '/api/dept/13',
        method: 'PUT',
        data: "{\"departmentName\": \"前臺部門\"}",
        headers: {'Content-Type': 'application/json'}
      }).then(
        res => {console.log(res)}
      ).catch(err => {console.log(err)})
    },
    deleteDept () {
      this.$axios({
        url: '/api/dept/11',
        method: 'DELETE'
      }).then(
        res => {
          console.log(res)
        }
      ).catch(
        err => {
          alert('失敗')
        }
      )
    },
    addEmployee () {
      alert('進入')
      this.$axios({
        url: '/api/emp',
        method: 'POST',
        data: "{\"lastName\": \"Jack\", \"email\": \"[email protected]\", \"phoneNumber\": \"25136587541\", \"birth\": \"1996-07-12\", \"createTime\": \"2019-09-24T12:00:00\", \"department\": \"/api/dept/4\"}",
        headers: {'Content-Type': 'application/json'}
      }).then(
        res => {
          alert('成功')
          console.log(res)
        }
      ).catch(
        err => {
          alert('失敗')
          console.log(err)
        }
      )
      alert('結束')
    },
    queryAllEmployees () {
      var url = '/api/emp'
      this.$axios.get(url).then(
        res => {
          console.log(res)
        }
      ).catch(
        err => {
          console.log(err)
        }
      )
    },
    addDept () {
      this.$axios({
        url: '/api/dept',
        method: 'post',
        data: "{\"departmentName\": \"前臺接待部門\"}",
        headers: {'Content-Type': 'application/json'}
      }).then(
        res => {
          console.log(res)
        }
      ).catch(
        err => {
          console.log(err)
        }
      )
    }
  }
}

本人才接觸Vue,就關掉了Eslint的檢查,不然雙引號會報錯

【注意】:`data`屬性應該是一個這樣的格式:

{"param1": "value1", "param2": "value2"}
data: “{\"param1\": \"value1\", \"param2\": \"value2\"}”
//要是不這麼發,後臺會報錯

另外注意的是,最好設定`Content-Type`為`application/json`

以上就可以進行簡單的增刪改查。而且後端再怎麼複雜,只要規範暴露REST API,就不管前端什麼事了

相關推薦

Vue+SpringBoot 前後分離實驗

1、概述 業務模型:員工+部門,多對一,實現增刪改查(CRUD) 後端:Spring Boot + Spring MVC + Spring REST Data 前端:Vue + axios 2、後端開發 POM依賴 <?xml version="1.

vue + Springboot 前後分離整合UEditor

UEditor只提供JSP版本的後端入口程式碼。但是它提供了專案原始碼,因此我們可以根據業務需求來修改原始碼。 現在開始整合UEditor  1、下載UEditor官網最新的jsp版本的包,下載完成解壓之後得到一個utf8-jsp的資料夾,裡面包含的內容如下: 除了

【筆記】vue+springboot前後分離實現token登入驗證和狀態儲存的簡單實現方案

簡單實現 token可用於登入驗證和許可權管理。 大致步驟分為: 前端登入,post使用者名稱和密碼到後端。 後端驗證使用者名稱和密碼,若通過,生成一個token返回給前端。 前端拿到token用vuex和localStorage管理,登入成功進入首頁。 之後前端每一次許可權操作如跳轉路由,都需要判斷是否存

Uni-app實戰專案之整合SpringBoot前後分離開發Android、iOS、程式應用

歡迎加入課程群:571278542 課程大綱[會有細微差異,最終以錄製課程為準]: 1、成果演示 2、開發技術和工具介紹 3、建立資料庫(後臺開發3-7節) 4、環境搭建 5、欄目管理(七牛雲管理附件)

Springboot+Vue前後分離與合併方案

摘要: springboot+vue的前後端分離與合併 springboot和vue結合的方案網路上的主要有以下兩種: 1. 【不推薦】在html中直接使用script標籤引入vue和一

一分鐘搭建vue,elementui,springboot前後分離項目

javax let ddp imp ram config tps save red 1.下載 npm , node.js 2.element-ui項目下載:https://github.com/ElementUI/element-starter 3.springboot項目

一套基於SpringBoot+Vue+Shiro 前後分離 開發的程式碼生成器

一、前言 最近花了一個月時間完成了一套基於Spring Boot+Vue+Shiro前後端分離的程式碼生成器,目前專案程式碼已基本

flask+vue.js 前後分離入門教程

pla .com 數據 快樂 storage pack 輕量 沒有 www 適合對象: 對flask有一定基礎,做過簡單的flask項目。但是之前每個頁面都是通過render_template來渲染的。沒有前後端分離的項目經歷。 整理了網上“非夢nj”童鞋的9篇文章: V

SpringBoot前後分離Instant時間戳自定義解析

在SpringBoot專案中,前後端規定傳遞時間使用時間戳(精度ms). @Data public class Incident { @ApiModelProperty(value = "故障ID", example = "1") private Integer id; @ApiMo

vue+Springboot 前後資料互動(1)

最近使用 vue 的 axios 往後端傳送資料,結果一直報錯,嘗試了多種方法 如果vue專案沒有打包放在 springboot 專案下的話,需要開啟跨域支援 在 vue 專案裡 config 目錄下的 index.js 檔案,找到 proxyTable   加上 '

Vue專案 前後分離模式解決開發環境的跨域問題

在前後端分離的web開發中,我們與後臺聯調時,會遇到跨域的問題。 比如: 開發地址是 localhost:8080,需要訪問 localhost:9000 上的介面。 不同域名之間的訪問,需要跨域才能正確請求。跨域的方法很多,在 Vue-cli 建立的專案中,可以直接利用 Node.js

Django連線VUE前後分離

搭建Django參考改自here 1、建立Django專案: django-admin startproject ulb_manager 2、進入專案根目錄,建立app作為專案後端 cd ulb_manager python manage.py star

從零到一 django + vue 構建前後分離專案

(本文在win10環境下進行) django 和 vue 的優點 django的python血統,開發起來基本上是站在巨人的肩膀上,用起來順手,加上drf這個restful API 框架,SaltStack、Ansible可做配置管理,celery做任務佇列

springboot前後分離跨域同源問題

筆者最近做springboot前後端分離遇到一些問題,在這裡分享下。主要是跨域問題,導致後端無法獲取自定義請求頭, 前端後臺分開部署在不同域名,自然而然就會存在跨域問題,前端ajax的處理方式通常就是jsonp。 springboot 後端配置有如下兩種方式,二選一就好

java面試題架構篇NodeJS,Vue前後分離都是什麼鬼

1.Node.JS node.js是開源的,跨平臺的,瀏覽器之外的Js執行環境。前後端統一語言開發。主要特點 事件驅動 非同步IO 基於Google的V8引擎,V8引擎執行Javascript的速度非常快,效能非常好 單執行緒,單程序 優點: 容易學習,全棧開發-

Java Web 開發 springboot 前後分離以及身份驗證

我先接觸的前後端分離是.Net的webapi,特性路由什麼的,所以想知道java中的webapi是什麼樣的,在網上直接查java webapi 得不到類似於C# 的webapi的資料,但是查java 前後端分離,就能找到類似於C# webapi的東西。 看了一篇文章,根據文章中提供的gith

Flask & Vue 構建前後分離的應用

Flask & Vue 構建前後端分離的應用 最近在使用 Flask 製作基於 HTML5 的桌面應用,前面寫過《用 Python 構建 web 應用》,藉助於完善的 Flask 框架,可以輕鬆的構建一個網站應用。服務端的路由管理和前端模板頁面的渲染都使用 Flask 提供的 API 即可,並且由於

springboot前後分離之跨域

springmvc有多種處理跨域的方法,介紹最簡單的一種: @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addCors

dotnetcore+vue+elementUI 前後分離 三(前端篇)

                        &n

angular+springboot前後分離無法獲取返回response頭中的Authorization

問題描述:專案前後端分離時,因為使用到jwt需要將jwt設定到Authorization中,頁面也可以顯示Authorization。但是angular無法獲取到。 解決辦法: 後臺伺服器解決跨域的地方新增設定: config.addExposedHeader("A