Springboot2整合knife4j过程解析

网友投稿 484 2022-12-12


Springboot2整合knife4j过程解析

knife4j官网:https://doc.xiaominfo.com/guide/useful.html

这玩艺就swagger的升级版,但是用起来比swagger方便多了,至少不会出现莫名的版本兼容问题

下面记录一个配置示例

1.代码结构

2.pom.xml

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

2.2.5.RELEASE

com.example

knife4j-demo

0.0.1-SNAPSHOT

knife4j-demo

Demo project for Spring Boot

1.8

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.junit.vintage

junit-vintage-engine

com.github.xiaoymin

knife4j-spring-boot-starter

2.0.2

com.alibaba

fastjson

1.2.58

org.projectlombok

lombok

1.18.10

org.springframework.boot

spring-boot-maven-plugin

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

2.2.5.RELEASE

com.example

knife4j-demo

0.0.1-SNAPSHOT

knife4j-demo

Demo project for Spring Boot

1.8

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.junit.vintage

junit-vintage-engine

com.github.xiaoymin

knife4j-spring-boot-starter

2.0.2

com.alibaba

fastjson

1.2.58

org.projectlombok

lombok

1.18.10

org.springframework.boot

spring-boot-maven-plugin

3.配置类

package com.example.knife4j.demo.config;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;

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

@EnableKnife4j

@Import(BeanValidatorPluginsConfiguration.class)

public class SwaggerConfiguration {

@Bean(value = "defaultApi2")

public Docket defaultApi2() {

Docket docket=new Docket(DocumentationType.SWAGGER_2)

.apiInfo(apiInfo())

//分组名称

.groupName("2.X版本")

.select()

//这里指定Controller扫描包路径(项目路径也行)

.apis(RequestHandlerSelectors.basePackage("com.example.knife4j.demo"))

.paths(PathSelectors.any())

.build();

return docket;

}

private ApiInfo apiInfo() {

return new ApiInfoBuilder()

.title("不重要")

.description("测试名称不重要")

.termsOfServiceUrl("http://localhost:88888/")

.contact("10086@mail.com")

.version("1.0")

.build();

}

}

4.模型bean

package com.example.knife4j.demo.beans;

import io.swagger.annotations.ApiModel;

import io.swagger.annotations.ApiModelProperty;

/**

* 创建时间: 23:09 2018/9/19

* 修改时间:

* 编码人员: ZhengQf

* 版 本: 0.0.1

* 功能描述:

*/

@ApiModel(value = "用户模型")

public class UserEntity {

@ApiModelProperty(value="id" ,required= true,example = "123")

private Integer id;

@ApiModelProperty(value="用户姓名" ,required=true,example = "郑钦锋")

private String name;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public String toString() {

return "DemoDoctor [id=" + id + ", name=" + name + "]";

}

}

5.两个接口controller

package com.example.knife4j.demo.controller;

import io.swagger.annotations.Api;

import io.swagger.annotations.ApiOperation;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

@Api(value = "IndexController测试接口")

@RestController

public class IndexController {

@ApiOperation(value = "测试index接口", nickname = "测试IndexController的index接口")

@GetMapping("/index")

public String index() {

return "测试IndexController的index接口...";

}

}

package com.example.knife4j.demo.controller;

import com.example.knife4j.demo.beans.UserEntity;

import io.swagger.annotations.Api;

import io.swagger.annotations.ApiImplicitParam;

import io.swagger.annotations.ApiImplicitParams;

import io.swagger.annotations.ApiOperation;

import org.springframework.web.bind.annotation.*;

@Api(value = "用户接口")

@RestController

public class UserController {

@ApiOperation(value = "获取用户信息接口", nickname = "根据用户ID获取用户相关信息")

@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "int")

@PostMapping("/postMember")

public UserEntity postMember(@RequestParam Integer id) {

UserEntity userEntity = new UserEntity();

userEntity.setId(id);

userEntity.setName("admin");

return userEntity;

}

@ApiOperation(value = "添加用户", nickname = "添加用户接口1", notes = "入参是复杂对象", produces = "application/json")

@PostMapping("/postUser")

@ResponseBody

@ApiImplicitParam(paramType = "query", name = "userId", value = "用户id", required = true, dataType = "int")

public UserEntity postUser(@RequestBody UserEntity user, @RequestParam("userId") int userId) { // 这里用包装类竟然报错

if (user.getId() == userId) {

return user;

}

return new UserEntity();

}

@ApiOperation(value = "添加用户", nickname = "添加用户接口2", notes = "入参是简单对象", produces = "application/json")

@PostMapping("/addUser")

@ResponseBody

@ApiImplicitParams({

@ApiImplicitParam(paramType = "query", name = "userName", value = "用户姓名", required = true, dataType = "String"),

@ApiImplicitParam(paramType = "query", name = "id", value = "用户id", required = true, dataType = "int")})

public UserEntity addUser(String userName, int id) {

UserEntity userEntity = new UserEntity();

userEntity.setName(userName);

userEntity.setId(id);

return userEntity;

}

}

6.srpingboot项目启动类

package com.example.knife4j.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import springfox.documentation.spring.web.SpringfoxWebMvcConfiguration;

@ConditionalOnClass(SpringfoxWebMvcConfiguration.class)

@SpringBootApplication

public class Knife4jDemoApplication implements WebMvcConfigurer {

public static void main(String[] args) {

SpringApplication.run(Knife4jDemoApplication.class, args);

}

@Override

public void addResourceHandlers(ResourceHandlerRegistry registry) {

registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");

registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");

}

}

这样简单一配置,就ok了,浏览器访问:http://127.0.0.1:8080/doc.html

不过,在项目中我使用了ResponseBodyAdvice接口对项目接口响应内容做统一处理,然后使用knife4j就出问题了。

ResponseBodyAdvice接口实现如下:

import org.springframework.context.annotation.Configuration;

import org.springframework.core.MethodParameter;

import org.springframework.http.MediaType;

import org.springframework.http.converter.HttpMessageConverter;

import org.springframework.http.server.ServerHttpRequest;

import org.springframework.http.server.ServerHttpResponse;

import org.springframework.web.bind.annotation.RestControllerAdvice;

import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**

* 自定义advise ,对restful请求响应体进行统一规范

*/

@EnableWebMvc

@Configuration

@RestControllerAdvice

public class ResponseAdvise implements ResponseBodyAdvice {

@Override

public boolean supports(MethodParameter returnType, Class extends HttpMessageConverter>> converterType) {

return true;

}

@Override

public Object beforeBodyWrite(Object object, MethodParameter returnType, MediaType selectedContentType, Class extends HttpMessageConverter>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {

if (object instanceof ResponseData) {

return object;

}

return ResponseData.of().setData(object);

}

}

请求报错

而且后台还说找不到映射路径

2020-03-10 23:31:01.533 WARN 7940 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound : No mapping for GET /service-worker.js

2020-03-10 23:31:01.560 WARN 7940 --- [nio-8080-exec-4] o.s.web.servlet.PageNotFound : No mapping for GET /favicon.ico

2020-03-10 23:31:14.468 WARN 7940 --- [nio-8080-exec-8] o.s.web.servlet.PageNotFound : No mapping for GET /service-worker.js

然后,我在ResponseAdvise#beforeBodyWrite方法中打上断点,发现我将swagger的请求内容进行了修改,以至于报了404。

最后在ResponseAdvise类上声明只对本项目的响应体内容进行统一处理

@RestControllerAdvice(basePackages = "com.example.knife4j.demo")

这样,就完全ok!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java web xml文件读取解析方式
下一篇:Java均摊复杂度和防止复杂度的震荡原理分析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~