Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
vue.js官网 ==> https://cn.vuejs.org/
vue.js菜鸟教程学习文档 ==> https://www.runoob.com/vue2/vue-tutorial.html
Swagger 官网 ==> https://swagger.io/
Swagger 2简介
它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。
话不多说开始撸码
先导入pom.xml依赖
<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.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.5.RELEASEversion>
<relativePath/>
parent>
<groupId>com.zhaoleigroupId>
<artifactId>jpa-swagger-vueartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>jpa-swagger-vuename>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.8.0version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.8.0version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
(注意导入swagger2相关的依赖)
pojo实体类
package com.zhaolei.jpaswaggervue.pojo;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
/**
* @author 15579
* 2019/6/3 14:09
* 文件说明:Student实体类
*/
@Data
@Table
@Entity //数据库没有此实体类对应的表就会自动生成
public class Student implements Serializable {
//自动增长
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column
private String name;
@Column
private String sex;
@Column
private Integer gradeId;
}
Dao层
package com.zhaolei.jpaswaggervue.dao;
import com.zhaolei.jpaswaggervue.pojo.Student;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
/**
* @author 15579
* 2019/6/3 14:21
* 文件说明:StudentDao层
*/
@Repository
public interface StudentDao extends JpaRepository<Student,Integer>, JpaSpecificationExecutor<Student>{
//nativeQuery =true 表示这是原生SQL
@Query(value = "SELECT * from student where `name` like concat('%',?,'%')",nativeQuery = true)
Page<Student> findLikeNameByPage(String name, Pageable pageable);
}
Service层
package com.zhaolei.jpaswaggervue.service;
import com.zhaolei.jpaswaggervue.pojo.Student;
import org.springframework.data.domain.Page;
import java.util.List;
/**
* @author 15579
* 2019/6/4 14:26
* 文件说明:
*/
public interface StudentService {
/**
* 新增学生信息
* @param student
* @return
*/
Student save(Student student);
/**
* 修改
* @param student
* @return
*/
Student update(Student student);
/**
* 删除学生
* @param id
*/
void deleteStu(Integer id);
/**
* 分页查询
* @param pageNum
* @param pageSize
* @return
*/
Page<Student> findByPage(Integer pageNum, Integer pageSize, Student student);
/**
* 根据编号查询
* @param id
* @return
*/
Student findStudentById(Integer id);
}
impl层
package com.zhaolei.jpaswaggervue.service.impl;
import com.zhaolei.jpaswaggervue.dao.StudentDao;
import com.zhaolei.jpaswaggervue.pojo.Student;
import com.zhaolei.jpaswaggervue.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author 15579
* 2019/6/4 14:27
* 文件说明:
*/
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
/**
* 新增学生信息
*
* @param student
* @return
*/
@Override
public Student save(Student student) {
return studentDao.save(student);
}
/**
* 修改
*
* @param student
* @return
*/
@Override
public Student update(Student student) {
return studentDao.save(student);
}
/**
* 删除学生
*
* @param id
*/
@Override
public void deleteStu(Integer id) {
studentDao.deleteById(id);
}
/**
* 分页查询
*
* @param pageNum
* @param pageSize
* @return
*/
@Override
public Page<Student> findByPage(Integer pageNum, Integer pageSize,Student student) {
if(pageNum==null||pageNum==0){
pageNum=1;
}
if(pageSize==null||pageSize==0){
pageSize=2;
}
// 第一种方式模糊查询并且分页
// ExampleMatcher matcher = ExampleMatcher.matching()
// .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())//模糊查询匹配开头,即{username}%
// .withIgnorePaths("sex")
// .withIgnorePaths("id");
// Example example = Example.of(student, matcher);
PageRequest of=PageRequest.of(pageNum-1,pageSize);
//第一种方式
// Page page=studentDao.findAll(example,of);
//第二种方式模糊查询并且分页
Page<Student> page=studentDao.findLikeNameByPage(student.getName()==null?"":student.getName(),of);
return page;
}
/**
* 根据编号查询
*
* @param id
* @return
*/
@Override
public Student findStudentById(Integer id) {
return studentDao.findById(id).get();
}
}
controller层
package com.zhaolei.jpaswaggervue.controller;
import com.zhaolei.jpaswaggervue.pojo.Student;
import com.zhaolei.jpaswaggervue.service.StudentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
/**
* @author 15579
* 2019/6/3 14:28
* 文件说明:Student控制层
*/
@RestController
@Api(value = "Swagger2 api 注释 Student控制层")
public class StuController {
@Autowired
private StudentService studentService;
//根据条件分页查询
@GetMapping("/findByPage")
@ApiOperation(value = "分页查询",notes = "根据姓名模糊查询并分页")
public Object findByPage(Integer pageNum, Integer pageSize, Student student){
if(pageNum==null||pageNum<=0){
pageNum=1;
}
Page<Student> page = studentService.findByPage(pageNum, pageSize,student);
return page;
}
//根据ID删除学生
@DeleteMapping("/deleteStu")
@ApiOperation(value = "删除",notes = "根据ID删除学生")
public int delteStu(@RequestParam("id") Integer id){
System.out.println(id);
try {
studentService.deleteStu(id);
return 1;
}catch (Exception e){
return 0;
}
}
//修改学生信息
@PutMapping("/updateStu")
@ApiOperation(value = "修改",notes = "修改学生信息")
public Object updateStu(@RequestBody Student student){
Student updStudent = studentService.update(student);
return updStudent;
}
//新增学生信息
@PostMapping("/addStu")
@ApiOperation(value = "新增",notes = "新增学生信息")
public Object addStu(@RequestBody Student student){
System.out.println(student.getName());
Student save = studentService.save(student);
return save;
}
//跳转至编辑页面
@GetMapping("/gotoEdit")
@ApiOperation(value = "跳转至编辑页面",notes = "根据编号判断是修改还是新增")
public String gotoEdit(Integer id,Model model){
if(id!=null){
//根据ID查询学生信息并显示在页面
Student student = studentService.findStudentById(id);
model.addAttribute("stu",student);
}
return "edit";
}
}
然后编写swagger2的配置类
package com.zhaolei.jpaswaggervue.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.zhaolei.jpaswaggervue.controller"))//改成你项目的controller层路径
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring Boot中使用Swagger2实现前后端分离开发")
.description("此项目只是练习如何实现前后端分离开发的小Demo")
.termsOfServiceUrl("https://blog.csdn.net/weixin_44530530")
.contact("***")
.version("1.0")
.build();
}
}
注意:需要在SpringBoot项目的应用程序入口类中开启swagger2如下所示
package com.zhaolei.jpaswaggervue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@EnableSwagger2 //开启swagger2 api接口文档
public class JpaSwaggerVueApplication {
public static void main(String[] args) {
SpringApplication.run(JpaSwaggerVueApplication.class, args);
}
}
让后就可以启动我们的项目我的端口号是8080:浏览器输入
http://localhost:8080/swagger-ui.html
然后会出现如下页面就代表你的swagger2 ui 的api接口已经生成好了
后端代码基本已经编写完毕接下来使用写前段页面接收后端返回的json数据
我前段使用的框架是vue.js 使用的软件是HbuilderX
<html>
<head>
<meta charset="utf-8" />
<title>title>
head>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js">script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js">script>
<body>
<div id="app">
<label>姓名:label>
<input type="text" name="likeName" v-model="likeName" />
<input type="button" v-on:click="findByPage(1)" value="查询" />
<table border="1" cellspacing="1" cellpadding="20">
<tr>
<th>编号th>
<th>姓名th>
<th>性别th>
<th>年级th>
<th>操作th>
tr>
<template v-for="stu in stuList">
<tr>
<td>{{stu.id}}td>
<td>{{stu.name}}td>
<td>{{stu.sex}}td>
<td>{{stu.gradeId}}td>
<td>
<a href="javascript:void(0)" v-on:click="del(stu.id)">删除a>
<a href="javascript:void(0)" v-on:click="edit(stu)">编辑a>
td>
tr>
template>
table>
<template>
<table>
<tr>
<td>
编号:<input type="text" name="id" v-model="student.id" placeholder="编号无需自己填写" readonly="readonly" />
td>
<td>
姓名:<input type="text" name="name" v-model="student.name" />
td>
<td>
性别:<input type="text" name="sex" v-model="student.sex" />
td>
<td>
年级:<input type="text" name="gradeId" v-model="student.gradeId" />
td>
<td>
<input type="button" value="保存" v-on:click="add(student)" />
td>
tr>
table>
template>
<a href="javascript:void(0)" v-on:click="findByPage(1)">首页a>
<a href="javascript:void(0)" v-on:click="findByPage(page.number)">上一页a>
<a href="javascript:void(0)" v-on:click="findByPage(page.number+2)">下一页a>
<a href="javascript:void(0)" v-on:click="findByPage(page.totalPages)">尾页a>
当前第<span v-text="page.number+1">span>页/共{{page.totalPages}}页
div>
body>
<script>
var app = new Vue({
el: "#app",
data: {
likeName:"",
student: {
id: "",
name: "",
sex: "",
gradeId: ""
},
stuList: [],
page:{}
},
methods: {
findByPage: function(pageNum) {
var _this = this;
var likeName=this.likeName;
if(pageNum!=null||pageNum!=''){
if(pageNum>_this.page.totalPages){
pageNum=_this.page.totalPages
}
}
axios.get('http://localhost:8080/findByPage', {
params: {
pageNum: pageNum,
name: likeName
}
})
.then(function(response) {
console.log(response.data)
_this.page=response.data;
_this.stuList = response.data.content;
})
.catch(function(error) { // 请求失败处理
console.log(error);
});
},
del: function(id) {
var _this = this;
console.log(id)
let delId = id;
axios.delete('http://localhost:8080/deleteStu', {
params: {
id: delId
}
})
.then(function(response) {
console.log(response.data)
if (response.data == 1) {
_this.findByPage();
alert("删除成功");
}
})
.catch(function(error) { // 请求失败处理
console.log(error);
});
},
add: function(student) {
var _this = this;
console.log(student.id);
if (student.id != null&&student.id !='') {
var stu = JSON.stringify(student);
axios.put('http://localhost:8080/updateStu',stu, {
headers: {
'Content-Type':'application/json;charset=utf-8'
}
})
.then(function(response) {
alert("修改成功")
_this.findByPage();
_this.student.id=null;
_this.student.name=null;
_this.student.sex=null;
_this.student.gradeId=null;
})
.catch(function(error) { // 请求失败处理
console.log(error);
});
} else {
axios.post('http://localhost:8080/addStu',student, {
headers: {
'Content-Type':'application/json;charset=utf-8'
}
})
.then(function(response) {
alert("新增成功")
_this.findByPage();
_this.student.name=null;
_this.student.sex=null;
_this.student.gradeId=null;
})
.catch(function(error) { // 请求失败处理
console.log(error);
});
}
},
edit: function(student) {
this.student = student;
}
},
// 钩子 在Vue创建时就运行
created: function() {
this.findByPage();
}
})
script>
html>
注意:
保存ctrl+r选择浏览器运行 然后会发现页面数据出不来按F12会发现报错
出现这个错误的原因是因为没有考虑到跨域问题,所以还需要在后端SpringBoot项目添加一个解决跨域问题的配置类代码如下:
package com.zhaolei.jpaswaggervue.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
//跨域配置
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
//重写父类提供的跨域请求处理的接口
public void addCorsMappings(CorsRegistry registry) {
//添加映射路径
registry.addMapping("/**")
//放行哪些原始域
.allowedOrigins("*")
//是否发送Cookie信息
.allowCredentials(true)
//放行哪些原始域(请求方式)
.allowedMethods("GET", "POST", "PUT", "DELETE")
//放行哪些原始域(头部信息)
.allowedHeaders("*")
//暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
.exposedHeaders("Header1", "Header2");
}
};
}
}
然后重启项目并刷新页面
数据出来了!问题完美解决so easy!打完收功!
最后附上后端git仓库地址:https://gitee.com/riven666/jpa-swagger-vue