【摘要】 工作不是很饱和的情况下,就有时间去研究一下技术上的东西,然后打算写一篇比较长的啰嗦的文章来记录一下一、准备工作首先要有一台云服务器(其他替代的能作为服务器的设备也行,最好是linux),然后我是提前配置好了java环境,OPENJDK或者ORACLEJDK都行,这两个的区别自行百度吧。二、后端开发新建一个springboot项目,然后可以用默认的起步依赖就行,我是多加了一个swagger的依…
工作不是很饱和的情况下,就有时间去研究一下技术上的东西,然后打算写一篇比较长的啰嗦的文章来记录一下
一、准备工作
首先要有一台云服务器(其他替代的能作为服务器的设备也行,最好是linux),然后我是提前配置好了java环境,OPENJDK或者ORACLEJDK都行,这两个的区别自行百度吧。
二、后端开发
新建一个springboot项目,然后可以用默认的起步依赖就行,我是多加了一个swagger的依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
目录结构如下所示
下面是SwaggerConfig类的代码,不过不用也没有啥影响
package com.zxc.springtest001.config;
import io.swagger.annotations.ApiOperation;
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//托管spring
@EnableSwagger2//开启swagger功能
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket( DocumentationType.SWAGGER_2 )
// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
.apiInfo( apiInfo() )
// 设置哪些接口暴露给Swagger展示
.select()
// (第一种方式)扫描所有有注解的api,用这种方式更灵活
.apis( RequestHandlerSelectors.withMethodAnnotation( ApiOperation.class ) )
// (第二种方式)扫描指定包中的swagger注解
//.apis(RequestHandlerSelectors.basePackage(“com.zxc.springtest001.controller”))
// (第三种方式)扫描所有
//.apis(RequestHandlerSelectors.any())
.paths( PathSelectors.any() )
.build();
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo() {
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title( “标题:应用API文档” )
// 描述
.description( “描述:向前端提供应用的ResultFul风格接口文档” )
// 作者信息
.contact( “zhx” )
// 版本
.version( “版本号:” + “V1.0.0” )
.build();
}
}
InterfaceUtils和ResultVo就是封装了一下返回值的结构,没啥好说的
package com.zxc.springtest001.utils;
import com.zxc.springtest001.enums.ResultEnum;
import com.zxc.springtest001.vo.ResultVo;
public class InterfaceUtil {
public static ResultVo success() {
return new ResultVo(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getInfo(), null);
}
public static ResultVo success(Object data) {
return new ResultVo(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getInfo(), data);
}
public static ResultVo error(String info) {
return new ResultVo(ResultEnum.SERVICE_ERROR.getCode(), info, null);
}
public static ResultVo error(ResultEnum resultEnum) {
return new ResultVo(resultEnum.getCode(), resultEnum.getInfo(), null);
}
public static ResultVo error(ResultEnum resultEnum, String info) {
return new ResultVo(resultEnum.getCode(), info, null);
}
public static ResultVo error(Integer code, String info) {
return new ResultVo(code, info, null);
}
}
package com.zxc.springtest001.vo;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel
public class ResultVo<T> {
private Integer code;
private String info;
private T data;
}
主要逻辑就在Controller中,其实也是非常简单的两个方法,由于重点在部署,所以逻辑直接写在Controller中,但是实际开发中千万不要这样做
package com.zxc.springtest001.controller;
import com.zxc.springtest001.utils.InterfaceUtil;
import com.zxc.springtest001.vo.ResultVo;
import com.zxc.springtest001.vo.GetVo;
import com.zxc.springtest001.vo.TableList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
@CrossOrigin
@Api(“测试方法controller”)
public class TestController {
@ApiOperation(value = “get方法请求”)
@GetMapping(“/getList”)
public ResultVo getList(String param){
if (param != null){
GetVo getVo = new GetVo();
getVo.setUserName(“yiyuzz”);
return InterfaceUtil.success(getVo);
}
return InterfaceUtil.error(“传入参数为空”);
}
@ApiOperation(value = “post方法请求”)
@PostMapping(“/postList”)
public ResultVo<List<TableList>> postList(){
List<TableList> tableList = new ArrayList<>();
tableList.add(new TableList(“张三”,”男”,”呜呜呜呜呜”));
tableList.add(new TableList(“李四”,”女”,”啊啊啊啊啊”));
tableList.add(new TableList(“王五”,”男”,”嗷嗷嗷嗷嗷”));
return InterfaceUtil.success(tableList);
}
}
然后配置文件里面写一下端口就行了,后端就写完了
三、前端开发
前端对我这种菜鸟来说还是太生疏了点,o(╥﹏╥)o。
框架是用的Vue,所以要先搭好环境,然后编译器的话IDEA、WebStorm、VScode都行,我是直接用vue脚手架创建了一个项目,然后执行npm install命令加载依赖,npm run dev 启动项目
要做修改的地方主要有两个
一是页面上要有一个向后端发送get请求的操作,还有一个发送post请求的操作
二是要通过axios发送请求包,接收响应包,并且携带参数,这里也涉及到跨域请求的问题,后面细说
先附上一个目录结构吧,要修改或者新增的红色标注
main.js文件如下所示,elementui和axios先引入
import Vue from ‘vue’
import App from ‘./App’
import router from ‘./router’
import ElementUI from ‘element-ui’
import ‘element-ui/lib/theme-chalk/index.css’
import axios from ‘axios’
import VueAxios from ‘vue-axios’
Vue.config.productionTip = false
Vue.use(ElementUI);
Vue.use(VueAxios,axios);
/* eslint-disable no-new */
new Vue({
el: ‘#app’,
router,
render: h => h(App)
})
新建一个组件,然后把根路由指过去
import Vue from ‘vue’
import Router from ‘vue-router’
import FirstPage from ‘@/components/FirstPage’
Vue.use(Router)
export default new Router({
routes: [
{
path: ‘/’,
name: ‘FirstPage’,
component: FirstPage
}
]
})
然后新建一个http.js文件设置axios的请求拦截和响应拦截,其实这个拦截器只是做了简单的错误处理,然后设置了一下默认的baseURL(这个是访问后端地址的基础),还有要注意的是import是从axios依赖中导入的,然后拦截器写完了之后用export导出,这是为了后面封装请求方法时能直接使用拦截器。
import axios from ‘axios’;
axios.defaults.timeout = 20000;
// 返回其他状态吗
axios.defaults.validateStatus = function (status) {
return status >= 200 && status <= 500; // 默认的
};
// 跨域请求,允许保存cookie
axios.defaults.withCredentials = true;
//设置默认url
axios.defaults.baseURL = ‘/api’;
axios.interceptors.request.use(
(config) => {
return config;
},
(error) => {
return Promise.reject(error);
}
);
// HTTPresponse拦截
axios.interceptors.response.use(
(res) => {
const status = Number(res.status) || 200;
// 如果是白名单类型放入catch自行处理
if (status !== 200) {
return Promise.reject(res);
}
return res.data;
},
(error) => {
return Promise.reject(new Error(error));
}
);
export default axios;
新建一个api.js封装请求方法,可以看到这里的axios是从http.js当中导入的,所以是直接带有拦截器的,然后封装了get和post方法(其实post方法里面的参数我没有用到,写不写都行),然后这里的url是一个相对url,完整的url是baseURL + url 这样,并且导出,让他们在项目其他组件可用