前后端联调

前言

使用Idea快速生成后端页面与VsCode生成的前端页面进行数据交互。

1.使用Spring+Maven快速构建后端项目

创建一个Maven项目取名为Login_Test,打包方式选择War,下一步添加依赖项

Web/Spring Web

SQL/MyBatis FrameWord+MySQL Driver

三个依赖包

time03.jpg

手动导入mavne依赖的pom.xml配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>Login_Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Login_Test</name>
<description>Login_Test</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
</dependencies>

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

</project>

2.根据三层架构构建出文件包

time04.jpg

2.1实体类entity

创建User实体,包含Username和password两个字段名和get、set方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.example.login_test.entity;

/**
* @Classname User
* @Description TODO
* @Version 1.0.0
* @Date 2024/5/16 13:47
* @Created by kd_13
*/
public class User {
private String userName;
private String passWord;

@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", passWord='" + passWord + '\'' +
'}';
}

public String getPassWord() {
return passWord;
}

public void setPassWord(String passWord) {
this.passWord = passWord;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public User(String userName, String passWord) {
this.userName = userName;
this.passWord = passWord;
}

public User() {
}
}

2.2数据库持久层mapper

在mapper包下创建UserMapper持久类,这里采用@Select注解的形式开发,也可以参考之前的MyBatis文章中使用xml类方式实现

1
2
3
4
5
6
7
8
import com.example.login_test.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
@Select(" select UserName,PassWord from user where UserName=#{username}")
User getUserByName(String username);
}

2.3服务层service和实现impl

创建抽象类UserService,包含查询用户对象的方法

1
2
3
4
5
6
import com.example.login_test.entity.User;
import org.springframework.stereotype.Service;
@Service
public interface UserService {
boolean isUser(User user);
}

实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import com.example.login_test.entity.User;
import com.example.login_test.mapper.UserMapper;
import com.example.login_test.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public boolean isUser(User user) {
String username = user.getUserName();
String password = user.getPassWord();
User finduser = userMapper.getUserByName(username);
if(finduser == null){
return false;
}else if (password.equals(finduser.getPassWord())){
return true;
}else {
return false;
}
}
}

2.4数据传输JSON格式化

为了使得页面之间传输的数据更加的简洁规范化,这里采用JSON传递数据

其中格式为:

1
2
3
4
5
{
status:“#状态码”,
msg:”#成功or失败“,
result:"参数集"
}

在实体类中entity中创建Return对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.example.login_test.entity;

import java.util.Map;

/**
* @Classname Return
* @Description TODO
* @Version 1.0.0
* @Date 2024/5/16 14:16
* @Created by kd_13
*/
public class Return {
private String status;
private String msg;
private Map<String,String> result;
public static Return buildSuccess(){
Return r = new Return();
r.setStatus("200");
r.setMsg("success");
return r;
}
public static Return buildFalse(){
Return r = new Return();
r.setStatus("400");
r.setMsg("false");
return r;
}
public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}

public Map<String, String> getResult() {
return result;
}

public void setResult(Map<String, String> result) {
this.result = result;
}

public Return() {
}

public Return(String status, String msg, Map<String, String> result) {
this.status = status;
this.msg = msg;
this.result = result;
}

}

2.5控制交互层controller

创建交互层对传入的数据进行加工判断和返回到前端页面中,其中@PostMapping(“/login”)表示需要以post请求的方式向../login页面传递参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.example.login_test.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.login_test.entity.Return;
import com.example.login_test.entity.User;
import com.example.login_test.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* @Classname UserContoller
* @Description TODO
* @Version 1.0.0
* @Date 2024/5/16 14:12
* @Created by kd_13
*/
@Controller
@CrossOrigin
public class UserContoller {
@Autowired
private UserService userService;
@PostMapping("/login")
@ResponseBody
public Return login(@RequestBody JSONObject params){
String username = params.getString("username");
String password = params.getString("password");
User user = new User(username,password);
Boolean result = userService.isUser(user);
if(result){
return Return.buildSuccess();
}else {
return Return.buildFalse();
}
}
}

2.6数据库配置链接

由于导入的是MySql数据库对象,这里创建一个新的数据库名为page,新建一张表为user表,包两个字段username和password对象,都为vacher类型notnull,username为主键。以下为创建表的语句,并且向其中插入一条数据(admin,root)。

1
2
3
4
5
6
7
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`UserName` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL,
`PassWord` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL,
PRIMARY KEY (`UserName`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;
INSERT INTO `user` VALUES ('admin', 'root');

在resources中创建application.properties对象存储数据库配置数据

1
2
3
4
5
6
7
8
spring.datasource.url=jdbc:mysql://localhost:3306/page?useUnicode=true&characterEncoding=utf8
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456

logging.level.com.example.login_test.mapper:debug

server.port=8088

logging.level.com.example.login_test.mapper:debug的作用是在控制台输出mapper对象执行中的sql语句,

server.port=8088的作用更改项目的端口号为8088(8080端口在前端Vue项目启动后被占用,会自动配置为8081).

2.7项目测试

在login_test包下创建WoniuCsdnSpringbootApplication项目启动包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.example.login_test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @Classname WoniuCsdnSpringbootApplication
* @Description TODO
* @Version 1.0.0
* @Date 2024/5/16 16:01
* @Created by kd_13
*/
@SpringBootApplication
public class WoniuCsdnSpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(WoniuCsdnSpringbootApplication.class,args);
}
}

点击运行后项目在8088端口运行使用http://localhost:8088/login对登入接口访问

time05.jpg

需要注意的是,我们在浏览器中直接访问这个页面是无法通过post请求传递参数的,这里可以在在网上寻找到向后端发送请求的测试项目,这里使用ApiPost这款软件进行演示:

在左边新建接口后,按照图中填写JSON数据和请求方式

time06.jpg

点击发送后我们得到后端返回的JSON格式的数据

time07.jpg

此时观察maven项目的控制台可以看到穿线sql语句的请求

time08.jpg

此时后端项目全部编写完成。

3.与前端按钮功能绑定完成交互

3.1前端请求转发

将前端js数据中数据发送的地址填写,这里为了简化开发直接将地址写入js文件,这种写法是不可靠的 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
login:function(e){
this.$axios({
url:"http://localhost:8088/login",
method: "POST",
data:{
username:this.username,
password:this.password,
},
})
.then((res)=> {
console.log(res.data);
if(res.data.status=="200"){
}else{
alert("登入失败");
}
})
.catch((err) =>{
console.log(err);
});
}
}
};

启动项目在页面中向后端发送登入校验

3.2跨域问题

在点击登入后,F12开启控制台后发现输出Access to XMLHttpRequest at ‘‘ from origin ‘‘ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

这一类的红色报错,这一类是指不同链接之间通信产生的不安全的跨域问题

2999487-20240110214156934-2026844454.png

这类问题百度跨域问题如何解决即可,这里提供一种解决办法:

在login_test目录下创建CorsConfig.java文件,这里将所有的访问源都默认允许,也是不推荐的,重新编译启动后端程序后,跨域问题解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.example.login_test;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

// 当前跨域请求最大有效时长。这里默认1天
private static final long MAX_AGE = 24 * 60 * 60;

@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
corsConfiguration.setMaxAge(MAX_AGE);
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}

控制台输出信息:

time09.jpg