6

我目前正在使用 Eclipse、Spring Framework MVC 创建一个 API Rest,并且我刚刚添加到我的项目中。我可以访问 swagger 的 json 结果,但我需要添加 swagger ui。

这是我为 swagger-springmvc 创建的所有文件:

WebAppInitializer.java

public class WebAppInitializer implements WebApplicationInitializer {

    private AnnotationConfigWebApplicationContext ctx = null;

    @Override
    public void onStartup(final ServletContext sc) throws ServletException {

        System.setProperty("spring.profiles.active", "web");

        // Create the 'root' Spring application context
        ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringBaseWebConfiguration.class,
                SpringSwaggerConfiguration.class);

        // Manages the lifecycle
        sc.addListener(new ContextLoaderListener(ctx));
        sc.addListener(new ContextCleanupListener());

        // Spring WebMVC
        ServletRegistration.Dynamic springWebMvc = sc.addServlet("ws",
                new DispatcherServlet(ctx));
        springWebMvc.setLoadOnStartup(1);
        springWebMvc.addMapping("/ws/*");
        springWebMvc.setAsyncSupported(true);
    }

    @PreDestroy
    protected final void cleanup() {
        if (ctx != null) {
            ctx.close();
        }
    }
}

SpringSwaggerConfiguration.java

public class SpringSwaggerConfiguration {
    public static final List<String> DEFAULT_INCLUDE_PATTERNS = Arrays
            .asList(new String[]{"/com/sa/rnd/dark/resources/.*"});
    public static final String SWAGGER_GROUP = "ApiDark";
    public static final String RELATIVE_GROUP = "ApiDark";
    @Autowired
    private SpringSwaggerConfig springSwaggerConfig;

/**
 * Adds the jackson scala module to the MappingJackson2HttpMessageConverter
 * registered with spring Swagger core models are scala so we need to be
 * able to convert to JSON Also registers some custom serializers needed to
 * transform swagger models to swagger-ui required json format
 */
@Bean
public JacksonScalaSupport jacksonScalaSupport() {
    final JacksonScalaSupport jacksonScalaSupport = new JacksonScalaSupport();
    // Set to false to disable
    jacksonScalaSupport.setRegisterScalaModule(true);
    return jacksonScalaSupport;
}

/**
 * Global swagger settings
 */
@Bean
public SwaggerGlobalSettings swaggerGlobalSettings() {
    final SwaggerGlobalSettings swaggerGlobalSettings = new SwaggerGlobalSettings();
    swaggerGlobalSettings.setGlobalResponseMessages(springSwaggerConfig
            .defaultResponseMessages());
    swaggerGlobalSettings.setIgnorableParameterTypes(springSwaggerConfig
            .defaultIgnorableParameterTypes());
    return swaggerGlobalSettings;
}

/**
 * API Info as it appears on the swagger-ui page
 */
private ApiInfo apiInfo() {
    return new ApiInfo(
            "Swagger Spring MVC for Dark Api",
            "Sample application demonstrating how to use swagger-springmvc in a no-XML environment.",
            "http://en.wikipedia.org/wiki/Terms_of_service",
            "michael@laccetti.com", "Apache 2.0",
            "http://www.apache.org/licenses/LICENSE-2.0.html");
}

/**
 * Configure a SwaggerApiResourceListing for each swagger instance within
 * your app. e.g. 1. private 2. external apis Required to be a spring bean
 * as spring will call the postConstruct method to bootstrap swagger
 * scanning.
 *
 * @return
 */
@Bean
public SwaggerApiResourceListing swaggerApiResourceListing() {
    // The group name is important and should match the group set on
    // ApiListingReferenceScanner
    // Note that swaggerCache() is by DefaultSwaggerController to serve the
    // swagger json
    final SwaggerApiResourceListing swaggerApiResourceListing = new SwaggerApiResourceListing(
            springSwaggerConfig.swaggerCache(), SWAGGER_GROUP);

    // Set the required swagger settings
    swaggerApiResourceListing
            .setSwaggerGlobalSettings(swaggerGlobalSettings());

    // Supply the API Info as it should appear on swagger-ui web page
    swaggerApiResourceListing.setApiInfo(apiInfo());

    // Use the default path provider
    swaggerApiResourceListing.setSwaggerPathProvider(springSwaggerConfig
            .defaultSwaggerPathProvider());

    // Global authorization - see the swagger documentation
    swaggerApiResourceListing.setAuthorizationTypes(authorizationTypes());

    // Sets up an auth context - i.e. which controller request paths to
    // apply global auth to
    swaggerApiResourceListing
            .setAuthorizationContext(authorizationContext());

    // Every SwaggerApiResourceListing needs an ApiListingReferenceScanner
    // to scan the spring request mappings
    swaggerApiResourceListing
            .setApiListingReferenceScanner(apiListingReferenceScanner());
    return swaggerApiResourceListing;
}

@Bean
/**
 * The ApiListingReferenceScanner does most of the work.
 * Scans the appropriate spring RequestMappingHandlerMappings
 * Applies the correct absolute paths to the generated swagger resources
 */
public ApiListingReferenceScanner apiListingReferenceScanner() {
    ApiListingReferenceScanner apiListingReferenceScanner = new ApiListingReferenceScanner();

    // Picks up all of the registered spring RequestMappingHandlerMappings
    // for
    // scanning
    apiListingReferenceScanner
            .setRequestMappingHandlerMapping(springSwaggerConfig
                    .swaggerRequestMappingHandlerMappings());

    // Excludes any controllers with the supplied annotations
    apiListingReferenceScanner.setExcludeAnnotations(springSwaggerConfig
            .defaultExcludeAnnotations());

    //
    apiListingReferenceScanner
            .setResourceGroupingStrategy(springSwaggerConfig
                    .defaultResourceGroupingStrategy());

    // Path provider used to generate the appropriate uri's
    apiListingReferenceScanner
            .setSwaggerPathProvider(relativeSwaggerPathProvider());

    // Must match the swagger group set on the SwaggerApiResourceListing
    apiListingReferenceScanner.setSwaggerGroup(SWAGGER_GROUP);

    // Only include paths that match the supplied regular expressions
    apiListingReferenceScanner.setIncludePatterns(DEFAULT_INCLUDE_PATTERNS);

    return apiListingReferenceScanner;
}

private List<AuthorizationType> authorizationTypes() {
    final List<AuthorizationType> authorizationTypes = new ArrayList<>();
    authorizationTypes.add(new BasicAuth());
    return authorizationTypes;
}

@Bean
public AuthorizationContext authorizationContext() {
    final List<Authorization> authorizations = newArrayList();

    AuthorizationScope authorizationScope = new AuthorizationScope(
            "global", "accessEverything");

    AuthorizationScope[] authorizationScopes = new AuthorizationScope[]{authorizationScope};
    authorizations.add(new Authorization("basic", authorizationScopes));

    AuthorizationContext authorizationContext = new AuthorizationContext.AuthorizationContextBuilder(
            authorizations).withIncludePatterns(DEFAULT_INCLUDE_PATTERNS)
            .build();

    return authorizationContext;
}

// Relative path example
@Bean
public SwaggerApiResourceListing relativeSwaggerApiResourceListing() {
    SwaggerApiResourceListing swaggerApiResourceListing = new SwaggerApiResourceListing(
            springSwaggerConfig.swaggerCache(), RELATIVE_GROUP);
    swaggerApiResourceListing
            .setSwaggerGlobalSettings(swaggerGlobalSettings());
    swaggerApiResourceListing
            .setSwaggerPathProvider(relativeSwaggerPathProvider());
    swaggerApiResourceListing
            .setApiListingReferenceScanner(relativeApiListingReferenceScanner());
    return swaggerApiResourceListing;
}

@Bean
public ApiListingReferenceScanner relativeApiListingReferenceScanner() {

    ApiListingReferenceScanner apiListingReferenceScanner = 
            new ApiListingReferenceScanner();

    apiListingReferenceScanner
            .setRequestMappingHandlerMapping(springSwaggerConfig
                    .swaggerRequestMappingHandlerMappings());

    apiListingReferenceScanner.setExcludeAnnotations(springSwaggerConfig
            .defaultExcludeAnnotations());

    apiListingReferenceScanner
            .setResourceGroupingStrategy(springSwaggerConfig
                    .defaultResourceGroupingStrategy());

    apiListingReferenceScanner
            .setSwaggerPathProvider(relativeSwaggerPathProvider());

    apiListingReferenceScanner.setSwaggerGroup(RELATIVE_GROUP);
    apiListingReferenceScanner.setIncludePatterns(DEFAULT_INCLUDE_PATTERNS);
    return apiListingReferenceScanner;
}

@Bean
public SwaggerPathProvider relativeSwaggerPathProvider() {
    return new ApiRelativeSwaggerPathProvider();
}

private class ApiRelativeSwaggerPathProvider extends
        DefaultSwaggerPathProvider {
    @Override
    public String getAppBasePath() {
        return "/ApiDark/ws";
    }
}

}

SpringBaseWebConfiguration.java:

@Configuration
@ComponentScan(basePackages = {"com.sa.rnd.dark.resources",
        "com.mangofactory.swagger.configuration",
        "com.mangofactory.swagger.controllers"})

@EnableWebMvc
public class SpringBaseWebConfiguration extends WebMvcConfigurerAdapter {
    private List<HttpMessageConverter<?>> messageConverters;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("/");
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/api-docs").setViewName("redirect:index.html");
    }

    /**
     * The message converters for the content types we support.
     *
     * @return the message converters; returns the same list on subsequent calls
     */
    private List<HttpMessageConverter<?>> getMessageConverters() {
        if (messageConverters == null) {
            messageConverters = new ArrayList<>();

            final MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJackson2HttpMessageConverter();
            final ObjectMapper mapper = new ObjectMapper();
            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
            mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
                    false);
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
                    false);
            mappingJacksonHttpMessageConverter.setObjectMapper(mapper);
            messageConverters.add(mappingJacksonHttpMessageConverter);
        }
        return messageConverters;
    }

    @Override
    public void configureMessageConverters(
            List<HttpMessageConverter<?>> converters) {
        converters.addAll(getMessageConverters());
    }

    @Bean
    public static PropertyPlaceholderConfigurer swaggerProperties() {
        final PropertyPlaceholderConfigurer swaggerProperties = new PropertyPlaceholderConfigurer();
        swaggerProperties.setLocation(new ClassPathResource(
                "swagger.properties"));
        return swaggerProperties;
    }
}

这是我的 3 个文件,可将 swagger 添加到我的项目中,atm 我只是决定只检查 1 个方法,即:

@Api(description = "CRUD services for containers working with WebDark",
        value = "CRUD Services Containers")
@RestController
@RequestMapping(value = "/container", produces = MediaType.APPLICATION_JSON_VALUE)
public class ContainersResources {
    /**
     * Find all children of a container.
     *
     * @param containerId
     *            ID of the parent container
     * @return ApiResponse
     */


    @ApiOperation(response = ApiResponse.class,
            value = "Find all children containers of one container",
            notes = "Find all children containers of one container")
    @RequestMapping(method = RequestMethod.GET, value = "/{containerId}")
    @ResponseStatus(HttpStatus.OK)
    public @ResponseBody ApiResponse<List<ContainerModel>> getContainerChildren(
            @ApiParam(required = true, value = "The id of the container parent",
                    name = "containerId")@PathVariable("containerId") final String containerId) {
        ApiResponse<List<ContainerModel>> result = new ApiResponse<>();
        result.setMessage("getContainerChildren  method of new Api Dark");
        result.setSuccess(true);
        result.setTotal(9000);
        return result;
    }
}

我的结果:我可以访问以下网址http://localhost:8080/ApiDark/ws/api-docs,但我得到的 json 值如下:

{"apiVersion":"1","swaggerVersion":"1.2","authorizations":{"basicAuth":{"type":"basicAuth"}},"info":{"title":"Swagger Spring MVC对于 Dark Api","description":"演示如何在无 XML 环境中使用 swagger-springmvc 的示例应用程序。","termsOfServiceUrl":" http://en.wikipedia.org/wiki/Terms_of_service ","contact ":"michael@laccetti.com","license":"Apache 2.0","licenseUrl":" http://www.apache.org/licenses/LICENSE-2.0.html "}}

这就是我决定添加 swagger-ui 的原因。我将 dist 文件夹的内容(取自swagger-ui)添加到我的 src/main/webapp 文件夹中。并修改 index.html 的内容以指向我的 url :

<script type="text/javascript">
$(function () {
  window.swaggerUi = new SwaggerUi({
      url: "http://localhost:8080/ApiDark/ws/api-docs.json",
  dom_id: "swagger-ui-container",

但是我无法访问 swagger-ui 界面,我只有 json 结果...需要帮助才能使其正常工作!

4

2 回答 2

3

这个问题似乎很老,但只是为了分享,使用最新版本的 swagger-springmvc 和 springmvc-ui,将 swagger 和 swagger-ui 与您的 Web 服务集成以在生产 REST api 文档中查看变得非常容易且不那么复杂。

添加了 @EnableSwagger 注释,使 swagger-springmvc 开箱即用。生成的 swagger json 资源列表可以在 /api-docs 访问。

您可以参考以下链接,了解将 swagger-springmvc 和 swagger-ui 与您的 spring mvc 项目集成的步骤。 https://github.com/martypitt/swagger-springmvc

于 2014-08-01T03:43:02.243 回答
0

“我无法访问 swagger-ui 界面”是什么意思?

在我的情况下,我的浏览器没有加载 index.html(我认为它会抛出 404),我将它与所有 dist 文件一起放在一个子文件夹中:webapp/doc/index.html。我必须从 web.xml 中的 servlet 映射中排除子文件夹,正如我在这里简要描述的那样: Java swagger with JaxRS throwing errors

我的 web.xml 片段最终看起来像这样:

  <servlet-mapping>
<servlet-name>My application servlet-name</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/doc/*</url-pattern>
</servlet-mapping>

(为什么这个工作见这里:http ://blog.ericdaugherty.com/2010/02/ exclude-content-from-url-pattern-in.html )

希望有帮助!

于 2014-05-07T08:45:10.433 回答