Add context path to requests in swagger - spring-boot

I have an eureka service which has a swagger. The eureka is on http://localhost:8050
and the service goes by name /service. The issue is that when i open swagger and try to make a request, it sends it to http://localhost:8050/service/somecontroller. The service has a context path "path" so it should be http://localhost:8050/service/path/somecontroller. This is the configuration of the swagger:
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("com.test")).paths(PathSelectors.any())
.build();
}

Springfox has an open issue (#2817) for your case, you can try one of the workarounds proposed by some users there.

Managed to change the context path of the swagger like this:
#Value("${contextPath}")
private String contextPath;
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
//.host(retrieveHostHostname())
.pathProvider(new PathProvider() {
#Override
public String getApplicationBasePath() {
return contextPath;
}
#Override
public String getOperationPath(String s) {
return s.replace("somecontroller", contextPath+"/somecontroller");
}
#Override
public String getResourceListingPath(String s, String s1) {
return "/";
}
}).select()
.apis(RequestHandlerSelectors.basePackage("com.test")).paths(PathSelectors.any())
.build();
}

Related

Spring Boot instinitate #Bean according to Condition

im working in spring boot project where i want to instantiate a Restemplate Bean with Interceptors , my issue that i don't want to duplicate the code because there is just the header that changes for each conciguration. this is my code :
#Bean
#Qualifier("restTemplateOne")
public RestTemplate restTemplateWithAccessToken() {
return new RestTemplateBuilder()
.interceptors((HttpRequest request, byte[] body, ClientHttpRequestExecution execution) -> {
//this is the only header that i want to add for
request.getHeaders().set("MY_PARTICULAR_HEADER", "my value");
request.getHeaders().set(HttpHeaders.AUTHORIZATION,"my auth value");
return execution.execute(request, body);
}).build();
}
#Bean
#Qualifier("restTemplateTwo")
public RestTemplate restTemplateWithIdToken() {
return new RestTemplateBuilder()
.interceptors((HttpRequest request, byte[] body, ClientHttpRequestExecution execution) -> {
request.getHeaders().set(HttpHeaders.AUTHORIZATION,"my auth value");
return execution.execute(request, body);
}).build();
}
#Autowired
#Qualifier("restTemplateOne")
private RestTemplate restTemplateOne;
#Autowired
#Qualifier("restTemplateTwo")
private RestTemplate restTemplateTwo;
do you have any idea how i can optimize code to avoid duplication . something like adding a parameter to the method and adding the header or not according to the condition.
Thanks in advance.
Just extract and parameterize your interceptor:
#Bean
#Qualifier("restTemplateOne")
public RestTemplate restTemplateWithAccessToken() {
return new RestTemplateBuilder()
.interceptors(new CustomClientHttpRequestInterceptor(true))
.build();
}
#Bean
#Qualifier("restTemplateTwo")
public RestTemplate restTemplateWithIdToken() {
return new RestTemplateBuilder()
.interceptors(new CustomClientHttpRequestInterceptor(false))
.build();
}
private static class CustomClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private boolean needParticularHeader;
public CustomClientHttpRequestInterceptor(boolean needParticularHeader) {
this.needParticularHeader = needParticularHeader;
}
#Override
public ClientHttpResponse intercept(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution) throws IOException {
if (needParticularHeader) {
//this is the only header that i want to add for
request.getHeaders().set("MY_PARTICULAR_HEADER", "my value");
}
request.getHeaders().set(HttpHeaders.AUTHORIZATION, "my auth value");
return execution.execute(request, body);
}
}

Swagger Ui hangs for api endpoint in spring boot

My client api endpoint is not loading in swagger UI as shown in the image what I need to do? It always show loading icon when I click on any client controller api like get,post
Please post answer Thank You
see picture
SwaggerConfig.groovy
#Configuration
#EnableSwagger2
class SwaggerConfig {
#Bean
Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any()
.paths(PathSelectors.any())
.build().apiInfo(metaData())
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("Swagger Example")
.description("\"Swagger configuration for application \"")
.version("1.1.0")
.license("Apache 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.build()
}
}
ClientController.groovy
#RestController
#RequestMapping('/client')
class ClientController {
#Autowired
ClientService clientService
#GetMapping('/')
ResponseEntity<List<Client>> getAllClients() {
List<Client> clients = clientService.getAllClients()
return new ResponseEntity<>(clients, HttpStatus.OK)
}
#GetMapping('/{clientId}')
ResponseEntity<Client> getClientById(#PathVariable("clientId") Integer clientId) {
return new ResponseEntity<>(clientService.getClientById(clientId), HttpStatus.OK)
}
#PostMapping('/create')
ResponseEntity<Client> createClient(#RequestBody Client client) {
return new ResponseEntity<>(clientService.addClient(client), HttpStatus.CREATED)
}
#PutMapping('/update/{clientId}')
ResponseEntity<Client> updateClient(#PathVariable("clientId") Integer clientId, #RequestBody Client client) {
clientService.updateClient(client, clientId)
return new ResponseEntity<>(clientService.getClientById(clientId), HttpStatus.OK)
}
#DeleteMapping('/delete/{clientId}')
ResponseEntity<Client> deleteClient(#PathVariable("clientId") Integer clientId) {
clientService.deleteClientById(clientId)
return new ResponseEntity<>(HttpStatus.NO_CONTENT)
}
}

Hide a method in SpringFox swagger-ui

I'm using SpringFox 3.0.0 in a SpringBoot (2.6.2) project.
My SpringBoxConfig.class file is:
/** SpringFoxConfig. */
#Configuration
#EnableSwagger2
#ComponentScan(basePackageClasses = {
CcController.class,
AreaController.class,
SubAreaController.class,
ProcController.class
})
public class SpringFoxConfig {
public static final String AREAS = "Areas";
public static final String AREAS_DESC =
"Provides access to Areas endpoints in ms-filters.";
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors
.basePackage(
"com.munidigital.bookingform.bffweb.application.web.incoming"))
.paths(PathSelectors.any())
.build()
.tags(new Tag(AREAS, AREAS_DESC))
.apiInfo(getApiInfo());
}
...
My AreaController.java is:
/** AreaController. */
#Api(tags = SpringFoxConfig.AREAS)
#RestController
public class AreaController {
#GetMapping(value = {"/v1/areas/", "/v1/areas/{id}"})
public ResponseEntity<?> read(
#PathVariable(required = false) Optional<Long> id) {
LOG.info("AreaController: read");
...
return response;
}
...
The output is:
My problem:
I need to hide the operation (/bookingform/api/web/v1/areas/) and just show /bookingform/api/web/v1/areas/{id}.
I want to see something like this:
I've tried #ApiIgnore, #Hidden, and #ApiOperation(hidden=true) but no results were achieved since I don't know how to indicate which is the URI that I want to hide. Both are shown or hidden. I couldn't get it to show only one.

springboot Multiple Dockets with the same group name are not supported

I have the follwoing spring boot configuration for swagger, when service starts up i get the following error, im not sure exactly why this would be the case. I have followed a tutorial and it works for them.
java.lang.IllegalStateException: Multiple Dockets with the same group name are not supported. The following duplicate groups were discovered. default
#Configuration
#EnableSwagger2
#Import(BeanValidatorPluginsConfiguration.class)
public class SpringFoxConfig {
#Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("test.rest"))
.paths(PathSelectors.ant("/test/**"))
.build()
.apiInfo(apiInfo());
}
// Describe the apis
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("test")
.description("Test")
.version("1.0.0")
.license("vvv")
.build();
}
}
i also have another config
#OurApp
#EnableSwagger2
public class CoreApp extends OurApp {
}
Here you are trying to do multiple Dockets with the same group name, which is not acceptable. Please review the link provided.
groupName(java.lang.String groupName) If more than one instance of
Docket exists, each one must have a unique groupName as supplied by
this method. Documentation
public class Docket implements DocumentationPlugin {
public static final String DEFAULT_GROUP_NAME = "default";
}
You can see above DocumentPlugin has groupname as "default".
public Docket(DocumentationType documentationType) {
this.apiInfo = ApiInfo.DEFAULT;
this.groupName = "default";
And above has "default" as group name.
So, you need to have two different group names for both the Dockets.
All you need to do is change your code as below: overwrite the existing default groupname.
#Configuration
#EnableSwagger2
#Import(BeanValidatorPluginsConfiguration.class)
public class SpringFoxConfig {
#Bean
public Docket apiDocket() {
String groupName = "Swagger";
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("test.rest"))
.paths(PathSelectors.ant("/test/**"))
.build()
.groupName(groupName)
.apiInfo(apiInfo());
}
// Describe the apis
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("test")
.description("Test")
.version("1.0.0")
.license("vvv")
.build();
}
}
Seems like you have given the same group name which is not accepted, please check and set the group name properly.

Not able to get Swagger UI with spring boot

I am following the article at http://raibledesigns.com/rd/entry/documenting_your_spring_api_with.
Everything works fine but not able to integrate Swagger UI.
http://localhost:8080/docs/index.html
results in /error redirection.
I know this is an old question but maybe this will help someone with the similar problem in the future.
I followed similar tutorial to the one you mentioned and I made it work without a problem. I put my own document on how to setup a Swagger with UI in a Spring boot project couple of weeks ago. Maybe it will help you out since it is shorter and more up-to-date.
Add Maven dependencies
Stick these in your pom.xml:
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>1.0.2</version>
<type>jar</type>
</dependency>
Add Swagger UI
Download the Swagger UI from github. Copy the dist folder into your webapp directory and rename dist to swagger (or any name you like).
Open the index.html file inside the copied directory and change the url in the first javascript function so it points to the /api-docs endpoint:
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "/project-name/api-docs";
}
Configure Swagger
Create a SwaggerConfig.java class and configure swagger there:
#Configuration
#EnableSwagger
#EnableAutoConfiguration
public class SwaggerConfig {
private SpringSwaggerConfig springSwaggerConfig;
#Autowired
public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {
this.springSwaggerConfig = springSwaggerConfig;
}
#Bean
public SwaggerSpringMvcPlugin customImplementation() {
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
// Root level documentation
.apiInfo(new ApiInfo("Swagger-demo JSON API", "This service provides a JSON representation the service API", null, null, null, null))
.useDefaultResponseMessages(false)
// Map the specific URL patterns into Swagger
.includePatterns("/greeting.*");
}
}
Your swagger should be up and running now. Try accessing /project-name/swagger/index.html.
I'm answering this with swagger2 configuration inside a gradle based spring boot application. Following are the configuration required for Swagger2.
Add Gradle Configuartion
Add Gradle dependencies inside build.gradle file
dependencies {
compile("io.springfox:springfox-swagger2:2.0.2")
compile("io.springfox:springfox-swagger-ui:2.0.2")
}
Swagger2 Confugration Class
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket userApi() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build().pathMapping("/")
.directModelSubstitute(LocalDate.class, String.class)
.genericModelSubstitutes(ResponseEntity.class)
.alternateTypeRules(newRule(
typeResolver.resolve(DeferredResult.class,
typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
typeResolver.resolve(WildcardType.class)))
.useDefaultResponseMessages(false)
.globalResponseMessage(RequestMethod.GET,
newArrayList(new ResponseMessageBuilder().code(500).message("500 message")
.responseModel(new ModelRef("Error")).build()))
.securitySchemes(newArrayList(apiKey())).securityContexts(newArrayList(securityContext()))
.apiInfo(apiInfo());
}
#Autowired
private TypeResolver typeResolver;
private ApiKey apiKey() {
return new ApiKey("mykey", "api_key", "header");
}
private SecurityContext securityContext() {
return SecurityContext.builder().securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("/anyPath.*")).build();
}
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return newArrayList(new SecurityReference("mykey", authorizationScopes));
}
#Bean
SecurityConfiguration security() {
return new SecurityConfiguration("123456", "test-app-realm", "clientapp", "apiKey");
}
#Bean
UiConfiguration uiConfig() {
return new UiConfiguration("validatorUrl");
}
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo("DSM API", "API for DSM", "1.0.0", "termsOfServiceUrl",
"nijo#ndimensionz.com", null, null);
return apiInfo;
}
}
Add Swagger UI
Download the Swagger UI from github. Copy the dist folder into your src/main/resources/static directory and rename dist to swagger
HomeController.class
#Api(basePath = "/", value = "/", description = "Home Controller")
#Controller
public class HomeController {
#RequestMapping("/")
public String home() {
return "redirect:swagger-ui.html";
}
}
MyApplication.class
#SpringBootApplication
#ComponentScan(basePackageClasses = SwaggerConfig.class)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Configure your spring boot application with dependencies and run to see the API.
the url will be http://localhost:8080/v2/swagger-ui.html
you can also customize this as above answer.
I too face same problem. I was able to see json but not swagger ui after adding dest folder aslo. In initialize class which extends SpringBootServletInitializer I added below method then it was working perfect
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SampleWebStaticApplication.class);
}
please refer link
Here is my working configuration incase it helps anyone else
#Configuration
#EnableSwagger2
#Profile({"!production"})
public class SwaggerConfiguration extends WebMvcConfigurerAdapter {
#Autowired
private ServletContext servletContext;
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.host("localhost")
.directModelSubstitute(LocalDate.class, Date.class)
.pathProvider(new RelativePathProvider(servletContext) {
#Override
public String getApplicationBasePath() {
return "/docs";
}
})
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
Since I am also using Spring security, I also had to add the following to my whitelist:
private String[] swaggerWhiteList = {"/v2/api-docs", "/swagger-resources/configuration/ui", "/swagger-resources", "/swagger-resources/configuration/security", "/swagger-ui.html", "/swagger.json", "/webjars/**"};
Then I could access it using the following url:
http://localhost:8080/docs/swagger-ui.html

Resources