vue3+SpringBoot+postgresql 项目前后端传参
Posted 水w
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3+SpringBoot+postgresql 项目前后端传参相关的知识,希望对你有一定的参考价值。
【项目大纲】:vue3+SpringBoot+postgresql 简单实现项目前后端传参:
- 使用postgresql数据库,
- 前端使用vue3+vite+ts,
- 后端使用SpringBoot框架。
目录
一、postgresql数据库
postgresql中新建了一个数据库【test-demo】,其中又新建了【my_geo】表结构,插入了三条数据。
二、vue3+vite部分
如果需要新建vite+vue3+ts项目,请移步到新建vite+vue3+ts项目,以及解决过程中遇到的问题_水w的博客-CSDN博客
目前项目的目录结构,如下所示:
1 main.ts
首先你要将axios作为全局的自定义属性,每个组件可以在内部直接访问(Vue3),该部分要放在pp.mount('#app')的全面。(这部分需要放在app.mount('#app')的前面)
import createApp from 'vue'
import './style.css'
import App from './App.vue'
import ElementPlus from 'element-plus'
// import 'element-plus/theme-chalk/index.css';
import 'element-plus/dist/index.css'
import axios from 'axios'
const app = createApp(App)
// 配置请求根路径
axios.defaults.baseURL = 'http://localhost:8088'
//将axios作为全局的自定义属性,每个组件可以在内部直接访问(Vue3),该部分要放在pp.mount('#app')的全面
app.config.globalProperties.$http = axios
app.use(ElementPlus)
app.mount('#app')
2 App.vue
App.vue是运行vue的主文件,引入myTable.vue测试文件。代码如下:
<template>
<div>
<myTable></myTable>
</div>
</template>
<script lang="ts">
import myTable from '@/components/Cesium/demo-test/myTable.vue'
export default
name: 'App',
data:function()
return
,
created: function()
console.log("组件被创建了")
,
components:
myTable
</script>
<style>
</style>
3 myTable.vue测试页面
这是测试页面,逻辑流程如下,
- 首先加载页面的时候,前端vue接收到sprintboot返回到的查询【my_geo】表中所有数据记录,展示到页面上;
- 当点击复选框选择“铁路”类型,并点击“确定”按钮之后,vue的axios将“铁路”参数传送到sprintboot后端;
- sprintboot后端接收到“铁路”参数,重新查询数据库中的【my_geo】表,过滤得到结果,并返回给前端vue;
- 前端vue接收到sprintboot返回到的结果时,更新页面展示数据,并展示到页面上;
<template>
<div>
<div>
<div v-for="item in checkboxData"
:key="item.dictid"
style="font-size: 18px">
<el-checkbox
v-model="item.checked" :label="item.type" :id="item.typeid" :value="item.type">
</el-checkbox>
</div>
<div style="margin-top: 10px">
<el-button @click="checkall" size="small">全选</el-button>
<el-button @click="checkno" size="small">全不选</el-button>
<el-button type="primary" @click="checkok" size="small">确定</el-button>
</div>
</div>
<el-table
ref="multipleTable"
:data="tableDataInfo"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="85">
</el-table-column>
<el-table-column prop="dictid" label="ID" width="220">
</el-table-column>
<el-table-column prop="dictvalue" label="类型" width="220">
</el-table-column>
<el-table-column prop="lng" label="经度" width="220">
</el-table-column>
<el-table-column prop="lat" label="纬度" width="220">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default
name: 'test',
data: function()
return
sourcedata: [],
checkboxData: [],
selectedData: [],
tableDataInfo:[]
,
methods:
checkall() // 全选
this.checkboxData.forEach(item =>
item.checked = true;
)
this.selectedData = []
,
checkno() // 全不选
this.checkboxData.forEach(item =>
item.checked = false;
)
this.selectedData = []
,
checkok() // 确定
// 获取Array [ Proxy, Proxy ]的target数据
var selected = JSON.parse(JSON.stringify(this.checkboxData.filter(item => item.checked)))
for(var i=0; i<selected.length; i++)
this.selectedData.push(JSON.parse(JSON.stringify(selected[i])).type) // 返回被选中的type,存入列表
console.log(JSON.parse(JSON.stringify(this.selectedData))) // 返回proxy,转列表
var p = this.selectedData[0]
// get请求 RequestParam传参
var data = this.$http.get('/geo/getRequestParam', params: p).then((response)=>
console.log("get请求 RequestParam传参", data);
this.tableDataInfo = response.data
console.log(response.data)
)
,
created()
// 【从后端获取过来的json数据】
this.$http.get("/geo/findAll").then((response)=>
this.sourcedata = response.data
this.tableDataInfo = response.data
// 原数据中没有checked字段,所以给每条数据添加checked以便后续操作
for(var i=0; i<this.sourcedata.length; i++)
this.sourcedata[i].checked = false
// console.log("this.sourcedata:", this.sourcedata)
this.tableDataInfo = this.sourcedata
)
// 【复选框中的树结构数据】
this.checkboxData = [
typeid: 0, type: '铁路',
typeid: 1, type: '高架桥',
]
</script>
<style scoped>
</style>
三、springboot部分
如果有需要,请移步到基于vscode创建SpringBoot项目,连接postgresql数据库 2 更简单_水w的博客-CSDN博客
目前项目的目录结构,如下所示:
1 Geo.java
创建实体类,
package com.example.demotwo.entity;
//@TableName("my_geo")
public class Geo
private int dictid;
private String dictvalue;
private String lng;
private String lat;
public String getDictvalue()
return dictvalue;
public void setDictvalue(String dictvalue)
this.dictvalue = dictvalue;
public String getLng()
return lng;
public void setLng(String lng)
this.lng = lng;
public String getLat()
return lat;
public void setLat(String lat)
this.lat = lat;
@Override
public String toString()
return "" + "dictid:" + dictid +
", dictvalue:" + dictvalue + '\\'' +
", lng:" + lng +
", lat:" + lat +
'';
2 GeoMapper.java
package com.example.demotwo.mapper;
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demotwo.entity.Geo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface GeoMapper
// 查询所有用户
@Select("select * from my_geo")
public List<Geo> find();
@Select("select * from my_geo WHERE dictvalue = #type")
public List<Geo> filter(@Param("type") String p);
3 application.properties配置文件
application.properties配置如下,其中Tomcat端口也可以不改,那就是8080,我是为了防止端口冲突,就随便改了一个。
- url在数据为postgresql时是jdbc:postgresql://localhost:5432/[数据库名]
- 后面是用户名和密码,我直接postgres登录的。
#??Tomcat??
server.port=8088
spring.datasource.url=jdbc:postgresql://localhost:5432/test-demo
spring.datasource.username=postgres
spring.datasource.password=123456
spring.datasource.driver-class-name=org.postgresql.Driver
4 GeoController.java
springboot接口如下:
- 使用get请求获得时,要用params传参数给后端,params会被添加到url的请求字符串中,就是常见的点击某个按钮路径后面会拼接一堆东西。
package com.example.demotwo.controller;
import com.example.demotwo.entity.Geo;
import com.example.demotwo.mapper.GeoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@CrossOrigin
public class GeoController
@Autowired
private GeoMapper geoMapper;
@GetMapping("/geo/findAll")
public List query()
List <Geo> list = geoMapper.find();
System.out.println(list); // 快捷键:so
return list;
/**
* 测试get请求RequestParam传参
*/
@GetMapping("/geo/getRequestParam")
public List testGetRequestParam(@RequestParam("p") String p)
System.out.println("result:" + p);
List <Geo> result = geoMapper.filter(p);
System.out.println(result); // 快捷键:so
return result;
四、测试结果
(1)启动sprintboot项目,效果如下图所示:
(2)然后,把前端vue项目文件夹,在vscode里面打开, 打开终端,然后vscode进入此文件夹的终端命令行窗口,执行如下指令运行该项目:
npm run dev
(3)最终,在浏览器打开http://localhost:5173/进行访问,效果如下图所示:
点击按钮之后,效果如下图所示:
Springboot Vue Login(从零开始实现Springboot+Vue登录)
一、简述
最近学习使用Vue实现前端后端分离,在Github上有一个很好的开源项目:mall,正所谓百看不如一练,自己动手实现了一个Springboot+Vue的登录操作,在此记录一下踩过的坑。
文章最后补充两端的GitHub代码,之所以放在最后,是因为文章写的很细致了,动手操作一下会更有帮忙,如果有很大出入可以比对原码,找找问题。
二、开发工具
VSCode
IDEA
Vue 的安装就不说了,有很多文章,但是Springboot+Vue整合的完整文章相对较少,所以我主要记录一下这两端整合时的内容。
(Vue安装后就会有 npm 或 cnpm,相应的介绍也不说了,Vue官网可查看)
-------------------------------Vue 开发-------------------------------
一、打开 cmd 创建 Vue 项目,并添加 Vue 依赖的框架:
1.创建 Vue 项目(进入自己想创建的文件夹位置,我放在 D:\\VSCodeWorkSpace),创建语句 vue create vue-spring-login-summed,方向键选择创建方式,我选择的默认
2.进入到创建的 Vue 项目目录,添加依赖框架:
cd vue-spring-login-summed (进入到项目根目录)
vue add element (添加 element,一个 element 风格的 UI 框架)
npm install axios (安装 axios,用于网络请求)
npm install vuex --save(安装 Vuex,用于管理状态)
npm install vue-router (安装 路由,用于实现两个 Vue 页面的跳转)
以上命令截图如下:
1)添加 Element
2)添加 axios
3)添加 Vuex
4)添加 路由
到此相关依赖的架包添加完毕,输入 code . 打开 VSCode
二、添加目录结构
在 VSCode 下看到 Vue 整体项目结构如下
现在需要创建相应功能的目录结构,进行分层开发,需要在 src 目录下创建下面几个目录
api (网络请求接口包)
router (路由配置包)
store (Vuex 状态管理包)
utils (工具包)
views (vue 视图包,存放所有 vue 代码,可根据功能模块进行相应分包)
创建后的目录结构如下
三、运行项目
现在可以运行项目了,在 VSCode 菜单栏依次选择:终端 —— 运行任务...
这里使用的是 serve 模式,即开发模式运行的项目
在浏览器输入:http://localhost:8080/
这是 Vue 默认的页面,代表项目创建成功了,在进行代码开发前,先贴上项目整体结构,防止不知道在哪创建
四、View 层代码编写
编写三个 vue 文件:login.vue(登录页面)、success.vue(登录成功页面)、error.vue(登录失败页面)
1.login.vue
代码如下(比较懒,直接从 mall 扒下来的代码,去掉了一些功能)
<template>
<div>
<el-card class="login-form-layout">
<el-form
autocomplete="on"
:model="loginForm"
ref="loginForm"
label-position="left"
>
<div style="text-align: center">
<svg-icon icon-class="login-mall" style="width: 56px;height: 56px;color: #409EFF"></svg-icon>
</div>
<h2 class="login-title color-main">mall-admin-web</h2>
<el-form-item prop="username">
<el-input
name="username"
type="text"
v-model="loginForm.username"
autocomplete="on"
placeholder="请输入用户名"
>
<span slot="prefix">
<svg-icon icon-class="user" class="color-main"></svg-icon>
</span>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
name="password"
:type="pwdType"
@keyup.enter.native="handleLogin"
v-model="loginForm.password"
autocomplete="on"
placeholder="请输入密码"
>
<span slot="prefix">
<svg-icon icon-class="password" class="color-main"></svg-icon>
</span>
<span slot="suffix" @click="showPwd">
<svg-icon icon-class="eye" class="color-main"></svg-icon>
</span>
</el-input>
</el-form-item>
<el-form-item style="margin-bottom: 60px">
<el-button
style="width: 100%"
type="primary"
:loading="loading"
@click.native.prevent="handleLogin"
>登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
export default
name: "login",
data()
return
loginForm:
username: "admin",
password: "123456"
,
loading: false,
pwdType: "password",
;
,
methods:
showPwd()
if (this.pwdType === "password")
this.pwdType = "";
else
this.pwdType = "password";
,
handleLogin()
this.$refs.loginForm.validate(valid =>
if (valid)
this.loading = true;
this.$store
.dispatch("Login", this.loginForm)
.then(response =>
this.loading = false;
let code = response.data.code;
if (code == 200)
this.$router.push(
path: "/success",
query: data: response.data.data
);
else
this.$router.push(
path: "/error",
query: message: response.data.message
);
)
.catch(() =>
this.loading = false;
);
else
// eslint-disable-next-line no-console
console.log("参数验证不合法!");
return false;
);
;
</script>
<style scoped>
.login-form-layout
position: absolute;
left: 0;
right: 0;
width: 360px;
margin: 140px auto;
border-top: 10px solid #409eff;
.login-title
text-align: center;
.login-center-layout
background: #409eff;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
margin-top: 200px;
</style>
2.success.vue
<template>
<div>
<h1>Welcome!msg</h1>
</div>
</template>
<script>
export default
data()
return
msg: this.$route.query.data
;
,
// data() //这种方式也可以
// return
// msg: null
// ;
// ,
// created()
// this.msg = this.$route.query.data;
//
</script>
3.error.vue
<template>
<div>
<h1>登录错误:msg</h1>
</div>
</template>
<script>
export default
// data()
// return
// msg: this.$route.query.data
// ;
// , //使用这种方式也可以显示 msg
data()
return
msg: null
;
,
created()
this.msg = this.$route.query.message;
;
</script>
五、路由
页面写好了,我们需要依次显示这三个页面,这里我们统一使用路由来管理显示页面,路由的官方文档见:vue 路由
本着先实践,后理解的码农学习方式。我们先使用路由显示三个页面后,再去理解Vue路由这个功能点。
1.创建路由配置文件
在刚才建立的 router 文件夹下创建一个 index.js 文件,内容如下
import Vue from 'vue' //引入 Vue
import VueRouter from 'vue-router' //引入 Vue 路由
Vue.use(VueRouter); //安装插件
export const constantRouterMap = [
//配置默认的路径,默认显示登录页
path: '/', component: () => import('@/views/login'),
//配置登录成功页面,使用时需要使用 path 路径来实现跳转
path: '/success', component: () => import('@/views/success'),
//配置登录失败页面,使用时需要使用 path 路径来实现跳转
path: '/error', component: () => import('@/views/error'), hidden: true
]
export default new VueRouter(
// mode: 'history', //后端支持可开
scrollBehavior: () => ( y: 0 ),
routes: constantRouterMap //指定路由列表
)
2.将路由添加到程序入口
路由配置文件写好,我们需要把他引入到 main.js 中,在项目的 src 目录根节点下,找到 main.js,添加内容如下:
import Vue from 'vue'
import App from './App.vue'
import './plugins/element.js'
import router from './router' //引入路由配置
Vue.config.productionTip = false
new Vue(
render: h => h(App),
router, //使用路由配置
).$mount('#app')
3.配置路由的出入口
现在路由已经完全引入到项目了,但是路由还需要一个出入口,这个出入口用来告诉路由将路由的内容显示在这里。上面 main.js 配置的第一个 vue 显示页面为 App.vue ,因此我们修改 App.vue 内容如下
<template>
<div id="app">
<!-- 路由的出入口,路由的内容将被显示在这里 -->
<router-view/>
</div>
</template>
<script>
export default
name: 'App'
</script>
<router-view/> 就是显示路由的出入口。
现在保存 App.vue 文件后,当前项目会被重新装载运行,在刚才浏览的界面就会看到登录界面如下:
4.路由跳转
在 login.vue 中可以使用 this.$router.push(path: "路径") 来跳转到指定路径的路由组件中,下面是通过路由跳转到 error.vue 与 success.vue的代码
this.$router.push(path: "/success"); //跳转到成功页
或
this.$router.push(path: "/error"); //跳转到失败页
六、使用 Vuex + Axios 方式进行网络请求
1.Axios
axios 是一个网络请求构架,官方推荐使用这种方式进行 http 的请求。
1) 在 utils 包下封装一个请求工具类 request.js
import axios from 'axios' //引入 axios
import baseUrl from '../api/baseUrl' //使用环境变量 + 模式的方式定义基础URL
// 创建 axios 实例
const service = axios.create(
baseURL: baseUrl, // api 的 base_url
timeout: 15000, // 请求超时时间
)
export default service
这里的 baseUrl 涉及 Vue CLI3 的环境变量与模式的概念,见:Vue 环境变量和模式(设置通用baseUrl)
2) 登录请求接口 API
在 api 文件夹下,创建一个登录API文件:login.js
import request from '@/utils/request' //引入封装好的 axios 请求
export function login(username, password) //登录接口
return request( //使用封装好的 axios 进行网络请求
url: '/admin/login',
method: 'post',
data: //提交的数据
username,
password
)
2.使用 Vuex 封装 axios
Vuex 是一个状态管理构架,官方文档:Vuex
1)封装 Vuex 中的 module
在 store 文件夹下创建一个 modules 文件夹,然后在此文件夹下创建一个 user.js 文件
import login from '@/api/login'//引入登录 api 接口
const user =
actions:
// 登录
Login( commit , userInfo) //定义 Login 方法,在组件中使用 this.$store.dispatch("Login") 调用
const username = userInfo.username.trim()
return new Promise((resolve, reject) => //封装一个 Promise
login(username, userInfo.password).then(response => //使用 login 接口进行网络请求
commit('') //提交一个 mutation,通知状态改变
resolve(response) //将结果封装进 Promise
).catch(error =>
reject(error)
)
)
,
export default user
这里的代码值得解释一下:官方文档对应:Vuex actions
1.首先引入 login 接口,之后使用登录接口进行网络请求。
2.定义一个 名为 Login 的 action 方法,Vue 组件通过 this.$store.dispatch("Login") 调用
3.Promise,这个类很有意思,官方的解释是“store.dispatch
可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch
仍旧返回 Promise”。这话的意思组件中的 dispatch 返回的仍是一个 Promise 类,因此推测 Promise 中的两个方法 resolve() 与 reject() 分别对应 dispatch 中的 then 与 catch。
2)创建 Vuex
在 store 文件夹下创建一个 index.js 文件
import Vue from 'vue' //引入 Vue
import Vuex from 'vuex' //引入 Vuex
import user from './modules/user' //引入 user module
Vue.use(Vuex)
const store = new Vuex.Store(
modules:
user //使用 user.js 中的 action
)
export default store
3) 将 Vuex 添加到 main.js 文件
修改之前的 main.js 文件如下:
import Vue from 'vue'
import App from './App.vue'
import './plugins/element.js'
import router from './router' //引入路由配置
import store from './store' //引入 Vuex 状态管理
Vue.config.productionTip = false
new Vue(
render: h => h(App),
router, //使用路由配置
store //使用 Vuex 进行状态管理
).$mount('#app')
重新运行项目,在 Chrome 浏览器中进入调试模式,点击登录按钮
可以看到有发送一个 8088 端口的请求,至此 Vue 端的所有代码已经完成。
-------------------------------Springboot 开发-------------------------------
项目创建就不提了,网上有很多,只要使用 Spring Assistant 创建就好。
整体目录结构如下
1.在 application.yml 修改端口号
不要和 Vue 在一个 8080 端口上:
server:
port: 8088
2.解决跨域问题
这里有一个跨域问题,即 Vue 使用 8080 端口,要访问 8088 端口的服务器,会报错。错误信息如下:
Access to XMLHttpRequest at 'http://localhost:8088/admin/login' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这个问题在 Vue 端或在 Springboot 端处理都可以,我在 Springboot 端处理的,写一个 CorsConfig 类内容如下,不要忘了 @Configuration 注解。
@Configuration
public class CorsConfig
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()); // 4
return new CorsFilter(source);
3.IErrorCode 接口
Java 版本
public interface IErrorCode
long getCode();
String getMessage();
Kotlin 版本
interface IErrorCode
fun getCode(): Long
fun getMessage(): String
4.CommonResult 类
Java 版本
public class CommonResult<T>
private long code;
private String message;
private T data;
protected CommonResult()
protected CommonResult(long code, String message, T data)
this.code = code;
this.message = message;
this.data = data;
/**
* 成功返回结果
*
* @param data 获取的数据
*/
public static <T> CommonResult<T> success(T data)
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
/**
* 成功返回结果
*
* @param data 获取的数据
* @param message 提示信息
*/
public static <T> CommonResult<T> success(T data, String message)
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
/**
* 失败返回结果
*
* @param errorCode 错误码
*/
public static <T> CommonResult<T> failed(IErrorCode errorCode)
return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
/**
* 失败返回结果
*
* @param message 提示信息
*/
public static <T> CommonResult<T> failed(String message)
return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
/**
* 失败返回结果
*/
public static <T> CommonResult<T> failed()
return failed(ResultCode.FAILED);
/**
* 参数验证失败返回结果
*/
public static <T> CommonResult<T> validateFailed()
return failed(ResultCode.VALIDATE_FAILED);
/**
* 参数验证失败返回结果
*
* @param message 提示信息
*/
public static <T> CommonResult<T> validateFailed(String message)
return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
/**
* 未登录返回结果
*/
public static <T> CommonResult<T> unauthorized(T data)
return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
/**
* 未授权返回结果
*/
public static <T> CommonResult<T> forbidden(T data)
return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
public long getCode()
return code;
public void setCode(long code)
this.code = code;
public String getMessage()
return message;
public void setMessage(String message)
this.message = message;
public T getData()
return data;
public void setData(T data)
this.data = data;
Kotlin 版本
class CommonResult<T>
var code: Long = 0
var message: String? = null
var data: T? = null
constructor(code: Long, message: String, data: T?)
this.code = code
this.message = message
this.data = data
companion object
/**
* 成功返回结果
* @param data 获取的数据
*/
fun <T> success(data: T): CommonResult<T>
return CommonResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data)
/**
* 成功返回结果
* @param data 获取的数据
* @param message 提示信息
*/
fun <T> success(data: T, message: String): CommonResult<T>
return CommonResult(ResultCode.SUCCESS.getCode(), message, data)
/**
* 失败返回结果
* @param errorCode 错误码
*/
fun <T> failed(errorCode: IErrorCode): CommonResult<T>
return CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null)
/**
* 失败返回结果
* @param message 提示信息
*/
fun <T> failed(message: String): CommonResult<T>
return CommonResult<T>(ResultCode.FAILED.getCode(), message, null)
/**
* 失败返回结果
*/
fun failed(): CommonResult<Any>
return failed(ResultCode.FAILED)
/**
* 参数验证失败返回结果
*/
fun validateFailed(): CommonResult<Any>
return failed(ResultCode.VALIDATE_FAILED)
/**
* 参数验证失败返回结果
* @param message 提示信息
*/
fun <T> validateFailed(message: String): CommonResult<T>
return CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null)
/**
* 未登录返回结果
*/
fun <T> unauthorized(data: T): CommonResult<T>
return CommonResult(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data)
/**
* 未授权返回结果
*/
fun <T> forbidden(data: T): CommonResult<T>
return CommonResult(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data)
5.ResultCode 枚举
Java 版本
public enum ResultCode implements IErrorCode
SUCCESS(200, "操作成功"),
FAILED(500, "操作失败"),
VALIDATE_FAILED(404, "参数检验失败"),
UNAUTHORIZED(401, "暂未登录或token已经过期"),
FORBIDDEN(403, "没有相关权限");
private long code;
private String message;
private ResultCode(long code, String message)
this.code = code;
this.message = message;
public long getCode()
return code;
public String getMessage()
return message;
Kotlin 版本
enum class ResultCode(private val code: Long, private val message: String) : IErrorCode
SUCCESS(200, "操作成功"),
FAILED(500, "操作失败"),
VALIDATE_FAILED(404, "参数检验失败"),
UNAUTHORIZED(401, "暂未登录或token已经过期"),
FORBIDDEN(403, "没有相关权限");
override fun getCode(): Long
return code
override fun getMessage(): String
return message
6.User类
Java 版本
public class User
private int id;
private String username;
private String password;
public int getId()
return id;
public void setId(int id)
this.id = id;
public String getUsername()
return username;
public void setUsername(String username)
this.username = username;
public String getPassword()
return password;
public void setPassword(String password)
this.password = password;
Kotlin 版本
data class User(
val id: Int,
val username: String,
val password: String)
7.LoginController 类
Java 版本
@RestController
public class LoginController
@RequestMapping(value = "/admin/login", method = RequestMethod.POST)
public CommonResult login(@RequestBody User user)
if (user.getUsername().equals("admin") && user.getPassword().equals("123456"))
return CommonResult.success("admin");
else
return CommonResult.validateFailed();
Kotlin 版本
@RestController //此注解是 @ResponseBody 和 @Controller 的组合注解,可返回一个 JSON
class LoginController
@RequestMapping(value = ["/admin/login"], method = [RequestMethod.POST])
fun admin(@RequestBody user: User): CommonResult<*>
return if (user.username == "admin" && user.password == "123456")
CommonResult.success("admin")
else
CommonResult.validateFailed()
启动两端程序
输入正确的账号密码
输入错误的账号密码
七、GitHub源码地址
vue端:https://github.com/xiaojinlai/vue-spring-login-summed
Java端:https://github.com/xiaojinlai/vue-login-java
Java端 - Kotlin版本:https://github.com/xiaojinlai/vue-login-kotlin
注:Kotlin 版本只是我本人用习惯了 Kotlin,就功能而言与Java是一样的。大家如果不喜欢可以不用理会,如果有感兴趣的可以看看,Kotlin 是 Google 推出的一种简洁性语言,主推在 Android 上,用习惯后还是蛮喜欢的。学习起来也不难,内容也不多,推荐一个学习 Kotlin 的网址:https://www.kotlincn.net/docs/reference/
以上是关于vue3+SpringBoot+postgresql 项目前后端传参的主要内容,如果未能解决你的问题,请参考以下文章