Spring boot 2.7.18使用knife4j

1、pom文件

复制代码
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
            <version>4.4.0</version>
        </dependency>

2、SwaggerConfig

复制代码
package com.example.demo.config;

import io.swagger.annotations.Api;
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.EnableSwagger2WebMvc;

@Configuration
@EnableSwagger2WebMvc
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("用户管理系统API文档")
                .description("基于Knife4j的API文档")
                .version("1.0")
                .build();
    }
}

3、application.yml

复制代码
# Knife4j API文档配置
knife4j:
  enable: true
  setting:
    language: zh-CN
  production: false
  basic:
    enable: false
    username: admin
    password: 123456

4、使用样例

复制代码
package com.example.demo.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.demo.entity.User;
import com.example.demo.request.UserRequest;
import com.example.demo.response.UserResponse;
import com.example.demo.service.UserService;
import com.example.demo.vo.UserOrderVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.HashMap;

/**
 * User API controller
 */
@RestController
@Api(tags = "用户管理")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * Single table pagination query user interface
     * @param pageNum Page number (default 1)
     * @param pageSize Page size (default 10)
     * @param age Age (optional)
     * @return Pagination result
     */
    @GetMapping("/user/page")
    public IPage<User> getUserPage(
            @RequestParam(defaultValue = "1", name = "pageNum") @ApiParam(value = "Page number", defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10", name = "pageSize") @ApiParam(value = "Page size", defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) @ApiParam(value = "Age") Integer age) {
        return userService.getUserPage(pageNum, pageSize, age);
    }

    /**
     * Multi-table join pagination query interface (User + Order)
     * @param pageNum Page number (default 1)
     * @param pageSize Page size (default 10)
     * @param username Username (optional)
     * @return Pagination result
     */
    @GetMapping("/user/joinPage")
    @ApiOperation(value = "联合分页查询", notes = "联合分页查询")
    public IPage<UserOrderVO> getUserOrderPage(
            @RequestParam(defaultValue = "1", name = "pageNum") @ApiParam(value = "Page number", defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10", name = "pageSize") @ApiParam(value = "Page size", defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) @ApiParam(value = "Username") String username) {
        return userService.getUserOrderPage(pageNum, pageSize, username);
    }

    @PostMapping("/user/add")
    @ApiOperation(value = "新增用户", notes = "新增用户")
    public void addUser(@RequestBody @ApiParam(value = "User information") UserRequest request) {
        User user = new User();
        BeanUtils.copyProperties(request, user);
        if(request.getExt() != null && !request.getExt().isEmpty()){
            user.setExtJson(JSONUtil.toJsonStr(request.getExt()));
        }
        userService.save(user);
    }

    @GetMapping("/user/detail")
    @ApiOperation(value = "用户详情", notes = "用户详情")
    public UserResponse getUserDetail(@RequestParam Long id) {
        User user = userService.getById(id);
        UserResponse response = new UserResponse();
        BeanUtils.copyProperties(user, response);
        if(StrUtil.isNotEmpty(user.getExtJson())){
            response.setExt(JSONUtil.toBean(user.getExtJson(), Map.class));
        }
        return response;
    }
}

5、启动类打印接口文档地址

复制代码
package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;

/**
 * 项目启动类
 * @MapperScan:扫描Mapper接口所在包
 */
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class SpringbootMpDemoApplication {

    public static void main(String[] args) {
        // 启动Spring Boot应用,并获取应用上下文
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootMpDemoApplication.class, args);

        // 从上下文获取环境配置(包含端口、IP等配置)
        Environment env = context.getEnvironment();

        // 1. 获取项目端口(优先读取配置的server.port,默认8080)
        String port = env.getProperty("server.port", "8080");

        // 2. 获取本机真实IP(排除127.0.0.1,适配多网卡场景)
        String ip = getLocalIpAddress();

        // 3. 打印完整的访问地址
        System.out.println("=========================================================");
        System.out.println("项目启动成功!🎉 接口文档访问地址:http://" + ip + ":" + port+"/doc.html");
        System.out.println("=========================================================");
    }

    /**
     * 获取本机真实的IPv4地址(非回环地址,适配多网卡)
     * @return 本机IP地址,异常时返回127.0.0.1
     */
    private static String getLocalIpAddress() {
        try {
            // 遍历所有网络接口
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface ni = interfaces.nextElement();
                Enumeration<InetAddress> addresses = ni.getInetAddresses();

                // 遍历当前网卡的所有IP地址
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    // 过滤条件:非回环地址(排除127.0.0.1)+ 是IPv4地址(排除IPv6)
                    if (!addr.isLoopbackAddress() && addr.getHostAddress().indexOf(":") == -1) {
                        return addr.getHostAddress();
                    }
                }
            }
            // 如果没找到有效IP,返回本机localhost的IP
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            return "127.0.0.1";
        } catch (Exception e) {
            return "127.0.0.1";
        }
    }

}
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm