1、在module下的pom.xml中引用相关插件

  • 引用swagger插件并用参数化版本信息,如下

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>exercise</artifactId>
<groupId>com.mycom.apitest</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion> <artifactId>exercise10</artifactId> <properties>
<swagger.version>2.6.1</swagger.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
</dependencies> </project>

2、写swagger的配置文件

  • 在main/java下新建一个配置包com.course.config,用来存放配置文件类SwaggerConfig.java,内容如下


package com.course.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.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; //Configuration和EnableSwagger2这两个注解标签用于自动加载swagger的配置文件
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
//固定写法,方法名api自定义
public Docket api(){
return new Docket(DocumentationType.SWAGGER_2)
//括号里加载的是下面创建的apiInfo方法
.apiInfo(apiInfo())
//配置整个的访问路径,这里为根路径
.pathMapping("/")
//选择上前面的目录,根路径
.select()
//路径选择器,正则配置server下的方法,选择根目录下的所有方法
.paths(PathSelectors.regex("/.*"))
//build下该文件
.build();
} private ApiInfo apiInfo(){
//swagger界面标题,联系人(含姓名,链接,邮箱),描述,版本,最后build这个文件
return new ApiInfoBuilder().title("我的接口文档")
.contact(new Contact("junjun","http://test.com","test168test@126.com"))
.description("这是我的swaggerui生成的接口文档")
.version("1.0.0.0")
.build(); }
}

3、在待测接口方法中加swagger注解,如@Api()、@ApiOperation()

  • 在main/java下的com.course.server包的方法如下

MyGetMethod.java

package com.course.server;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects; @RestController //表示以下类是需要被扫描的
//Api表示标识这个类是swagger的资源,value自定义,表示这类方法在swaggerui的名称
@Api(value = "/",description = "这是我全部的get方法")
public class MyGetMethod { @RequestMapping(value = "/getCookies",method = RequestMethod.GET) //请求映射地址和请求方法,即请求路径,可与后面的方法名相同
@ApiOperation(value = "通过这个方法可以获取到cookies",httpMethod = "GET") //表示一个http请求的操作,value描述该接口的作用,后面指定该接口的请求方式
public String getCookies(HttpServletResponse response){
//HttpServletRequest 装载请求信息的类
//HttpServletResponse 装载响应信息的类
//定义响应的cookie信息
Cookie cookie = new Cookie("login","true");
response.addCookie(cookie); //将cookie信息添加到响应中返回
return "恭喜你获取cookies信息成功"; //响应信息,text格式
} /*
* 要求客户端携带cookies访问
* 这是一个需要携带cookies信息才能访问的get请求
* */
@RequestMapping(value = "/get/with/cookies",method = RequestMethod.GET)
@ApiOperation(value = "这是一个需要携带cookies信息才能访问的get请求",httpMethod = "GET")
public String getWithCookies(HttpServletRequest request){
//获取请求中的cookie信息,并存在一维数组中,因可能有多个cookie信息,HttpServletRequest request是需要装载请求信息时的固定写法
Cookie[] cookies = request.getCookies();
//定义cookie信息为空时的响应信息
if (Objects.isNull(cookies)){
return "你必须携带cookies信息来!";
}
//将获取到的cookie信息遍历出来比对,比对通过则返回成功相应信息
for (Cookie cookie : cookies){
if (cookie.getName().equals("login") &&
cookie.getValue().equals("true")){
return "成功,这是一个需要携带cookies信息才能访问的get请求!";
}
}
//如果获取到的cookie信息比对不正确,则返回以下信息(即除了上面两种情况,剩下的情况都返回以下信息)
return "你必须携带正确的cookies信息来!!!";
} /*
* 开发一种需要携带参数才能访问的get请求
* 第一种实现方式 url:key=value&key=value
* 现模拟获取商品列表
* */ @RequestMapping(value = "/get/with/param",method = RequestMethod.GET)
@ApiOperation(value = "需要携带参数才能访问的get请求实现方式一(校验参数)",httpMethod = "GET")
//将参数定义在方法传参位置处,用@RequestParam关键字,如下,需要传两个参数
//泛数据类型(对象类型)
//required=true:该参数不能为空;相反required=false:该参数能为空;若不写括号和括号内容,则默认为true
public Map<String,Integer> getList(@RequestParam(value = "start", required = false) Integer start,
@RequestParam(value = "end", required = false) Integer end){
//泛数据类型的类,在实例化对象时,具体化元素的数据类型
//响应体,如下返回的是json格式的信息
Map<String, Integer> myList = new HashMap<>(); if (start.equals(15) && end.equals(30)) { myList.put("鞋", 400);
myList.put("干脆面", 1);
myList.put("衬衫", 300); return myList;
}
//参数错误,则返回以下信息,空值则返回500
myList.put("oh sorry start or end is wrong", 0);
return myList;
} //不做参数校验
@RequestMapping(value = "/get/with/param2",method = RequestMethod.GET)
@ApiOperation(value = "需要携带参数才能访问的get请求实现方式一(不校验参数)",httpMethod = "GET")
public Map<String,Integer> getList2(@RequestParam Integer start,
@RequestParam Integer end){
Map<String,Integer> myList = new HashMap<>();
myList.put("鞋",400);
myList.put("衬衫",300);
myList.put("干脆面",1); return myList; } /**
*第2种需要携带参数访问的get请求,用到的是@PathVariable 关键字,因为是参数化的路径,有校验
* url: ip:port/get/with/param/10/20
* */
@RequestMapping(value = "/get/with/param/{start}/{end}") //另一种请求url
@ApiOperation(value = "需要携带参数才能访问的get请求实现方式二(校验参数)",httpMethod = "GET")
public Map myGetList(@PathVariable Integer start,
@PathVariable Integer end){ Map<String, Integer> myList = new HashMap<>(); if (start.equals(15) && end.equals(30)) { myList.put("鞋", 400);
myList.put("干脆面", 1);
myList.put("衬衫", 300); return myList;
}
//参数错误,则返回以下信息,空值则返回500
myList.put("oh sorry start or end is wrong", 0);
return myList;
} //不做参数校验
@RequestMapping(value = "/get/with/param2/{start}/{end}")
@ApiOperation(value = "需要携带参数才能访问的get请求实现方式二(不校验参数)",httpMethod = "GET")
public Map myGetList2(@PathVariable Integer start,
@PathVariable Integer end){ Map<String,Integer> myList = new HashMap<>();
myList.put("鞋",400);
myList.put("衬衫",300);
myList.put("干脆面",1); return myList;
} }

4、修改@ComponentScan包含的包类,需包含配置包

  • main/java下的Application.java如下

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan; @SpringBootApplication //加这个注解标签,表示将下面的入口类托管
@ComponentScan("com.course") //表示托管给我后,你要我扫描哪个包下的类
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args); //固定写法,参数args与方法中的args相同
}
}

5、运行Application.java

6、返回cookies信息的post接口开发

  • 1、在main/java下的com.course.server包新建接口类MyPostMethod.java,如下

package com.course.server;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse; @RestController
//tags–表示接口类说明,value–也是说明,可以使用tags替代;但是tags如果有多个值,会生成多个list
@Api(value = "post-controller",tags={"mock-post"},description = "这是我全部的post请求")
/*@RequestMapping可以用来注释一个控制器类,在这种情况下,所有方法都将映射为相对于类级别的请求,
表示该控制器处理的所有请求都被映射到value属性所指示的路径下*/
//如下,表示根目录为v1,而后面的value = "/login"则表示在根目录下的login路径中,即该接口的实际路径为 /v1/login ,若前面没定义根路径,则以后面的value路径为实际路径
@RequestMapping("v1")
public class MyPostMethod { //cookie变量用来装我们的cookies信息
private static Cookie cookie; //用户登陆成功获取到cookies,然后在访问其他接口获取到的列表,必须要求是post方法才可以访问
@RequestMapping(value = "/login",method = RequestMethod.POST)
@ApiOperation(value = "登陆接口,成功后获取cookies信息",httpMethod = "POST")
//Value的值是在前端显示的名称,request为true表示该参数必需,false为非必需
//这里参数的格式为data格式,如 usenName=zhangsan&password=123456
public String login(HttpServletResponse response, //传入response这个参数是会在浏览器中看到cookie的属性
@RequestParam(value = "usenName",required = true) String userName,
@RequestParam(value = "密码",required = true) String password){ if(userName.equals("zhangsan")&&password.equals("123456")){
cookie = new Cookie("login","true");
response.addCookie(cookie); //把cookie信息加到响应中
return "恭喜你登陆成功!";
}
return "用户名或者密码错误!";
} }
  • 重启springboot程序,重新加载类包,访问http://127.0.0.1:8888/swagger-ui.html#/

    若不定义tags,则默认使用该类的类名



7、Cookies验证和返回用户列表的post接口开发

  • 附录:Lombok的使用
  • Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。
  • Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。

Lombok的使用跟引用jar包一样,可以在官网(https://projectlombok.org/download)下载jar包,也可以使用maven添加依赖:

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
  • Lombok虽然有很多优点,但Lombok更类似于一种IDE插件,项目也需要依赖相应的jar包。Lombok依赖jar包是因为编译时要用它的注解,为什么说它又类似插件?因为在使用时,eclipse或IntelliJ IDEA都需要安装相应的插件,在编译器编译时通过操作AST(抽象语法树)改变字节码生成,变相的就是说它在改变java语法。
  • 虽然非常不建议在属性的getter/setter写一些业务代码,但在多年项目的实战中,有时通过给getter/setter加一点点业务代码,能极大的简化某些业务场景的代码。所谓取舍,也许就是这时的舍弃一定的规范,取得极大的方便。

lombok安装与使用

  • 在Settings→Plugins→lombok安装



  • 在Settings→Build,Excution,Deployment→Compiler→Java Compiler页面Use compiler设置JavaC

  • 在module的pom.xml配置文件中引用依赖(springboot版本是2.1.5.RELEASE)


<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
  • 1、在main/java下新建com.course.bean包,在bean目录下新建user类,作为后续被引用的数据类型的类:

User.java

package com.course.bean;

import lombok.Data;
//加了@Data后,该类写成员属性即可,而获取成员属性的方法如getUserName,在编译执行时,会自动从lombok里解析出来
//该类被引用后,如getUserName、setAge这些方法是可以直接调用的 @Data
public class User {
private String userName;
private String password;
private String name;
private String age;
private String sex;
}
  • 2、在com.course.server包MyPostMethod类下开发返回用户列表的post接口,如下

MyPostMethod.java

package com.course.server;

import com.course.bean.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @RestController
//tags–表示接口类说明,value–也是说明,可以使用tags替代;但是tags如果有多个值,会生成多个list
@Api(value = "post-controller",tags={"mock-post"},description = "这是我全部的post请求")
/*@RequestMapping可以用来注释一个控制器类,在这种情况下,所有方法都将映射为相对于类级别的请求,
表示该控制器处理的所有请求都被映射到value属性所指示的路径下*/
//如下,表示根目录为v1,而后面的value = "/login"则表示在根目录下的login路径中,即该接口的实际路径为 /v1/login ,若前面没定义根路径,则以后面的value路径为实际路径
@RequestMapping("v1")
public class MyPostMethod { //cookie变量用来装我们的cookies信息
private static Cookie cookie; //用户登陆成功获取到cookies,然后在访问其他接口获取到的列表,必须要求是post方法才可以访问
@RequestMapping(value = "/login",method = RequestMethod.POST)
@ApiOperation(value = "登陆接口,成功后获取cookies信息",httpMethod = "POST")
//Value的值是在前端显示的名称,request为true表示该参数必需,false为非必需
//参数的数据类型是data格式,如 usenName=zhangsan&password=123456
public String login(HttpServletResponse response, //传入response这个参数是会在浏览器中看到cookie的属性
@RequestParam(value = "usenName",required = true) String userName,
@RequestParam(value = "password",required = true) String password){ if(userName.equals("zhangsan")&&password.equals("123456")){
cookie = new Cookie("login","true");
response.addCookie(cookie); //把cookie信息加到响应中
return "恭喜你登陆成功!";
}
return "用户名或者密码错误!";
} @RequestMapping(value = "/getUserList",method = RequestMethod.POST)
@ApiOperation(value = "获取用户列表",httpMethod = "POST")
//定义请求体是User类,因User的数据结构是json,所以请求体是json类型,测试时,请求头需设置为application/json
public String getUserList(HttpServletRequest request,
@RequestBody User u){ //声明对象,将其移到了外面申明,后面引用
User user;
//获取请求过来的cookies
Cookie[] cookies = request.getCookies();
//验证cookies和请求体是否合法
/* Equals与“==”的区别,“==”用于匹配地址,因而在代码比对校验时,应用equals来比对;
==改成.equals,否则会在接口测试传参比对校验时,会出错,比如u.getPassword() == "123456"时,接口实际传参校验会认为不通过*/
for (Cookie c : cookies){
if (c.getName().equals("login")
&& c.getValue().equals("true")
&& u.getUserName().equals("zhangsan") //利用lombok补全的getUserName获取请求体传过来的UserName
&& u.getPassword().equals("123456") //这里只校验了user里的两个成员属性,请求体的json只需有这两个属性即可,其他属性不用传
){
user = new User(); //利用User类,来设置响应内容,申明对象方法for外面进行,这样能辐射到整个方法,若在这里申明,则返回时可能会有问题
user.setName("lisi");
user.setAge("18");
user.setSex("man");
return user.toString(); //将响应体转成字符串类型,user里的成员属性不用全部设置,没有设置值的部分,则返回null
} }
return "参数不合法";
} }
  • 3、执行程序后,结果如下:





    响应信息,返回的是user类的类名和它的成员属性(括号部分)

  • 4、Jmeter中显示cookie信息

    1. 修改 /bin/ jmeter.properties文件,将CookieManager.save.cookies=true的注释去掉,并将值改成true。
    2. 添加一个空的http cookie管理器,然后在添加一个debug sampler,请求成功后,cookie信息即可在debug sampler中查看,如下,COOKIE_是jmeter自带的,后面的login=true才是请求成功后,响应信息中返回的cookie值。

SpringBoot集成SwaggerUI的更多相关文章

  1. Springboot 4.Springboot 集成SwaggerUi

    SwaggerUi就是自动生成接口文档的这么一个类似于插件的工具,可以直接访问接口. 首先打开pom文件,将插件引进来,然后增加一个属性<properties>,用来设置版本号的,然后直接 ...

  2. springboot系列十三、springboot集成swaggerUI

    一.Swagger介绍 Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原因: Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API. ...

  3. Spring Boot笔记(一) springboot 集成 swagger-ui

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.添加依赖 <!--SpringBoot整合Swagger-ui--> <depen ...

  4. SpringBoot集成Swagger2实现Restful(类型转换错误解决办法)

    1.pom.xml增加依赖包 <dependency> <groupId>io.springfox</groupId> <artifactId>spri ...

  5. spring-boot集成Springfox-Swagger2

    import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Co ...

  6. springboot集成swagger2构建RESTful API文档

    在开发过程中,有时候我们需要不停的测试接口,自测,或者交由测试测试接口,我们需要构建一个文档,都是单独写,太麻烦了,现在使用springboot集成swagger2来构建RESTful API文档,可 ...

  7. spring-boot 集成 swagger 问题的解决

    spring-boot 集成 swagger 网上有许多关于 spring boot 集成 swagger 的教程.按照教程去做,发现无法打开接口界面. 项目由 spring mvc 迁移过来,是一个 ...

  8. SpringBoot集成Swagger2 以及汉化 快速教程

    (一) Swagger介绍 Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件 (二)为什么使用Swagger 在现在的开发过程中还有很大一部分公司都是以口口相传的方式来进行 ...

  9. Springboot集成swagger2生成接口文档

    [转载请注明]: 原文出处:https://www.cnblogs.com/jstarseven/p/11509884.html    作者:jstarseven    码字挺辛苦的.....   一 ...

随机推荐

  1. Yaf自定义autoload以实现Model文件和Controller文件命名区分

    先上图: 由于Yaf作者在设计Yaf框架目录时没有直接区分开models文件和controllers文件,所以在IDE看着会很难受,眼睛离开了编辑器就不大好区分这两个文件夹的文件.所以自己写了一个au ...

  2. 使用shader,矩阵旋转实现图片的旋转动画

    常用于loading动画之类的 具体的实现代码: fixed4 frag (v2f i) : SV_Target { //1.先将uv平移到原点(让图片中心与原点重合) float2 pianyi=( ...

  3. Docker(一)概念与基础

    Docker 基础 为什么需要docker?在传统部署下,我们会遇到不同机器.不同依赖版本的兼容性等问题,解决此问题一般会消耗大量时间,并且在不同机器上均要执行统一环境的部署也是一个耗时较长的工作.除 ...

  4. Oracle Data Guard搭建 1.虚拟机安装linux

    1.安装虚拟机 VMware 14 2.下载Linux镜像文件,创建虚拟机

  5. js中进入页面后刷新一次,且只刷新一次

    让页面进行刷新,可以使用location.reload()方法,但是这种方法会让页面一直不断的刷新,这是因为当页面加载完成以后,我们让它刷新一次,那么浏览器就会重新向服务器请求数据,界面会重新加载,然 ...

  6. http接口性能测试工具

    一. http_load 程序非常小,解压后也不到100K.http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载. 但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一 ...

  7. Python学习第三天(持续学习了很多的str类型相关方法)

    今天的主要内容是各种各样的str对应方法,就直接把自己测试的东西放在了下面:还有很多习题,这个倒是得抓紧啊. #expandtabs:以制表符\t对字符串进行断句,并根据参数数字补齐位数 test = ...

  8. css 动画开关按钮

    <style> input[type="checkbox"] { display: none; } input[type="checkbox"] + ...

  9. php/js将 CST时间转成格式化时间

    PHP :比较简单 $str = 'Wed Jul 24 11:24:33 CST 2019'; echo date('Y-m-d H:i:s', strtotime($str)); echo dat ...

  10. 网络知识杂谈 - https - 原理简述

    概述 简单描述 https 尽量介绍它的原理 实际的机制, 可能会更加复杂一些... 背景 这玩意, 困扰我好多年了 今天开始, 想做个了断 之前工作也接触过, 但从我的角度来说, 认识很浅 会配置 ...