Unable to link Swagger-ui to my swagger Spring mvc project
This issue seems old but just to share, with the recent version of swagger-springmvc and springmvc-ui, it has become very easy and less complicated to integrate swagger & swagger-ui with your web service to see in production REST api documentation.
@EnableSwagger annotation is added that enables swagger-springmvc out of the box. The generated swagger json Resource Listing can be accessed at /api-docs.
You may refer to following link for the steps on integrating swagger-springmvc and swagger-ui with your spring mvc project. https://github.com/martypitt/swagger-springmvc
Tekateyy
Updated on June 17, 2022Comments
-
Tekateyy almost 2 years
I'm currently creating an API Rest using Eclipse, Spring Framework MVC, and I just added to my project swagger. I can access the json result of swagger but I need to add swagger ui.
Here are all my files creating for 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; } }
Here are my 3 files to add swagger to my project, atm I just decide to check just 1 method which is :
@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; } }
My results : I can access the following url
http://localhost:8080/ApiDark/ws/api-docs
but I get the json value like :{"apiVersion":"1","swaggerVersion":"1.2","authorizations":{"basicAuth":{"type":"basicAuth"}},"info":{"title":"Swagger Spring MVC for Dark Api","description":"Sample application demonstrating how to use swagger-springmvc in a no-XML environment.","termsOfServiceUrl":"http://en.wikipedia.org/wiki/Terms_of_service","contact":"[email protected]","license":"Apache 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.html"}}
That's why I decided to add swagger-ui. I add the content of dist folder (taken from swagger-ui) to my src/main/webapp folder. And modify the content of index.html to point to my url :
<script type="text/javascript"> $(function () { window.swaggerUi = new SwaggerUi({ url: "http://localhost:8080/ApiDark/ws/api-docs.json", dom_id: "swagger-ui-container",
But I can't access to swagger-ui interface, I just have the json result... Need help to make it work please !
-
Tekateyy almost 10 yearsThanks, but I found a work-around by redirecting the web.xml to the swagger index.html ;)
-
plzdontkillme about 9 yearsEven though I am using @EnableSwagger, I am seeing the same issue.
-
spiderman over 8 yearsplease refer this : stackoverflow.com/questions/26807791/…