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