You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让Swagger识别@ApplicationPath?基于swagger-jaxrs 1.5.18

解决Swagger-JAXRS 1.5.18路径前缀缺失问题

这种情况我维护老项目时也碰到过,Swagger 1.5.x确实有个小坑——它默认不会自动把@ApplicationPath的路径前缀合并到生成的API路径里。不用改动现有注解的话,有几个靠谱的方案可以试试:

方案一:配置Swagger的BasePath参数(最简单直接)

Swagger允许通过配置手动指定API的基础路径,刚好可以补上@ApplicationPath的前缀。

方式1:Web.xml配置

如果项目用web.xml管理Servlet,给Swagger的配置Servlet加一个初始化参数:

<servlet>
    <servlet-name>swagger-jaxrs-config</servlet-name>
    <servlet-class>io.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class>
    <init-param>
        <!-- 这里填你的完整基础路径:/api/docs -->
        <param-name>swagger.api.basepath</param-name>
        <param-value>/api/docs</param-value>
    </init-param>
    <init-param>
        <param-name>swagger.resource.package</param-name>
        <param-value>com.your.project.resource</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>swagger-jaxrs-config</servlet-name>
    <url-pattern>/swagger.json</url-pattern>
</servlet-mapping>

方式2:Java代码配置(无web.xml场景)

创建一个Servlet上下文监听器,手动初始化Swagger的BeanConfig

import io.swagger.jaxrs.config.BeanConfig;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class SwaggerInitializer implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setVersion("1.0.0");
        beanConfig.setSchemes(new String[]{"http"});
        beanConfig.setHost("localhost:8080");
        // 补上ApplicationPath的前缀
        beanConfig.setBasePath("/api/docs");
        // 扫描你的资源类包
        beanConfig.setResourcePackage("com.your.project.resource");
        beanConfig.setScan(true);
    }
}

方案二:自定义ApiListingResource(动态适配路径)

如果需要动态获取@ApplicationPath的值(比如多环境路径不同),可以重写Swagger的默认资源类,手动合并路径:

  1. 自定义ApiListingResource
import io.swagger.jaxrs.listing.ApiListingResource;
import io.swagger.models.Swagger;
import javax.inject.Inject;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.UriInfo;

public class CustomApiListingResource extends ApiListingResource {
    @Inject
    private Application jaxrsApplication;

    @Override
    protected Swagger process(UriInfo uriInfo, HttpHeaders headers, String swaggerJson) {
        Swagger swagger = super.process(uriInfo, headers, swaggerJson);
        // 获取@ApplicationPath的配置值
        String applicationPath = jaxrsApplication.getApplicationPath();
        if (applicationPath != null && !applicationPath.isEmpty()) {
            // 合并基础路径和ApplicationPath
            String fullBasePath = uriInfo.getBaseUri().getPath() + applicationPath;
            swagger.setBasePath(fullBasePath);
        }
        return swagger;
    }
}
  1. 在你的Application类里注册这个自定义资源:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

@ApplicationPath("/docs")
public class MyJaxrsApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<>();
        // 注册自定义的ApiListingResource
        classes.add(CustomApiListingResource.class);
        // 注册Swagger序列化类
        classes.add(io.swagger.jaxrs.listing.SwaggerSerializers.class);
        // 注册你的业务资源类
        classes.add(MyDocsResource.class);
        return classes;
    }
}

方案三:Spring Boot整合场景(可选)

如果是Spring Boot项目,直接在配置文件里指定Swagger的基础路径:

# application.properties
swagger.base-path=/api/docs

注:该方式需要确保你的Swagger整合starter支持此配置,老版本可能需要配合springfox使用。


内容的提问来源于stack exchange,提问作者GuitarStrum

火山引擎 最新活动