Spring mvc Swagger UI endpoint for two different URL pattern - java

I have two different url patterns one which starts with /api and second which starts with /svc. So, my question here is can we have two different swagger endpoint urls for these both API documentation using Swagger ?
I am using Spring MVC and Swagger for documentation purpose. Any hint please ? Thanks in advance!

#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
This has to help you.
The code:
apis(RequestHandlerSelectors.any())
will select all the apis from your controllers.

Related

Springfox - Is it possible to document a POJO via annotation if it's not used in a controller

As the title says, is it possible to include a POJO in a swagger doc if it's not used in a controller method?
I've tried using the #ApiModel annotation on the POJO class, i.e.:
#ApiModel("POJO")
public class Pojo {
...
}
However, unless the POJO is returned by a controller, I haven't been able to have it appear in the generated swagger docs. Is there a way to accomplish this?
I'm using springfox version 2.9.2, by the way.
It is possible with Springfox. You just have to modify your Docket. Add additionalModels method to your Docket implementation:
#Autowired
private TypeResolver resolver;
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
...
.additionalModels(resolver.resolve(Pojo.class));
}

RequestMapping URL pattern ending with jsp

I have a Controller in Spring Boot application
#Controller
public class MyController {
#RequestMapping("/vues/*.jsp")
public String views(HttpServletRequest request) {
return ((String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).substring(1);
}
}
And in application.properties
server.context-path=/myapp
spring.mvc.view.prefix=/WEB-INF/myapp/
The goal is to dispatch all my jsp in the WEB-INF/myapp/vues/ directory and to keep the exact comportement of the older app with .jsp URL
My app should work like this:
The user call http://myapp/vues/page.jsp
My app receive the call and find the handler in my controller because the URL match the RequestMapping url pattern
My handler return vues/pages.jsp
Spring Boot add /WEB-INF/myapp/ to find the good JSP file
I've already developed several Spring Boot apps which work perfectly, with JSP and so on. But it seems in that case, that url pattern ending with JSP won't work.
I try in the same app with #RequestMapping("/vues/*"), spring.mvc.view.suffix=.jsp in application.properties and a call to the same url but without .jsp at the end and it work.
Is there a solution to configure Spring Boot to accept *.jsp by RequestMapping?
NOTE: I've seen lots of posts talking about this subject but none of them answer to this question
UPDATE: I continue to develop without the ending jsp, but in the code I cover, there are calls to response.sendRedirect("../vues/view1"); or request.getRequestDispatcher("../vues/view1.jsp") and request.getRequestURI().endsWith("/vues/view1.jsp");. Everything seems a bit confusing. I know (beacause it was already done in the past!) is it posible to manage URL with ending .jsp. Why isn't this more popular? Why is it such a problem in springboot? Must I edit a web.xml file to manage this?
You need to enable the default servlet in one class of configuration. You can do this by this way:
#Configuration
#EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".html");
return resolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
After this you can use #RequestMapping("/some-mapping") without specifing the .jsp termination.

Swagger-ui.html not showing api list

I'm using spring boot + swagger 2 for documenting all the REST API .I'm able to list all the api of a controller when i have the below project structure.
If i move the swaggerconfig.java to the config package then i'm not able to list all api of a controller.i'm getting
This is my SwaggerConfig.java
#Configuration
#EnableAutoConfiguration
//#ComponentScan(basePackages="com.javainuse.swaggertest")
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket postsApi() {
return new Docket(DocumentationType.SWAGGER_2).groupName("public-api")
.apiInfo(apiInfo()).select().paths(postPaths()).build();
}
private Predicate<String> postPaths() {
return or(regex("/api/posts.*"), regex("/api/javainuse.*"));
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("JavaInUse API")
.description("JavaInUse API reference for developers")
.termsOfServiceUrl("http://javainuse.com")
.contact("javainuse#gmail.com").license("JavaInUse License")
.licenseUrl("javainuse#gmail.com").version("1.0").build();
}
}
What i'm doing wrong
I fixed the problem. The problem is browser cache. I just cleared all the cache, and then I'm able to get the swagger-ui.html with all api list.
what worked for me is:
#Bean
public Docket customImplementation(){
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("your base package"))
.paths(PathSelectors.any())
.build();
notice paths is not specific, its any.
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot")))
.apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.cloud")))
.apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.security")))
.build();
}
Although the OP issue was solved already, I stumbled upon this thread and my solution was somewhat different. Here it is for others should they find themselves in the same position:
I had the same issue, but with using swagger-codegen-maven-plugin (v3)
The API is defined in a api.yml specification file and I generate the interface and models with the plugin.
It has an option to also generate a controller, in which case it was showing in the UI. However when I configure the controllers to be ignored/skipped for generation and just implement my own it was not showing.
The problem was the package. The plugin also auto generates the SwaggerDocumentationConfig class which includes all controllers from the API package that is configured. My own controllers had to be in the exact same package.
Code snippets to clarify:
In my pom.xml I have configured the plugin with:
<apiPackage>a.b.c.spec.api</apiPackage>
The auto generated SwaggerDocumentationConfig class contains:
#Bean
public Docket customImplementation() {
return (new Docket(DocumentationType.SWAGGER_2)).select()
.apis(RequestHandlerSelectors
.basePackage("a.b.c.spec.api"))
.build().apiInfo(this.apiInfo());
}
My controller lives in the package a.b.c.api so I had to change the apiPackage property to align and the issue was resolved.
This solved my issue.
Add .pathMapping("/") in the Docket
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.pathMapping("/");
I am working on maven based Java Spring Boot project.
In my case, it was a version mismatch of swagger and swagger-ui dependency in pom.xml
In my scenario, it's because of the #Profile("dev") configuration in SwaggerConfig limited for dev profile only, while I was running with another profile.
Checking versions of Swagger-UI and springfox-swagger2 in pox.xml
Adding #EnableSwagger2 in application.java helped.

Swagger REST API documentation with Spring Boot

I want to use Swagger 2.0 with my Spring Boot RESTful web service to generate documentation. I have searched quite a bit for an answer to this. Basically I have a Spring Boot project with a set of controllers and I want to document the API's. I have the following dependencies setup in my POM file.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.5.0</version>
</dependency>
This is my Swagger configuration class with the #Configuration and #EnableSwagger2:
#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("My application title")
.description("This is a test of documenting EST API's")
.version("V1.2")
.termsOfServiceUrl("http://terms-of-services.url")
.license("LICENSE")
.licenseUrl("http://url-to-license.com")
.build();
}
}
From what I have gathered in reading a couple of other answers here that at this point I should be able to see something at a URL such as http://myapp/v2/api-docs or alternatively http://localhost:8080/myapp/api-docs I have made the assumption that the "myapp" portion of the above URL refers to the name of the class in which my main resides (is this correct)? Also I have tried this with port 8080 and port 80 and the bottom line is that I see nothing other than site can't be reached. I have looked at the answers provided here and here however I'm not having any success. Any help would be much appreciated, thank you in advance.
As you can see on the following documentation :
https://springfox.github.io/springfox/docs/snapshot/#springfox-swagger-ui
The endpoint is now on swagger-ui.html, for your case, it will be http://localhost:8080/myapp/swagger-ui.html
I used, <artifactId>springdoc-openapi-ui</artifactId> with
public class OpenApiConfiguration{
#Bean
public GroupedOpenApi abcApp(){
String[] abcAppRootPath={"com.stockoverflow.swagger"};
return GroupedOpenApi.builder().group("my app").packagesToScan(abcAppRootPath).build();
}
}
reference : https://springdoc.org/#getting-started

Spring-boot - how to use both Resteasy JAX-RS and Spring MVC controllers

I have a jax-rs resources which I am trying to convert to spring boot. I have made them work but looks like some of jax-rs resources which are included in project as dependencies from other projects. I know it should be a service! Anyway so I may be able to make change to that library and make them mvc compatible but is there another way I can make spring servlet work with both? I am using all java based configuration btw no xml.
Main application class is currently annotated as following unless I add "/" in url-mapping which moots the point of adding this. I don't even see why I should add this if dispatcher servlet can find handler for every / request.
#SpringBootApplication(exclude = { EmbeddedServletContainerFactory.class })
#EnableAsync
#ImportResource(value = { "classpath:springmvc-resteasy.xml" })
public class Application implements AsyncConfigurer, DisposableBean { .. }
I think with above spring DispatcherServlet is still at front in control and it knows of rest easy handleradapters. By default boot also maps everything under '/' so I dont understand why it doesnt work. I am getting 404 when hitting jax-rs uri, spring mvc uri works.
I tried to add following but after that everything stopped working.
#Bean
public ServletRegistrationBean initServlet(DispatcherServlet dispatcherServlet) {
ServletRegistrationBean servletRegistrationBean
= new ServletRegistrationBean(dispatcherServlet, false,"/jaxrs-api/*", "/mvc-api/*");
servletRegistrationBean
.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
return servletRegistrationBean;
}
I can see following beans are being loaded for resteasy upon context initialization.
resteasy.deployment
resteasy.registry
resteasy.dispatcher
resteasy.providerFactory
resteasy.spring.bean.processor
abstract.resteasy.handlerMapping
resteasy.handlerMapping
resteasy.handlerAdapter
resteasy.exception.handler
resteasy.no.resource.found.view
reateasy.error.view.resolver
It looks like things started working again after some try and errors which is not the way this should be! Spring-boot really should document here how it can work with spring mvc and jax-rs in co-existence.
Here's the sequence of changes I did.
I added #EnableWebMvc to my Application.java class or It can be on any other #Configuration class
#SpringBootApplication(exclude = { EmbeddedServletContainerFactory.class })
#EnableAsync
#EnableWebMvc
#ImportResource(value = { "classpath:springmvc-resteasy.xml" })
public class Application implements AsyncConfigurer, DisposableBean { .. }
In hindsight I knew this gonna create some problem and it did! My additional MessageConverter stopped working. I had following in Application.java
#Bean
public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper scalaObjectMapper = new ScalaObjectMapper();
//scalaObjectMapper.enable(features)
//objectMapper.registerModule(new DefaultScalaModule());
scalaObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jsonConverter.setObjectMapper(scalaObjectMapper);
return jsonConverter;
}
Now I had to move it to another config class which overrides WebMvcConfigurerAdapter to customize spring mvc beans.
#Component
#Configuration
public class WebMvcCustomConfig extends WebMvcConfigurerAdapter {
/**
* Registering Scala ObjectMapper
* #return
*/
#Bean
public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper scalaObjectMapper = new ScalaObjectMapper();
scalaObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jsonConverter.setObjectMapper(scalaObjectMapper);
return jsonConverter;
}
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//converters.add(ScalaObjectMapper);
super.configureMessageConverters(converters);
converters.add(customJackson2HttpMessageConverter());
}
}
So looks like now Spring MVC has some control rather then Spring Boot. I am sure this is gonna break loose when I have some additional components for example swagger2 integration or something similar.

Categories