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";
        }
    }

}
相关推荐
leobertlan7 小时前
2025年终总结
前端·后端·程序员
面向Google编程7 小时前
从零学习Kafka:数据存储
后端·kafka
易安说AI8 小时前
Claude Opus 4.6 凌晨发布,我体验了一整晚,说说真实感受。
后端
易安说AI8 小时前
Ralph Loop 让Claude无止尽干活的牛马...
前端·后端
易安说AI8 小时前
用 Claude Code 远程分析生产日志,追踪 Claude Max 账户被封原因
后端
JH30739 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
颜酱9 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
Coder_Boy_10 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
invicinble10 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟10 小时前
使用ASM和agent监控属性变化
java