„Prosty” sposób implementacji Swaggera w aplikacji Spring MVC

85

Mam API ReSTFul napisane prostym Springiem (bez Spring Boota, bez fantazyjnych rzeczy!). Muszę zaimplementować w tym Swagger. Jak dotąd KAŻDA strona w Internecie doprowadzała mnie do szaleństwa tylko mylącymi konfiguracjami i rozdętym kodem, którego w ogóle nie znalazłem przenośnym.

Czy ktoś ma przykładowy projekt (lub zestaw szczegółowych kroków), które mogą mi w tym pomóc? W szczególności szukam dobrej próbki, która wykorzystuje swagger-springmvc. Wiem, że ma „próbki”, ale w najlepszym razie ezoteryczny kod jest zniechęcający.

Muszę wyjaśnić, że nie szukam „dlaczego Swagger jest po prostu najlepszy”. Nie używam (i nie będę używać) Spring Boot lub podobnego.

falisty
źródło
4
Na podstawie próbek zakładam, że masz na myśli github.com/adrianbk/swagger-springmvc-demo . Właściwie zachęcałbym cię do otwarcia zgłoszenia bezpośrednio na swagger-springmvc, ponieważ ważne jest, aby wiedzieli, że niektórzy z ich potencjalnych użytkowników mogą uważać, że dokumenty są nieodpowiednie, aby mogli je ulepszyć.
Ron

Odpowiedzi:

122

Springfox (specyfikacja Swagger 2.0, aktualna)

Springfox zastąpił Swagger-SpringMVC i obsługuje teraz obie specyfikacje Swagger 1.2 i 2.0. Klasy implementacji uległy zmianie, co pozwala na głębsze dostosowanie, ale wymaga trochę pracy. Dokumentacja uległa poprawie, ale musi jeszcze pewne szczegóły dodane do zaawansowanej konfiguracji. Starą odpowiedź na implementację 1.2 nadal można znaleźć poniżej.

Zależność Mavena

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.5.0</version>
</dependency> 

Minimalna implementacja wygląda mniej więcej tak samo, ale teraz używa Docketklasy zamiast SwaggerSpringMvcPluginklasy:

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.regex("/api/.*"))
            .build()
            .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
            .title("TITLE")
            .description("DESCRIPTION")
            .version("VERSION")
            .termsOfServiceUrl("http://terms-of-services.url")
            .license("LICENSE")
            .licenseUrl("http://url-to-license.com")
            .build();
    }

}

Twoja dokumentacja interfejsu API Swagger 2.0 będzie teraz dostępna pod adresem http://myapp/v2/api-docs.

Uwaga: jeśli nie używasz Spring Boot, powinieneś dodać zależność jackson-databind. Ponieważ springfox używa jackson do wiązania danych.

Dodanie obsługi interfejsu Swagger UI jest teraz jeszcze łatwiejsze. Jeśli używasz Maven, dodaj następującą zależność dla pliku webjar interfejsu użytkownika struktury Swagger:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.5.0</version>
</dependency>

Jeśli używasz Spring Boot, Twoja aplikacja internetowa powinna automatycznie pobierać niezbędne pliki i wyświetlać interfejs użytkownika pod adresem http://myapp/swagger-ui.html(dawniej:) http://myapp/springfox. Jeśli nie używasz Spring Boot, to jak wspomina yuriy-tumakha w poniższej odpowiedzi, będziesz musiał zarejestrować program obsługi zasobów dla plików. Konfiguracja Java wygląda następująco:

@Configuration
@EnableWebMvc
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

Nowa funkcja generowania dokumentacji statycznej również wygląda całkiem ładnie, chociaż sam jej nie wypróbowałem.

Swagger-SpringMVC (specyfikacja Swagger 1.2, starsza)

Dokumentacja Swagger-SpringMVC może być nieco zagmatwana, ale w rzeczywistości jest niezwykle łatwa do skonfigurowania. Najprostsza konfiguracja wymaga stworzenia SpringSwaggerConfigbeana i włączenia konfiguracji opartej na adnotacjach (co prawdopodobnie już robisz w swoim projekcie Spring MVC):

<mvc:annotation-driven/>
<bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />

Uważam jednak, że warto wykonać dodatkowy krok definiowania niestandardowej konfiguracji Swaggera za pomocą SwaggerSpringMvcPluginzamiast poprzedniego komponentu bean zdefiniowanego w XML:

@Configuration
@EnableSwagger
@EnableWebMvc
public class SwaggerConfig {

    private SpringSwaggerConfig springSwaggerConfig;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {
        this.springSwaggerConfig = springSwaggerConfig;
    }

    @Bean
    public SwaggerSpringMvcPlugin customImplementation(){

        return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
                .apiInfo(apiInfo())
                .includePatterns(".*api.*"); // assuming the API lives at something like http://myapp/api
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
            .title("TITLE")
            .description("DESCRIPTION")
            .version("VERSION")
            .termsOfServiceUrl("http://terms-of-services.url")
            .license("LICENSE")
            .licenseUrl("http://url-to-license.com")
            .build();
    }

}

Po uruchomieniu aplikacji powinieneś zobaczyć specyfikację API utworzoną pod adresem http://myapp/api-docs. Aby uzyskać fantazyjny interfejs Swagger UI, musisz sklonować pliki statyczne z projektu GitHub i umieścić je w swoim projekcie. Upewnij się, że projekt jest skonfigurowany do obsługi statycznych plików HTML:

<mvc:resources mapping="*.html" location="/" />

Następnie edytuj index.htmlplik na najwyższym poziomie katalogu Swagger UI dist. Na początku pliku zobaczysz JavaScript, który odwołuje się do api-docsadresu URL innego projektu. Edytuj to, aby wskazać dokumentację Swaggera projektu:

  if (url && url.length > 1) {
    url = url[1];
  } else {
    url = "http://myapp/api-docs";
  }

Teraz, gdy przejdziesz do http://myapp/path/to/swagger/index.html, powinieneś zobaczyć wystąpienie interfejsu użytkownika Swagger dla swojego projektu.

woemler
źródło
1
@MikhailBatcer: Zaktualizowałem odpowiedź o zależność Maven dla Springfox. Jest to jedyna zależność, którą musisz uwzględnić w swoim projekcie, chyba że chcesz również użyć interfejsu Swagger UI lub Static Docs.
woemler
2
wygląda na to, że adres URL interfejsu użytkownika to teraz /myapp/swagger-ui.html, a nie /
springfox
7
Dla kompletności: Metoda „regex” w przykładzie springfox „SwaggerConfig” pochodzi z „springfox.documentation.builders.PathSelectors.regex (String)”. Zajęło mi to trochę czasu,
zanim to rozgryzłem
2
PathSelectors.regex
Pozwoliłem
1
Warto zauważyć: jeśli dokładnie wykonasz te instrukcje i nie użyjesz SpringBoot, otrzymasz błąd w czasie wykonywania z powodu różnych wersji bibliotek springfox i springfox-ui pobranych z Maven. Zamiast tego zacznij od najnowszej wersji obu, jeśli to możliwe ( 2.5.0jak to piszę)
Kip
13

Interfejs użytkownika Springfox Swagger działa u mnie po dodaniu zależności WebJar i mapowań zasobów. http://www.webjars.org/documentation#springmvc

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.2.2</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>bootstrap</artifactId>
        <version>3.3.5</version>
    </dependency>

spring-servlet.xml:

<mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/"/>
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>

lub wiosenna adnotacja https://github.com/springfox/springfox-demos/blob/master/spring-java-swagger/src/main/java/springfoxdemo/java/swagger/SpringConfig.java

Swagger2 powinien być włączony

 @EnableSwagger2
 public class SwaggerConfiguration {
 }
Yuriy Tumakha
źródło
To mi bardzo pomogło, ale nadal otrzymuję 404 /swagger-resourcespodczas otwierania swagger-ui.html. Jakieś wskazówki? Może więcej mapowań zasobów?
Tim Büthe
Wygląda na to, że zasoby swagger nie są w kontekście głównym. Można to naprawić, mapując DispatcherServlet na kontekst główny. Przyjrzyj się rozwiązaniu problemu 983 i pytaniu. Jak skonfigurować interfejs Swagger-ui dla aplikacji innych niż springboot?
Yuriy Tumakha