King of Bots - 配置git环境和项目搭建
当前进度代码:https://git.acwing.com/yuezi2048/kob/-/tree/282cd25a1251eee9384c1ec97ff9889bf79ea4fa
一、游戏系统设计框架
我们的框架树里面,每个孩子都是对应一个导航栏(链接)
前后端分离的优越性:一个后端可以对应多个前端。
二、git基础应用
为什么用git?
- 代码存档(commit),可以回滚出历史代码
- 同步不同设备
怎么用git?
- 首先用git bash在home目录下输入ssh-keygen 生成密钥,找到公钥,放入平台的SSH密钥
- 创建项目文件KOB,使用git init 生成.git隐藏文件夹,再新建一个readme.md
- 然后我们如果想commit 流程如下
- ps:我们应该要去掉--global,以此来保证每个项目不用这个信息
- 我们后续提交代码就这固定的操作就OK
- 接收方面, 我们可以使用git pull拉取最新的代码
三、后端创建
3.1 基本概念和环境搭建
我们首先明确前后端分离的概念
那先明确大家都在说的前后端到底是什么?他就是给前端服务的,他本质上其实就是函数的调用,前端需要什么页面就输入相关内容,那后端就给他输出返回,好比上菜,后端就是厨师,服务员就是前端。
前后端分离是什么?就是首先web端返回给用户,后续再通过后端在对应的地方渲染出来(本质就是字符串拼接)
每个链接本质上就是函数调用,我们具体的实现是使用到了controller来控制返回哪些页面。
引申 MVC:C是controller负责向用户返回数据 V就是html M是model 数据库
我们在idea新建一个项目,选择Spring,这里用的是1.8版本的
选择依赖Spring Web,注意Spring版本要低于7才行 否则不支持了
我们改一下端口防止和vue默认的8080端口冲突
运行main文件后就可以启动了
3.2 前后端不分离
我们建立一个controller包用来作后端函数,pk模块 排行榜 用户中心。
比如我们新建一个pk界面,/controller/pk/IndexController.java
-
我们建立一个注解Controller
-
注解 RequestMapping是对Web资源配置请求的映射
- 我们映射的是/pk/index/ 目录 对应的 index()函数 => 返回templates里面的pk/index.html
package com.zjxu.kob.backend.controller.pk;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/pk/")
public class IndexController {
@RequestMapping("index/")
public String index() {
return "pk/index.html"; // 返回pk页面的路径 resources/templates/pk/index.html
}
}
- index.html文件我们是放在了resources/templates/pk/index.html中
- 图片是在resources/static下,我们引用就是在其/imge/img.png
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<img src="/image/img.png" alt="">
</div>
</body>
</html>
3.3 前后端分离
比如说我们后续需要返回数据BotInfoController
- 这里的注解就是RestController了
- 类似地,加上RequestMapping映射
- 我们不止可以返回所谓的数据,还可以返回列表、字典这些,还可以嵌套
package com.zjxu.kob.backend.controller.pk;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/pk/")
public class BotInfoController {
// 可以返回字符串、列表、字典
@RequestMapping("getbotinfo/")
public Map<String, String> getBotInfo(){
List<Map<String, String>> list = new LinkedList<>();
Map<String, String> bot1 = new HashMap<>();
bot1.put("name", "tiger");
bot1.put("rating", "1500");
Map<String, String> bot2 = new HashMap<>();
bot2.put("name", "apple");
bot2.put("rating", "1800");
list.add(bot1);
list.add(bot2);
return bot1;
}
}
四、前端创建
我们在当前后端目录下创建前端
不用git初始化,使用的是vue3
我们创建一个web 和acppp项目,需要vue-router和vuex插件,具体细节看我的vue学习笔记
web端装一个jquery和bootstrap
我们可以把hash去掉,让url里的#号去掉
我们把默认的view都可以删掉
4.1 前端ajax访问后端
- script写法都是固定的,我们export若干对象(我们理解为vue创建了一个新的实例),里面有name和setup()函数入口 注意最后return
- 在setup()里我们定义bot_name和bot_rating变量,并且使用ajax来获取
- url是我们需要访问的地址
- type是访问类型,有get获取 post提交 delete删除 put修改
- success 是获取成功后的操作 也可以简写成success(resp) { } ,setup(){ }同理
- template前端界面使用{{ }}来取得ref响应式变量
- 我们在CSS里引用了assets里的背景图片 使用cover 100%填充 @是当前目录的根目录
<template>
<div>
<div>Bot昵称:{{ bot_name }}</div>
<div>Bot战力:{{ bot_rating }}</div>
</div>
</template>
<script>
import $ from 'jquery';
import { ref } from 'vue';
export default{
name: "App",
setup: () => {
let bot_name = ref("");
let bot_rating = ref("");
$.ajax({
url: "http://127.0.0.1:3000/pk/getbotinfo/",
type: "get",
success: resp => {
console.log(resp);
bot_name.value = resp.name;
bot_rating.value = resp.rating;
}
});
return {
bot_name,
bot_rating
}
}
}
</script>
<style>
body {
background-image: url("@/assets/background.png");
background-size:cover;
}
</style>
4.2 解决禁止跨域问题
我们回忆一下计网的知识,我们通信的一个端点实际上是ip+端口号,那么我们 127.0.0.1:8080访问 127.0.0.1:3000 那么就是跨域访问,这里是被后端默认禁止了,我们在后端那边 加一个跨域配置文件CorsConfig就可以了。
package com.zjxu.kob.backend.config;
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Configuration
public class CorsConfig implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
String origin = request.getHeader("Origin");
if(origin!=null) {
response.setHeader("Access-Control-Allow-Origin", origin);
}
String headers = request.getHeader("Access-Control-Request-Headers");
if(headers!=null) {
response.setHeader("Access-Control-Allow-Headers", headers);
response.setHeader("Access-Control-Expose-Headers", headers);
}
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
那么这就是我们目前进度的最终效果了。
五、前后端交互的逻辑总结
实际上用户所看到的界面里的源码,浏览器已经全部把我们的代码全部打包到app.js里面了
具体的运作可以大致总结如下:
- 用户Client访问前端网址,我们前端会通过js里的setup()函数访问向后端backend服务器发送请求
- 后端是怎么运作的?比如他执行看Controller下的/pk/路径下的getbotInfo/路径下的对应的getBotInfo()函数
- 函数里面通过返回json对象,里面有两个属性,分别是name和rating
- 后端将结果resp返回给前端,前端success()后将resp赋值给我们的ref可变响应式变量