2014-04-17 15 views
6

Obecnie tworzę interfejs API odpoczynku przy użyciu Eclipse, Spring Framework MVC i właśnie dodałem do mojego projektu swagger. Mogę uzyskać dostęp do wyniku json'a, ale muszę dodać ui.Nie można powiązać aplikacji Swagger-ui z moim projektem Spring McVc

Oto wszystkie moje pliki tworzące dla 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", 
      "[email protected]", "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; 
    } 
} 

Oto moje 3 pliki, aby dodać puszyć do mojego projektu, bankomat po prostu decydują się sprawdzić tylko 1 metodę, która jest:

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

Moje wyniki: Mogę wejść na następującą stronę http://localhost:8080/ApiDark/ws/api-docs ale mogę wartość json jak:

{ "apiVersion": "1", "swaggerVersion": "1.2", "zezwolenia" { "BasicAuth" { "typ": "podstawowe jest"}} "informacji ": {" title ":" Swagger Spring MVC dla Dark Api "," description ":" Przykładowa aplikacja demonstrująca sposób użycia swagger-springmvc w środowisku bez XML. " "TermsOfServiceUrl":" http://en.wikipedia.org/wiki/Terms_of_service " "kontakt": "[email protected]", "licencja": "Apache 2.0", "licenseUrl":" http://www.apache.org/licenses/LICENSE-2.0.html „}}

Dlatego zdecydowałem dodać swagger-ui. Dodałem zawartość folderu dist (pobranego z swagger-ui) do mojego folderu src/main/webapp. I modyfikować zawartość index.html zwrócić do mojego url:

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

Ale nie może uzyskać dostępu do interfejsu swagger-UI, mam tylko wynik json ... Potrzebna pomoc, aby to działało proszę!

+0

masz odpowiedź dobrze wyjaśnione tutaj: http://stackoverflow.com/questions/26807791/integrating-swagger-in-spring-mvc – spiderman

Odpowiedz

0

Co masz na myśli przez "Nie mogę uzyskać dostępu do interfejsu użytkownika swagger-ui"?

W moim przypadku przeglądarka nie załadowała pliku index.html (chyba 404), który miałem w podfolderze razem z wszystkimi plikami dist: webapp/doc/index.html. Musiałem wyłączyć podfolder z mapowania serwletu w web.xml jak krótko opisane tutaj: Java swagger with JaxRS throwing errors

Moja web.xml fragment wygląda tak wreszcie:

<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> 

(dlaczego to działa zobaczyć tutaj: http://blog.ericdaugherty.com/2010/02/excluding-content-from-url-pattern-in.html)

Nadzieję, że pomaga!

+0

Dzięki, ale znalazłem obejście poprzez przekierowanie web.xml to the swagger index.html;) – Tekateyy

3

Ten problem wydaje się stary, ale po to, aby udostępnić, z najnowszą wersją oprogramowania swagger-springmvc i springmvc-ui, integracja z usługą WWW, aby zobaczyć w trybie REST produkcji, stała się bardzo łatwa i mniej skomplikowana. dokumentacja api.

Adnotacja @EnableSwagger została dodana, dzięki czemu można wyskoczyć-wyskakują-springmvc z pudełka. Wygenerowany artykuł Json Resource Listing można uzyskać w/api-docs.

Możesz odwołać się do poniższego linku, aby zapoznać się z krokami integracyjnymi: swagger-springmvc i swagger-ui z twoim wiosennym projektem mvc. https://github.com/martypitt/swagger-springmvc

+0

Mimo że używam @EnableSwagger, widzę ten sam problem. – plzdontkillme

+0

proszę odnieść się do tego: http://stackoverflow.com/questions/26807791/integrating-swagger-in-spring-mvc – spiderman