Tb0_图书管理系统保姆教程(一)
基于Vue+SpringBoot+Mybatis的图书管理系统
图书管理系统保姆教程(一)
需求分析
技术架构
前端:使用Vue+axios+elemenet框架实现
后端:SpringBoot+Mybatis
背景知识介绍
环境准备
IDE
- VSCode
- IntelliJ IDEA
使用 CLI 搭建 Vue.js 项目
利用 Vue CLI(或写成 vue-cli,即 Vue 脚手架)搭建项目
- 安装 NPM(Node Package Manager),是一个NodeJS包管理和分发工具 。所以直接安装 Node.js,访问官网 https://nodejs.org/en/下载。
- 安装 Vue CLI
npm install -g vue-cli
或者
npm install -g @vue/cli
- 测试验证(略)
使用IntelliJ IDEA 创建Spring Boot项目
- IntelliJ IDEA 专业版自带Spring插件
- IntelliJ IDEA 社区版本,下载Spring Boot Helper
- 使用maven的方法配置项目
- 使用spring网站配置
创建项目
后端项目创建
博主直接使用spring网站配置的spring工程,直接使用idea打开运行。
后端运行效果(这个是正常运行的标志,虽然还没有加前端)
后端开发
用户类
java/demo/src/main/java/com/example/demo/User.java
这个类是有问题的!!!解决方法在后面
package book;
public class User {
int ID;
String userame;
String passWord;
public int getId() {
return ID;
}
public void setId(int id) {
this.ID = id;
}
public String getuserName() {
return userame;
}
public void setuserName(String userName) {
this.userame = userName;
}
public String getPassword() {
return passWord;
}
public void setPassword(String password) {
this.passWord = password;
}
}
相应控制类
java/demo/src/main/java/com/example/demo/LoginController.java
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
@Controller
public class LoginController {
@CrossOrigin(origins = "*", allowedHeaders = "*")
@PostMapping(value = "/api/login")
@ResponseBody
public Result login(@RequestBody User requestUser) {
String username = requestUser.getUsername();
if (!Objects.equals("admin", username) || !Objects.equals("123123", requestUser.getPassword())) {
String message = "账号密码错误";
return new Result(400);
} else {
return new Result(200);
}
}
@CrossOrigin
@PostMapping(value = "/api/test")
public int test() {
return 400;
}
}
后端配置
java/demo/src/main/resources/application.properties添加 内容(初始应该是空白的,后期还要配置数据库等)
server.port=8888
前端页面开发
后端创建完成,需开发一个前端显示界面。
登录页面:src\components\Login.vue
<template>
<div>
用户名:<input type="text" v-model="loginForm.username" placeholder="请输入用户名"/>
<br><br>
密码: <input type="password" v-model="loginForm.password" placeholder="请输入密码"/>
<br><br>
<button v-on:click="login">登录</button>
</div>
</template>
<script>
export default {
name: 'Login',
data () {
return {
loginForm: {
username: '',
password: ''
},
responseResult: []
}
},
methods: {
login () {
this.$axios
.post('/login', {
username: this.loginForm.username,
password: this.loginForm.password
})
.then(successResponse => {
if (successResponse.data.code === 200) {
this.$router.replace({path: '/index'})
}
})
.catch(failResponse => {
})
}
}
}
</script>
跳转页面:src\components\AppIndex.vue
<template>
<div>
Hello World!
</div>
</template>
<script>
export default {
name: 'AppIndex'
}
</script>
<style scoped>
</style>
前端配置
设置反向代理
src\main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
// 设置baseURL,8888是后端端口号,前端请求默认发送到baseURL的地址
// var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8888/api'
Vue.prototype.$axios = axios// 全局注册,其他组件中通过调用 this.$axios 发送数据
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
这儿会报错:
ailed to compile with 1 errors 上午11:32:03
This dependency was not found:
* axios in ./src/main.js
To install it, you can run: npm install --save axios
Error from chokidar (D:\): Error: EBUSY: resource busy or locked, lstat 'D:\DumpStack.log.tmp'
Error from chokidar (D:\node_modules): Error: EBUSY: resource busy or locked, lstat 'D:\DumpStack.log.tmp'
这儿英文提示的很清楚,需安装axios。
配置页面路由
src\router\index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Login from '@/components/Login'
import AppIndex from '@/components/AppIndex'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/AppIndex',
name: 'AppIndex',
component: AppIndex
}
]
})
跨域支持
config\index.js
修改proxyTable
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://localhost:8888',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
},
运行程序
同时运行前端和后端项目,访问 localhost:8080/#/login
,输入用户名 admin
,密码 123123
后端未启动的情况
后端启动报错
Access to XMLHttpRequest at 'http://localhost:8888/api/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.
xhr.js:264
POST http://localhost:8888/api/login net::ERR_FAILED
? 这是常见的跨域资源共享(CORS)问题 。
? 浏览器限制了跨域请求,只有在服务端设置了响应头 Access-Control-Allow-Origin 时,才允许跨域请求。 这个错误是由于浏览器的跨域安全策略导致的。
CORS原理
跨域资源共享(CORS)是一种机制,是W3C标准。它允许浏览器向跨源服务器,发出XMLHttpRequest或Fetch请求。整个CORS通信过程都是浏览器自动完成的,不需要用户参与。
CORS的工作原理是:
- 浏览器先根据同源策略对前端页面和后台交互地址做匹配,若同源,则直接发送数据请求;若不同源,则发送跨域请求。
- 当浏览器需要向跨源服务器发送请求时,会在请求头中添加一些额外的字段,这些字段告诉服务器请求来自哪个源(即来源域名、协议和端口)。
- 服务器接收到请求后,会检查请求头中的这些字段,确认是否接受来自该源的请求。如果接受,服务器会正常处理请求并返回数据;如果不接受,服务器可能会返回一个错误响应。
CORS的配置通常包括以下几个字段:
- Access-Control-Allow-Origin:指定哪些来源的网页可以访问该资源。可以是具体的来源域名,也可以是通配符’*'表示任何来源都可以访问。
- Access-Control-Allow-Methods:指定允许的前端发起请求的方法类型。
- Access-Control-Allow-Headers:指定允许的前端请求头字段。
- Access-Control-Allow-Credentials:指定是否允许携带凭据(如cookies、HTTP认证等)。
- Access-Control-Max-Age:指定预检请求的有效期(以秒为单位),即在多长时间内无需发送预检请求。
需要注意的是,使用CORS的前提是浏览器必须支持这个功能,并且服务器端也必须同意这种"跨域"请求。因此实现CORS的关键是服务器。
解决方法
将这几个类直接改到DemoApplication包下。
如图:
博主的问题是把LoginController类、Result类、User类都放到自己创建的book目录下了。途中的book目录已经删除。book目录需时demo的子目录。
遇到跨域问题的同学可以尝试检查一下自己的
control类所在的包需符合“controller类必须是Application的所在包的类或者子包的类” ,启动类Application是Controller文件的上一级,只有这样,项目启动时才能扫描加载到controller类。
登录后不跳转
问题描述
两个页面单独登录可以登录
http://localhost:8080/#/login
http://localhost:8080/#/index
输入用户密码,页面不跳转
问题分析
单独页面都可以登录说明页面没有问题;
输入用户名密码,在login函数中,修改返回结果都是200后。页面可以正常跳转。说明前端代码正常。
public Result login(@RequestBody User requestUser) {
String username = requestUser.getUsername();
if (!Objects.equals("admin", username) || !Objects.equals("123123", requestUser.getPassword())) {
String message = "账号密码错误";
return new Result(200);
} else {
return new Result(200);
}
}
在方法中打断点,查看变量,username获取为空,密码是正确的。
按照原来的逻辑,应该返回new Result(400)
,确实不会跳转。
检查发现
设置两个断点,一个是setUserName
函数,一个是setPassword
函数。结果只进入setPassword
解决方法
点击右上角警告提示
警告已经写了这两个函数未使用,那么直接修改名称。修改名称后,还是不跳转。修改函数setUserName
改成setUsername
。此处犯了两个拼写错误,都是泪。
至此完成前后端正常登录跳转功能。
演示结果:
为空,密码是正确的。
按照原来的逻辑,应该返回new Result(400)
,确实不会跳转。
检查发现
设置两个断点,一个是setUserName
函数,一个是setPassword
函数。结果只进入setPassword
解决方法
点击右上角警告提示
警告已经写了这两个函数未使用,那么直接修改名称。修改名称后,还是不跳转。修改函数setUserName
改成setUsername
。此处犯了两个拼写错误,都是泪。
至此完成前后端正常登录跳转功能。
演示结果:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!