Springboot 结合 Vue 进行本地接口联调

这是一个简单的 Springboot 项目,仅供学习,前端使用的是经过 webpack 编译打包之后的静态文件。


简介

继上一篇 《整合 vue、viewui、axios、mock 和 webpack 的简单案例》之后,前端的 VUE 项目可以开展本地开发、编译打包的工作了。打包之后的静态资源文件(包括 HTML,CSS,JS等资源)若需要被外部用户访问则必须部署到服务器上。目前市面上的 Web 服务器非常多,无论哪种 Web 服务器,这些静态资源都能被正常地部署。

在 Java 领域,很多工程师都知道 Springboot,它内置Tomcat、Jetty和Undertow服务器的支持。很多时候只需使用合适的“Starter”来获取完全配置的实例就能轻松构建一个独立应用。

本文以 Springboot 结合 Vue 进行本地接口联调 为主题介绍了一个简单的案例,根据这个项目可以清晰知道一个简单的 Springboot 项目的基础结构和前后端联调的基础内容,并可以在此基础上做的任何拓展。源码地址:https://github.com/marvelousness/springboot-simple-web


选择 Springboot 的版本

很多文章中都提倡使用 IDEA 或者 MyEclipse 等工具来快速构建一个项目。因为本文的目的是为了学习,故而不走捷径,按照 Springboot 的文档一步步来构建一个简单的 Springboot 项目即可。Springboot 官方网址是:https://spring.io/projects/spring-boot/

从 Springboot 的官方介绍中可以知道,目前最新版本是 2.2.5。根据经验,一般刚发布的版本可能存在一些问题,故而选择上一个 GA 版本,即 2.1.3 版本。如图所示:
选择 2.1.3 版本
点击上图中所示版本右边的 Reference Doc. 可跳转到对应版本的文档,即:https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/

这里需要说明下图中的版本号后缀的含义:

  1. SNAPSHOT 为快照版本
  2. PRE 为预发布版本
  3. GA 为官方正式版

Springboot 项目之所以能够很快地被构建和部署的很重要的原因是运用 Maven 或 Gradle 的依赖管理将很多常用的模块(也就是 jar)组织在一起,当需要使用的时候,直接依赖某些指定的包就能快速引入依赖的其它组件。如果想查看 2.1.13.RELEASE 这个版本的 Springboot 到底将那些模块组织到一起了,可以通过点击文档的最下方的 Dependency versions 跳转到 https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/appendix-dependency-versions.html 进行查看。

Appendix F. Dependency versions
The following table provides details of all of the dependency versions that are provided by Spring Boot in its CLI (Command Line Interface), Maven dependency management, and Gradle plugin. When you declare a dependency on one of these artifacts without declaring a version, the version listed in the table is used.


配置 Maven 依赖

为一个项目配置依赖需要根据项目实际需求。而本例是一个简单的 Springboot 项目,故而,只需要满足以下三个要求即可:

  1. 提供基础的 Restful 数据接口
  2. 通过单元测试检测数据接口
  3. 以 HTML 作为视图解析器

spring-boot-starter-web 提供了嵌入式 Web 容器和 MVC 架构等基础设施。它是一个 Springboot 项目开发 Web 应用的基础依赖模块。而为项目进行单元测试则需要依赖 spring-boot-starter-test

前端的 Vue 项目最后打包后生成的静态资源需要被一个 HTML 文档引用才能进行页面的渲染。故而,依赖一个视图解析器向前端响应一个 HTML 文档作为当前这个 Springboot 项目的界面尤为重要。Springboot 支持的视图解析器非常多,这里不展开做讨论。本例推荐使用 thymeleaf 作为项目的视图解析器,它是适用于 Web 和独立环境的现代服务器端 Java 模板引擎。需要引入的依赖是:spring-boot-starter-thymeleaf

关于 thymeleaf 的更多介绍可以移步它的官方网站:https://www.thymeleaf.org/。另外,通过阅读 Springboot 的文档中的 Appendix F. Dependency versions 章节并查找 thymeleaf 模块可以发现,Springboot 依赖的 thymeleaf 的版本是 3.0.11.RELEASE,故而,根据这个版本信息,可以到官网查看对应版本的说明文档。
即:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
当然,感兴趣的朋友还可以下载它的 PDF 版本进行阅读:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.pdf

所以,该项目的核心依赖是:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<version>2.1.3.RELEASE</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
	<version>2.1.3.RELEASE</version>
</dependency>

这时候就可以新建一个 java 类作为项目的入口文件,测试下项目是否能正常启动。

SpringbootApplicationEntrance.java

@SpringBootApplication
public class SpringbootApplicationEntrance {
	public static void main(String[] args) {
		SpringApplication.run(SpringbootApplicationEntrance.class, args);
	}
}

如果在启动过程中出现异常,提示找不到 ch.qos.logback.core.joran.spi.JoranException 的话,可参考 排错笔记 —— java.lang.NoClassDefFoundError: ch/qos/logback/core/joran/spi/JoranException 的解决方案。

在 maven 项目中,如果需要将项目打包编译为 jar 需要指定命令:

mvn package

一般来讲,maven 的命令是可以串联一起使用的,推荐的做法是:清理 > 编译 > 打包,即:

mvn clean compile package

可以在项目中使用 maven-compiler 插件约束项目使用的 jdk 版本,如下所示:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>3.1</version>
	<configuration>
		<source>1.8</source>
		<target>1.8</target>
		<encoding>UTF-8</encoding>
	</configuration>
</plugin>

该项目被 maven 编译打包之后,会得到一个 jar 文件,可以通过 java -jar simple-web.jar 命令执行并启动该项目。其中 simple-web 是生成的 jar 文件的名称。但是,在 Springboot 项目中,使用该命令启动的时候,可能会出现如下提示:

simple-web.jar 中没有主清单属性

这时候需要使用到 spring-boot-maven 插件来指定项目的入口类,重新编译打包后即可正常启动 Springboot 项目。插件配置如下:

<plugin>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-maven-plugin</artifactId>
	<configuration>
		<fork>true</fork>
		<mainClass>org.marvelousness.springboot.simple.SpringbootApplicationEntrance</mainClass>
		<layout>JAR</layout>
	</configuration>
</plugin>

这时候,编译打包的命令就是:

mvn clean compile package spring-boot:repackage

当然,也可以在 POM 文件中指定依赖包的仓库的地址和插件的仓库地址,于是,得到最后的 POM 文件的配置如下:

<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>org.marvelousness.springboot</groupId>
	<artifactId>simple-web</artifactId>
	<version>1.0.0</version>
	<packaging>jar</packaging>
	<name>简单 springboot 项目</name>
	<description>简单 springboot 项目</description>
	<organization>
		<url>https://github.com/marvelousness/springboot-simple-web</url>
		<name>marvelousness</name>
	</organization>
	<properties>
		<java.version>1.8</java.version>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring-boot.version>2.1.3.RELEASE</spring-boot.version>
	</properties>
	<dependencies>
		<!-- <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.3</version> </dependency> -->
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.1.3</version>
		</dependency>
		<!-- <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-access</artifactId> <version>1.1.3</version> </dependency> -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<version>${spring-boot.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>${spring-boot.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
			<version>${spring-boot.version}</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>simple-web</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>${maven.compiler.source}</source>
					<target>${maven.compiler.target}</target>
					<encoding>${project.build.sourceEncoding}</encoding>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<fork>true</fork>
					<mainClass>org.marvelousness.springboot.simple.SpringbootApplicationEntrance</mainClass>
					<layout>JAR</layout>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<repositories>
		<repository>
			<id>nexus-aliyun</id>
			<name>Nexus aliyun</name>
			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
		</repository>
		<repository>
			<id>activiti-repos2</id>
			<name>Activiti Repository 2</name>
			<url>https://app.camunda.com/nexus/content/groups/public</url>
		</repository>
		<repository>
			<id>springsource-repos</id>
			<name>SpringSource Repository</name>
			<url>http://repo.spring.io/release/</url>
		</repository>
		<repository>
			<id>central-repos</id>
			<name>Central Repository</name>
			<url>http://repo.maven.apache.org/maven2</url>
		</repository>
		<repository>
			<id>central-repos1</id>
			<name>Central Repository 2</name>
			<url>http://repo1.maven.org/maven2/</url>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<url>https://repo.spring.io/snapshot</url>
		</pluginRepository>
		<pluginRepository>
			<id>spring-milestones</id>
			<url>https://repo.spring.io/milestone</url>
		</pluginRepository>
	</pluginRepositories>
</project>

源码

首先看下该项目的文件目录结构:

src
 ├─main
 │  ├─org.marvelousness.springboot.simple
 │  │								├─configurer
 │  │								│	└ WebMvcBasicConfigurer.java
 │  │								├─controller
 │  │								│	├ HomeController.java
 │  │								│	└ TestController.java
 │  │								└ SpringbootApplicationEntrance.java
 │  └─resources
 │      ├─static
 │      │  ├─css
 │      │  ├─images
 │      │  └─js
 │      ├─templates
 │      │  ├ index.debug.html
 │      │  └ index.html
 │      └─ application.yml
 └─test
     └─java
         └─org.marvelousness.springboot.simple.test
 												└ TestSpringbootApplication.java

项目中一共五个 java 文件,一个测试类,一个入口类,一个配置类和两个控制器类。当然,还有一个配置文件 application.yml。接下来分别看下它们的代码:

项目入口类

SpringbootApplicationEntrance.java 是项目的入口类,代码如下:

/**
 * 项目入口
 * @author marvelousness@foxmail.com
 * @time 2020-03-15 18:11
 */
@SpringBootApplication
public class SpringbootApplicationEntrance {
	public static void main(String[] args) {
		SpringApplication.run(SpringbootApplicationEntrance.class, args);
	}
}

项目配置类

WebMvcBasicConfigurer.java 是项目的配置类,该类的作用是为了注册静态资源的处理器,主要作用如下:

  1. /favicon.ico 指定了具体的文件的位置为 src/main/resources/static/images/favicon_128.ico ,如果不指定,则默认显示的是 springboot 的图标,也就是那个绿色的叶子。
  2. /statics 路径映射到 src/main/resources/static/ 目录,使得目录中的文件在访问的时候都会以 /statics 作为前缀。例如存在 src/main/resources/static/css/app.css 资源,在默认情况下,可以通过 /css/app.css 可以访问,做了这样的调整之后,就得通过 /statics/css/app.css 来访问。
/**
 * 基础配置类
 * 
 * @author marvelousness@foxmail.com
 * @time 2020-03-16 17:12
 */
@EnableWebMvc
@Configuration
public class WebMvcBasicConfigurer implements WebMvcConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		// 设置 favicon.ico 的实际文件地址
		registry.addResourceHandler("/favicon.ico").addResourceLocations("classpath:/static/images/favicon_128.ico");
		// 将所有的静态资源定位到 /statics 路径下
		registry.addResourceHandler("/statics/**").addResourceLocations("classpath:/static/");
	}

}

提供 Restful 数据接口的控制器类

TestController.java 是项目提供 Restful 数据接口的控制器类。提供一个映射 GET 请求的接口和一个映射 POST 请求的接口,用来给前端提供 JSON 数据。因为在类上的@RequestMapping 注解赋予了两个值,故而,类中的每个映射的接口都有两个请求地址,具体的请求地址包括:

  1. [GET] /test/list
  2. [GET] /data/list
  3. [POST] /test/save
  4. [POST] /data/save
/**
 * 测试数据控制器
 * 
 * @author marvelousness@foxmail.com
 * @time 2020-03-17 11:11
 */
@RestController
@RequestMapping(value = { "test", "data" })
public class TestController {
	/**
	 * 通过 Springboot 提供的随机 uuid 来获取随机字符串
	 */
	@Value("${random.uuid}")
	private String randomString;

	/**
	 * 测试处理 GET 请求返回数据
	 * 
	 * @param page 页码数
	 * @param size 页项数
	 * @return
	 */
	@GetMapping("list")
	public ResponseEntity<List<Map<String, Object>>> list(Integer page, Integer size) {
		List<Map<String, Object>> list = new ArrayList<>();
		// 初始化参数 size
		Random random = new Random(System.currentTimeMillis());
		while (size == null || size < 0 || size > 1000) {
			size = random.nextInt();
		}
		for (int i = 0; i < size; i++) {
			Map<String, Object> map = new HashMap<>(10);
			map.put("boolean", random.nextBoolean());
			map.put("double", random.nextDouble());
			map.put("float", random.nextFloat());
			map.put("integer", random.nextInt());
			map.put("long", random.nextLong());
			if (!StringUtils.isEmpty(randomString)) {
				map.put("uuid", randomString);
			}
			list.add(map);
		}
		return new ResponseEntity<List<Map<String, Object>>>(list, HttpStatus.OK);
	}

	/**
	 * 测试处理 POST 请求返回数据
	 * 
	 * @param instance JSON示例对象
	 * @return
	 */
	@PostMapping("save")
	public ResponseEntity<?> save(@RequestBody Map<String, Object> instance) {
		if (instance == null || instance.isEmpty()) {
			return new ResponseEntity<String>("invalid request data", HttpStatus.INTERNAL_SERVER_ERROR);
		}
		Long id = null;
		// 获取主键
		{
			Object object = instance.get("id");
			if (object != null) {
				try {
					id = Long.valueOf(object.toString());
				} catch (NumberFormatException e) {
					// e.printStackTrace();
				}
			}
		}
		if (id != null) {
			if (id > 0) {
				// 大于零的数据认为是 update
				return new ResponseEntity<String>("success", HttpStatus.OK);
			} else {
				// 小于零的数据认为是 insert
				return new ResponseEntity<String>("success", HttpStatus.OK);
			}
		}
		return new ResponseEntity<String>("failure", HttpStatus.INTERNAL_SERVER_ERROR);
	}
}

首页视图的控制器类

HomeController.java 是项目的首页视图的控制器类。该类的目的是为了响应一个 HTML 文档。为了与上一篇 《整合 vue、viewui、axios、mock 和 webpack 的简单案例》中的项目进行联调,这里做了一个小小的改动:就是通过读取配置文件来判断是否需要进行本地接口联调

研发思路及流程图:

首页视图说明

在之前的前端案例的文章中可以知道,webpack 在 development 模式下将会提供一个本地 web 服务器使得代码的修改在浏览器上实时可见。而这个本地 Web 服务器监听 7070 端口,使得开发者能在浏览器中看到对应的网页,并且修改代码后实时通知浏览器端代码更新内容。详细内容移步 整合 vue、viewui、axios、mock 和 webpack 的简单案例

实际上,前端的这个本地 Web 服务器提供的正是一系列经过打包之后的静态资源文件,在该前端项目中,实际上就是 http://localhost:7070/app.js,当修改了前端代码后,Webpack 将会自动更新该 js 文件。同时,会使用 Socket 通知浏览器,代码已经发生变更,这时候,前端就会重新请求 app.js 文件进而更新页面。所以,只需要将该 js 文件引入到对应的 HTML 文档中来就能实现前后端联调了。

先看控制器的代码:

/**
 * 首页控制器
 * 
 * @author marvelousness@foxmail.com
 * @time 2020-03-15 18:18
 */
@Controller
public class HomeController {

	@Value("${debug:false}")
	private Boolean debug;

	/**
	 * 前端项目在开发模式下的网络地址
	 */
	@Value("${nodejs.host:}")
	private String nodejsHost;
	/**
	 * 前端项目的入口
	 */
	@Value("${nodejs.entrance:}")
	private String nodejsEntrance;

	/**
	 * 首页视图
	 */
	@RequestMapping("")
	public ModelAndView index() {
		boolean dev = isDev();
		ModelAndView mv = new ModelAndView(dev ? "index.debug" : "index");
		mv.addObject("host", dev ? nodejsHost : "");
		mv.addObject("entrance", dev ? nodejsHost.concat(nodejsEntrance) : "");
		return mv;
	}

	/**
	 * 判断是否是开发模式
	 * 
	 * @return
	 */
	private boolean isDev() {
		if (!Boolean.TRUE.equals(debug)) {
			return false;
		}
		return !(StringUtils.isEmpty(nodejsHost) || StringUtils.isEmpty(nodejsEntrance));
	}

}

再来看下配置文件的配置信息:

debug: false
server:
   port: 8080
spring:
   application:
      name: simple-web
   thymeleaf:
      cache: false
      prefix: classpath:/templates/
      suffix: .html
      encoding: UTF-8
      mode: HTML
nodejs:
   host: http://localhost:7070
   entrance: /app.js

将流程图、 HomeController.javaapplication.yml 结合起来看,流程图中的 前端项目在开发模式下的网络地址 指的就是 nodejs.host 配置项,而 前端项目的入口 指的就是 nodejs.entrance 配置项。所以,只要配置文件中的 debug 设置为 true,首页返回的是 index.debug 视图,否则返回的是 index 视图。因为项目的视图解析器使用的是 thymeleaf,所以,根据配置文件可知:index.debug 视图对应的 HTML 文档正是src/main/resources/templates/index.debug.html,而 index 视图对应的 HTML 文档正是src/main/resources/templates/index.html。接下来比对象这两个文件:

index.debug.html

<!DOCTYPE HTML>
<html lang="zh-CN">

	<head>
		<title>vue-view-design</title>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-status-bar-style" content="default" />
		<meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui" />
		<link rel="shortcut icon" sizes="48x48" href="/statics/images/logo.png" />
		<link rel="apple-touch-icon" sizes="120x120" href="/statics/images/logo.png" />
		
		<!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->
        
		<!-- <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script> -->

	<body>
		<div id="app"></div>
		<script type="text/javascript" th:src="${entrance}"></script>
	</body>

</html>

index.html

<!DOCTYPE HTML>
<html lang="zh-CN">

	<head>
		<title>vue-view-design</title>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-status-bar-style" content="default" />
		<meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui" />
		<link rel="shortcut icon" sizes="48x48" href="/statics/images/logo.png" />
		<link rel="apple-touch-icon" sizes="120x120" href="/statics/images/logo.png" />
		
		<!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->
        
		<!-- <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script> -->
		<link href="/statics/css/vendors.css" rel="stylesheet">
		<link href="/statics/css/app.css" rel="stylesheet">
	</head>

	<body>
		<div id="app"></div>
		<script type="text/javascript" src="/statics/js/vendors.js"></script>
		<script type="text/javascript" src="/statics/js/app.js"></script>
	</body>

</html>

index.html 文件正是前端项目打包之后生成的,而 index.debug.html 则只根据 ${entrance} 来确定需要引入什么 js 文件,而根据 HomeController.java 可知,该 js 文件是 http://localhost:7070/app.js,故而,当配置文件的 debug 设置为 true 时,首页控制器响应的网页文档应该是:

首页文档
关注下地址栏和文档底部的 js,就相当于是在 http://localhost:8080/ 域的网页引入了 http://localhost:7070/ 域的 js,而当前端项目中调用接口 /data/list 的时候,就不再是请求 7070 站点了,而是 8080 站点。在前端项目的 src/mock/index.js 文件中,指定了端口是 7070 才 mock 。故而,达到了能让后端开发进行本地接口联调的同时也不影响前端开发的本地调试。

单元测试类

TestSpringbootApplication .java 是项目的单元测试类。作为一个后端开发工程师,为自己写的每个接口做单元测试是一个不错的习惯。在本类中,对 //test/list/test/save 三个接口进行了单元测试。可以通过 JUnit 执行也可以通过 mvn test 命令来执行。

/**
 * 测试 Springboot 项目的控制器
 * @author marvelousness@foxmail.com
 * @time 2020-03-16 13:00
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestSpringbootApplication {

	@Autowired
	private WebApplicationContext wac;

	private MockMvc mvc;

	@Before
	public void setUp() {
		mvc = MockMvcBuilders.webAppContextSetup(wac).build();
	}

	/**
	 * 测试首页控制器是否正常
	 */
	@Test
	public void testHome() throws Exception {
		MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("");
		builder.contentType(MediaType.TEXT_HTML);

		ResultActions actions = mvc.perform(builder);
		actions.andExpect(MockMvcResultMatchers.status().isOk());

		MvcResult result = actions.andReturn();
		MockHttpServletResponse response = result.getResponse();
		String string = response.getContentAsString();

		System.out.println(string);
	}

	/**
	 * 测试接口处理 GET 请求的接口是否正常返回数据
	 */
	@Test
	public void testGetDataList() throws Exception {
		MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/test/list");
		builder.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
		builder.param("size", "30");

		ResultActions actions = mvc.perform(builder);
		actions.andExpect(MockMvcResultMatchers.status().isOk());

		MvcResult result = actions.andReturn();
		MockHttpServletResponse response = result.getResponse();
		String string = response.getContentAsString();

		System.out.println(string);
	}

	/**
	 * 测试接口处理 POST 请求的接口是否正常提交数据
	 */
	@Test
	public void testPostData() throws Exception {
		MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/test/save");
		builder.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
		// 组装提交的参数
		{
			JSONObject json = new JSONObject();
			json.put("id", 1000);
			json.put("name", "tom");
			json.put("weight", 45.3);
			builder.content(json.toString());
		}

		ResultActions actions = mvc.perform(builder);
		// actions.andExpect(MockMvcResultMatchers.status().isOk());

		MvcResult result = actions.andReturn();
		MockHttpServletResponse response = result.getResponse();
		String string = response.getContentAsString();

		System.out.println(string);
	}

}

小结

很多 springboot 项目都是在一个简单的小案例的基础上进行不断的拓展,在本例中,以一个简单的 springboot 项目为核心,与将前端的项目进行联调。当然,有很多项目前后端联调的方式是通过跨域联调,跨域联调的内容会在后面的文章再展开讨论。最后附上效果图:

联调效果图 —— 首页
首页
联调效果图 —— 接口调试
接口测试

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot结合Vue权限管理是一种常见的前后端分离的权限管理方案。在这种方案中,后端使用Spring Boot框架来搭建RESTful API接口,前端使用Vue框架来实现用户界面。 首先,后端需要实现用户认证和权限控制的逻辑。可以使用Spring Security框架来实现用户认证和鉴权。通过配置Spring Security,可以限制用户访问某些API接口或页面。可以根据不同的用户角色,设置不同的权限。 其次,前端需要实现用户登录和权限控制的界面。可以使用Vue框架来实现用户登录界面和权限管理界面。用户登录时,前端会发送登录请求到后端,后端会验证用户身份,并生成Token返回给前端。前端将Token保存在本地,并在每次请求时将Token携带在请求头中,以实现用户身份的验证。 前端还需要根据用户角色和权限来控制页面的显示与操作。可以根据用户权限,在页面渲染前进行权限判断,只显示用户具备权限的页面内容和操作按钮。 最后,前后端需要进行协同开发和测试。前端开发人员和后端开发人员需要进行密切合作,在制定API接口和权限设计时进行沟通和协商。前后端开发人员还需要进行联合测试,确保权限管理功能的正常运行。 综上所述,Spring Boot结合Vue可以实现灵活高效的权限管理。后端负责用户认证和权限控制的逻辑,前端负责用户界面和用户操作的控制。通过这种方式,可以提高开发效率和用户体验,同时也保障了系统的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值