i am using swagger with spring mvc, the pom.xml
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
and in spring configuration.xml
<mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/" />
<mvc:resources mapping="/webjars/**"
location="classpath:/META-INF/resources/webjars/" />
also i use java-based configuration
#Configuration
#EnableSwagger2
#PropertySource("classpath:application.properties")
public class SwaggerConfig extends WebMvcConfigurerAdapter {
#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(" Admin Api").description("Admin Api").version("V1")
.termsOfServiceUrl("http://terms-of-services.url").license("LICENSE")
.licenseUrl("http://url-to-license.com").build();
}
}
in the controller i use
#Controller
#RequestMapping({ "/" })
#Api(value = "product", description = "Products Web Services") // Swagger annotation
public class ProductController {
#ApiOperation(value = "products", nickname = "Get list of all products", response = ProductListResponse.class)
#RequestMapping(value = "/products", method = RequestMethod.GET)
public #ResponseBody ProductListResponse getAllProducts(HttpServletResponse httpServletResponse) {
in application.propeties i added springfox.documentation.swagger.v2.path=/api-docs.
that is all information i used to generate documentation
using the url http://localhost:8080/admin-api/admin/api-docs , it doesnt generate documentation for the end points
{
swagger: "2.0",
info: {
description: " Admin Api",
version: "V1",
title: "Admin Api",
termsOfService: "http://terms-of-services.url",
license: {
name: "LICENSE",
url: "http://url-to-license.com"
}
},
host: "localhost:8080",
basePath: "/admin-api/admin"
}
Solved. after miss around many things i found the solution, i changed the method Docket api() to be
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build().apiInfo(apiInfo());
}
i think the the part PathSelectors.regex("/api/.*") on the old method was restricting the lookup process of the end points
Related
Has anyone tried adding Swagger-UI to projects running with Tomcat and Spring, but without Spring Boot?
My project runs on a Tomcat server, with spring. I want to add swagger-UI to see all the endpoints but I can't implement it.
I tried with all kinds of dependencies and configurations but I didn't manage to finish it.
This is my configuration:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.betfair"})
#Import(SwaggerConfig.class)
public class AppConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
}
#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/");
}
}
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo("My REST API", "Some custom description of API.", "API TOS", "Terms of service", "myeaddress#company.com", "License of API", "API license URL");
return apiInfo;
} }
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration implements WebSecurityCustomizer {
#Override
public void customize(WebSecurity web) {
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**");
}
}
// My pom.xml dependencies:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-schema</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.7.2</version>
</dependency>
What I am missing? Do I need more special configurations? Thanks.
Is there a way to make swagger private documentation? I have documentation that needs to be accessible and public and some "admin" methods just for my colleagues. Does the swagger have such functionality?
pom.xml
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
SpringFoxConfig.java
#Bean
public Docket admin() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.paths(PathSelectors.ant("/admin/**"))
.apis(RequestHandlerSelectors.basePackage("mypackage"))
.build()
.groupName("admin")
.tags(new Tag(USER, "User controller"))
.apiInfo(apiDetails())
.useDefaultResponseMessages(false);
}
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.paths(PathSelectors.ant("/api/**"))
.apis(RequestHandlerSelectors.basePackage("my package"))
.build()
.groupName("api")
.tags(new Tag(USER, "User controller"))
.apiInfo(apiDetails())
.useDefaultResponseMessages(false);
}
So I want my admin endpoints be accessible only for admins.
I do not use .yaml file for my docs, just annotating methods.
Using Spring Fox 2.9.2 with Spring Boot 2.1.5 RELEASE, I am not able to use the interactive UI generated by Swagger.
This is with the REST Endpoints not expanded:
This is with the REST Endpoint expanded (as you can see there's no text field to type the id inside):
Maven pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
Swagger2Config.java:
package com.myservice.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Configuration
#EnableSwagger2
public class Swagger2Config {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors
.basePackage("com.myservice"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiEndPointsInfo());
}
private ApiInfo apiEndPointsInfo() {
return new ApiInfoBuilder().title("MyService API")
.description("Buildings you measure.")
.contact(new Contact(null, null, null))
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.version("1.0.0")
.build();
}
}
Also noticed is that I didn't need to use any Swagger specific annotations (e.g.#ApiOperation & #ApiResponse) inside the RestController (I did try putting them above getByUsingId(Integer id) method, and whereas my documentation was visible it still didn't have the id text field):
RestController:
#RequestMapping(value = {"/{id}" }, method = RequestMethod.GET, produces = "APPLICATION/JSON")
public ResponseEntity<Object> getByUsingId(#PathVariable(value = "id", required = true) Integer id)
throws IOException {
MyResponse response = myDao.getById(id);
if (response == null) {
return new ResponseEntity<Object>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<Object>(response, headers, HttpStatus.OK);
}
Comparing this to an old Spring Boot 1.5.6 RELEASE project, Spring Fox 2.6.1 has a much better UI and it is interactive (notice the better colors and the visible text field when expanded):
This is exactly what I need and want.
Maven pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
<scope>compile</scope>
</dependency>
<dependencies>
Swagger2Config.java:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.google.common.base.Predicates;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#EnableSwagger2
#Configuration
public class SwaggerConfig {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(Predicates.not(PathSelectors.regex("/error"))).build().apiInfo(metaInfo());
}
private ApiInfo metaInfo() {
ApiInfo apiInfo = new ApiInfo("Hierarchy Project", "Hierarchy Demo as a Spring Boot based Microservice", "1.0", null,
new Contact("", "", ""), "", "");
return apiInfo;
}
}
RestController:
#ApiOperation(httpMethod = "GET", value = "Get All Records Within a Level of Hierarchy Based On Parent Node.",
notes = "List records within a level of the hierarchy, for a given parent node.",
produces = "application/json")
#ApiResponses(value =
{
#ApiResponse(code = 200, message = "Successful GET Command", response = String.class),
#ApiResponse(code = 404, message = "Not Found")
}
)
#RequestMapping(value = { "/api/nodes" }, method = RequestMethod.GET, produces = "APPLICATION/JSON")
public ResponseEntity<Object> getHierarchyByUsingNode(Node node) throws Exception {
if (null == node) {
return new ResponseEntity<Object>(HttpStatus.NOT_FOUND);
}
List<Node> nodes = nodeService.getHierarchyPerParentNode(node);
if (nodes.isEmpty()) {
return new ResponseEntity<Object>(HttpStatus.NOT_FOUND);
}
else {
return new ResponseEntity<Object>(nodes, headers, HttpStatus.OK);
}
}
When I tried using the Spring Fox 2.6.1 dependencies inside my Spring Boot 2.1.5.RELEASE project, the swagger-ui.html page didn't even render!
As one can notice that whereas Spring Fox 2.9.2 doesn't need annotations, generated swagger-ui.html page not only looks different (in terms of colors, etc) but it doesn't even have any text fields like my second example, Hierarchy Project, does.
Question(s):
Is this a possible bug (the non-interactive text field) in Spring Fox 2.9.2?
Why is the swagger-ui looked dumbed down (the colors being different & not being so sharp looking, etc)?
Figured it out... The older versions of Swagger used the "Try it Out" button to execute the REST calls...
Now, it's a two-step process, you have to click on the "Try it Out" button first, enter in the id inside the text field, and then click on the very horizontally long blue "Execute" button.
This was a horrible change (in terms of aesthetics and UI design) and is not that intuitive as the previous design was.
Try to add this to your pom.xml
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
and also
#Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("myPackage"))
.paths(PathSelectors.any())
.build();
}
where myPackage is the package that contains the Spring boot starter class.
Hope it will solve your problem. :)
I am using below swagger maven depedepncy.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
<scope>compile</scope>
</dependency>
Config
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.it"))
.build()
.tags(new Tag("Admin API", "Admin interface to manage users"));
}
Controller
#RequestMapping(value = "/kyc")
#Api(tags = {"Admin API"})
#SwaggerDefinition(tags = {
#Tag(name = "Admin API", description = "Admin interface to manage users")
})
public class KycController
But in swagger-ui, description of the Tag is not coming as Admin interface to manage users
Needless to say I know there are a ton of questions about this same subject but I've been stuck trying to fix this for 2 days now and most of what I've read is outdated.
So yeah.. this is what I have right now:
Gradle:
dependencies {
compile 'org.springframework.cloud:spring-cloud-starter-hystrix'
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'org.springframework.boot:spring-boot-starter-security'
compile 'org.springframework.ws:spring-ws-core'
compile 'io.springfox:springfox-swagger2:2.4.0'
compile 'io.springfox:springfox-swagger-ui:2.4.0'
}
Main class:
#EnableSwagger2
public class Application {
public static void main(String[] args) {
SpringApplication.run(FeedServiceApplication.class, args);
}
#Bean
public Docket swaggerSettings() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.pathMapping("/");
}
When I visit: http://localhost:8080/v2/api-docs, I get the json documentation just fine. Also when I download swagger-ui from github, set the source to the link above and run it on desktop, it also works fine. What doesn't work is putting these 2 things together (getting it to work at http://localhost:8080/swagger-ui.html).
There are many tutorials such as these, where they claim the stuff above will make swagger-ui work:
http://kubecloud.io/guide-using-swagger-for-documenting-your-spring-boot-rest-api/
http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api
And a ton of other tutorials where they instruct you to add dist folder from swagger-ui git to your project.
Also mapping like this:
#Configuration
#EnableWebMvc
public class WebConfig 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/");
}
}
Fails as well, throwing Scope 'request' is not active for the current thread; exception.
After trying some tutorials from youtube, the ones linked above and many others, all I've seen is "page not found". If anyone could explain what I'm missing I would be very grateful.
TL:DR How do I get swagger-ui.html to work?
EDIT: found the solution.
In case anyone else stumbles upon this, the problem is that if you have a request mapping that takes in a parameter #RequestMapping("/{param}"), dispatcherServlet no longer maps /** to ResourceHttpRequestHandler. The code below fixes that issue.
#Configuration
#EnableAutoConfiguration
#EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurerAdapter{
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
#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/");
}
}
That's what we use as setup. A class for its own annotated with #Configuration
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(Predicates.not(PathSelectors.regex("/error")))
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfo(
"APP NAME",
"APP DESCRIPTION",
"1.0",
null,
new Contact("Firstname Lastname", null, "firstname.lastname#somewhere.net"),
null,
null);
}
}
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spi</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-core</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-spring-web -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>${swagger.version}</version>
</dependency>
Convert the above dependency to gradle.
Version i used is 2.3.1
package XXXX;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#EnableSwagger2
public class SwaggerConfiguration {
}
We enabled the Swagger Config as stated above.
You can add Docket bean for custom headers:
#Bean
public Docket docket() {
Parameter parameterAuthorization =
new ParameterBuilder().name("Authorization").description("Authentication of the API User")
.modelRef(new ModelRef("string")).parameterType("header").required(true).build();
Parameter parameterClientUserId =
new ParameterBuilder().name("user_id").description("Client user identifier")
.modelRef(new ModelRef("string")).parameterType("header").required(true).build();
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build()
.globalOperationParameters(Lists.newArrayList(parameterClientUserId, parameterAuthorization));
}
And finally import the Swagger config in Main Application Class on Spring boot
#Import({SwaggerConfiguration.class})