I am building one spring cloud gateway and in that I am implementing Keycloak Security everything works fine but need to do programmatically instead of writing in yml file there can be multiple Realms.
Below are the dependencies which I am using:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
And my application Api gateway start application code is as below:
#SpringBootApplication
#ComponentScan(basePackages = {"com", "com.b","com.auth","com.security"})
public class APIGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(APIGatewayApplication.class, args);
}
#Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new PathBasedKeycloakConfigResolver();
}
}
Security Config http code is as below:
#Configuration
public class SecurityConfig {
#Bean
public SecurityWebFilterChain springSecurityFilterChain (ServerHttpSecurity http) {
http
.authorizeExchange()
.anyExchange()
.authenticated()
.and()
.oauth2Login(); // to redirect to oauth2 login page.
return http.build();
}
}
and in my application.yml file I am adding below configuration:
spring:
security:
oauth2:
client:
provider:
my-keycloak-provider:
issuer-uri: http://localhost:8280/auth/realms/Default
registration:
keycloak-spring-gateway-client:
provider: my-keycloak-provider
client-id: Default
client-secret: 8ZRUH62Pfhfde6uqasD8dfgdhvqWt03K6
authorization-grant-type: authorization_code
redirect-uri: '{baseUrl}/app'
main:
web-application-type: reactive
application:
name: app
cloud:
gateway:
default-filters:
- TokenRelay
So we can in configuration file I am manually adding configs for one Realms but there can be multiple realms in that how to do it programmatically dynamic? .
I am using "Spring Boot - 2.1.5.RELEASE" and "Spring framework - 5.1.7.RELEASE".
JMS listener annotation is not picking a message from a MQ queue. No error logs are rolling in my IntelliJ IDEA as well.
About my project - I am exposing a REST service which sends and receives a message from MQ (used JMSTemplate annotation). Till now it was working. Now I have to add another class which should listen for a queue. Hence added #JMSListener annotation which is not picking any message. Any insight will be really helpful.
The pom has below specified dependencies.
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>mq-jms-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
The class has below specified method.
import org.springframework.jms.annotation.JmsListener;
#Component
public class PickMyMessage {
#JmsListener(destination = "IN",containerFactory = "myFactory")
public void pullMyMessaage(String message){
System.out.println("Message is pulled..");
}
}
My main application has #EnableJMS annotation. In my application.yml file I have given below information.
ibm:
mq:
channel: MY.APP.SVRCONN
connName: 192.168.0.1(1415)
password: Pswd
queueManager: QM01
user: appsrv
My Bean class configs are
My JMS connection factory as below.
#Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
}
Not sure what else I am missing here. Any insight will be really helpful.
Instead of my existing project, if i create any simple demo project it is working as expected.
The class PickMyMessage is not a Spring bean, that's why Spring ignores it. Declare it as a #Bean or as a #Component.
May be there are further problems. But this is the first one that needs to be resolved.
I am unable to get the value I am expecting, An exception is thrown at this line #Value("${message:this-is-class-value}").
SERVER SIDE
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
src/main/resources/application.properties
server.port=8888
spring.application.name=config-service
spring.cloud.config.server.git.uri=file:///C:/config
management.endpoints.web.exposure.include=*
spring.security.user.name=root
spring.security.user.password=abc123
Application class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
#SpringBootApplication
#EnableConfigServer
public class ConfigServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServiceApplication.class, args);
}
}
Local git folder
Configurations files with the same property but the different value to detect
c:/config/application.properties
c:/config/api-gateway.properties
c:/config/api-gateway-PROD.properties
output while server startup
Completed initialization in 5 ms
WARN : Could not merge remote for master remote: null
INFO : o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/config/application.properties
if I access this url
http://localhost:8888/api-gateway/PROD
console output is as follows
WARN : Could not merge remote for master remote: null
INFO : o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/config/api-gateway-PROD.properties
INFO : o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/config/api-gateway.properties
INFO : o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/config/application.properties
CLIENT SIDE (Separate Project)
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
Application class
#SpringBootApplication
#EnableZuulProxy
#EnableDiscoveryClient
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
Controller
#RestController
public class SettingsController {
#Value("${message:this-is-class-value}")
String name = "World";
#RequestMapping("/")
public String home() {
return "Hello " + name;
}
}
resources/application.yml
server:
port: 8282
spring:
application:
name: api-gateway
eureka:
instance:
preferIpAddress: true
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
resources/bootstrap.yml
spring:
profiles:
active: PROD
cloud:
config:
name: api-gateway
uri: http://localhost:8888/
username: root
password: abc123
management:
endpoints:
web:
exposure:
include: refresh
Console output
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'settingsController': Injection of autowired dependencies failed; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.util.LinkedHashMap<?, ?>] to type [java.lang.String]
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.util.LinkedHashMap<?, ?>] to type [java.lang.String]
Please do let me know if anything else is required.
add message=Hello from property file1 in src/main/resources/application.properties. Or if you want to read this property from c:/config/application.properties or c:/config/config-service.properties you need to configure external configuration file by using #ConfigurationProperties annotation.
Looks, you are trying to use the #Value annotation on controller class which resides in your Cloud config server application. While the concept is like cloud config server application will be the provider to other applications and it can provide the properties from git or local file system (configuration) to requester client application. Other applications will connect to your config server application by providing it's URL, application name and profile for which it want to get the properties. You can check below URL for cloud config server and client application.
https://www.thetechnojournals.com/2019/10/spring-cloud-config.html
Your cloud config server has security configuration as below.
spring.security.user.name=root
spring.security.user.password=abc123
You client configuration doesn't provide any security configuration which is causing 401 error in your logs.
To solve this issue please do below changes to your client configuration.
Client configuration:
spring:
profiles:
active: PROD
cloud:
config:
name: api-gateway
uri: http://localhost:8888/
username: root
password: abc123
I'm having problems to set up a global OkHttp interceptor for my #FeignClient beans. I'm not experiencing any error, but the interceptor is being ignored.
My understanding is that Spring Cloud's auto configuration should pick the OkHttpClient.Builder bean that I'm declaring and use it to create the underlying OkHttpClient instances, but I might be wrong about this.
Here are the relevant parts of my Spring app:
#SpringBootApplication
#EnableFeignClients(defaultConfiguration = FeignConfig.class)
#EnableCircuitBreaker
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class);
}
}
#Configuration
public class FeignConfig {
#Bean
public MyInterceptor myInterceptor() {
return new MyInterceptor();
}
#Bean
public OkHttpClient.Builder okHttpClientBuilder(MyInterceptor interceptor) {
return new OkHttpClient.Builder().addInterceptor(interceptor);
}
}
public class MyInterceptor implements okhttp3.Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
System.out.println("Hey there, this is my request: " + request);
Response response = chain.proceed(request);
System.out.println("Hey there, this is my response: " + response);
return response;
}
}
The intercept method above is never called. I need MyInterceptor to be a Spring bean, because I need to inject other dependencies to it.
#FeignClient(name = "myClient", fallback = MyClientFallback.class)
public interface MyClient {
// method declarations
}
#Component
public class MyClientFallback implements MyClient {
// method fallback implementations
}
Here's the relevant part of my application.properties file:
feign.hystrix.enabled = true
feign.okhttp.enabled = true
ribbon.eureka.enabled = false
ribbon.eager-load.enabled = true
ribbon.eager-load.clients = myClient
myClient.ribbon.listOfServers = <IP_LIST>
myClient.ribbon.ServerListRefreshInterval = 10000
As you see from the properties declared above, I'm not using Eureka and I'm using Ribbon to load balance my rest client. I'm also using Hystrix to enable fallback responses and I have set the feign.okhttp.enabled property to true.
Below is the info about dependecies config and versions...
Spring Boot version is 2.0.3.RELEASE and Spring Cloud version is Finchley.SR1, while OkHttp version is 3.11.0.
In my pom.xml file, I have this spring-cloud-dependencies config:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencies>
</dependencyManagement>
I have also included the following Spring Boot and Spring Cloud dependencies, along with the OkHttp dependency:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
...
</dependencies>
You should provide an OkHttpClient bean as stated in the doc:
The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled or feign.httpclient.enabled to true, respectively, and having them on the classpath. You can customize the HTTP client used by providing a bean of either ClosableHttpClient when using Apache or OkHttpClient whe using OK HTTP.
https://github.com/OpenFeign/feign/blob/master/okhttp/src/main/java/feign/okhttp/OkHttpClient.java
The solution is to let Spring auto configuration do its job.
In order for that to happen, the following dependency must be removed from the pom.xml file:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
And the following one must be manually included:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
Once this is done, everything works as expected with the provided configuration.
Solution is to use OkHttpClient. Add pom.xml dependencies:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
and configure a bean:
#Configuration
public class FeignConfiguration {
#Bean
public OkHttpClient client() {
return new OkHttpClient();
}
}
Explanation: For 401, 407 and some other HTTP-status responses, bodies are replaced with null by HTTP clients used in Open Feign by default.
From OpenFeign: Currently in the feign.Default client there is a streaming mode enabled. You can see in the sun.net.www.protocol.http.HttpURLConnection following lines of code :
if (respCode == HTTP_UNAUTHORIZED) {
if (streaming()) {
disconnectInternal();
throw new HttpRetryException (RETRY_MSG2, HTTP_UNAUTHORIZED);
}
}
So if the streaming is enabled and you have 401 HTTP response code you will get empty errorStream, because there is no initialization. The feign client will try to get the errorStream as a body because there is a check
if (status >= 400) {
stream = connection.getErrorStream();
} else { stream = connection.getInputStream(); }
I'm trying to integrate my Spring Boot version 2.0.1.RELEASE with Swagger.
From this blog post it seemed like it will be easy by just adding two Maven dependencies and everything should work.
So I added the following dependencies to the pom:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
And created the SwaggerConfig bean:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
return docket;
}
}
And in the properties file I ended up with these 3 entries during the attempts to make it work:
spring.application.name=cat-service
management.server.servlet.context-path=/cat-service
server.servlet.contextPath=/cat-service
But at the end, when accessing
http://localhost:8080/cat-service/api/v2/api-docs
or the UI page at
http://localhost:8080/cat-service/swagger-ui.html
I get a page not found error.
I found this issues in the swagger github page and this question in stackoverflow but I was not able to change my 404 error.
I was able to make it work with Spring boot version 2.0.4.RELEASE and this blog post:
I added these 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>
And this configuration file:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Configuration
#EnableSwagger2
public class SpringFoxConfig {
#Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
And it worked.
The Swagger UI can be reached at /swagger-ui.html#
Please check the reference: https://springfox.github.io/springfox/docs/current/
"2.1.3. Migrating from existing 2.x version"
You can remove springfox-swagger2 and springfox-swagger-ui from your pom.xml and add springfox-boot-starter instead (for example version 3.0.0). Also you can remove the #EnableSwagger2 annotations
And: "swagger-ui location has moved from https://host/context-path/swagger-ui.html to https://host/context-path/swagger-ui/index.html OR https://host/context-path/swagger-ui/ for short. This makes it work much better with pulling it as a web jar and turning it off using configuration properties if not needed."
First add SwaggerConfig.java file at the same package of your springboot file like the following example.
#Configuration
#EnableSwagger2
#EnableWebMvc
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/");
}
}
try this
http://localhost:8080/spring-security-rest/api/swagger-ui.html
or
http://localhost:8080/spring-security-rest/swagger-ui.html
If that does not work, try to change the path in application.properties
Add this to application.properties:
server.servlet-path=/loop-service
and try the following urls:
http://localhost:8080/loop-service/swagger-ui.html (UI Docs)
http://localhost:8080/loop-service/v2/api-docs (JSON Docs)
Result :
OpenAPI
Just use springdoc-openapi-ui instead.
The Maven dependency:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.11</version>
</dependency>
Or Gradle:
implementation 'org.springdoc:springdoc-openapi-ui:1.6.11'
Links
UI: http://localhost:8080/swagger-ui.html
Json: http://localhost:8080/v3/api-docs
Yaml: http://localhost:8080/v3/api-docs.yaml
That's really all there is to it... No annotations / configuration needed. Cheers!
For Spring Security
If you are using spring security, make sure you can reach these paths for it to work:
"/swagger-ui.html" <-- for UI
"/swagger-ui/**" <-- for UI redirects
"/v3/api-docs/**" <-- for json docs and openapi configuration
"/v3/api-docs.yaml" <-- for yaml docs
For more information:
https://www.baeldung.com/spring-rest-openapi-documentation
I also had the same issue (404 Not Found with springfox 3.0.0). By setting the logging level to "DEBUG", I was able to see endpoints for /v3/api-docs and they worked, but there was nothing about "swagger-ui".
I finally found https://github.com/springfox/springfox/issues/3285, which indicates that:
the new url in 3.0.0 is /swagger-ui/index.html or /swagger-ui/ rather than /swagger-ui.html"
Could they not have added a debug log to indicate where the swagger UI is available?
Springfox swagger UI opens at path /swagger-ui/index.html.
Make sure you are allowing correct ResourceLocations and path excluded from interceptors
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
Note: i'm using Springfox swagger version 3.0.0 and Springboot version 2.5.3
This worked for me, I used the WebMvcConfigurer instead of the WebMvcConfigurerAdapter because that class is already deprecated.
#Configuration
#EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.illary.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(metaData());
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("Spring Boot Swagger App")
.description("\"Spring Boot Swagger Server App\"")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.build();
}
public ApiInfo apiInfo() {
final ApiInfoBuilder builder = new ApiInfoBuilder();
builder.title("Swagger Test App").version("1.0").license("(C) Copyright Test")
.description("The API provides a platform to query build test swagger api");
return builder.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/");
}
}
For Spring Boot, just use the dependency below, it's all it needs to work on the URL /swagger-ui/ (the trailing slash is mandatory).
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
Before trying that I was trying to use the classic dependencies of swagger2 and swagger-ui, and none of the suggested URLs were working.
Another possibility is the location of your Swagger config file; you need to place it at the same package or a subpackage of the spring boot file's.
Like the above picture:
Don't forget to change server.contextPath to server.servlet.contextPath if you upgrade Spring Boot to 2+.
Solution: You just need to remove #EnableWebMvc from the configuration classes.
Description: #EnableWebMvc turn on the class org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport. In spring-boot, there is an autoconfiguration class org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration, which has the annotation #ConditionalOnMissingBean(WebMvcConfigurationSupport.class).
What we get in the end: By adding #EnableWebMvc to the project, we ourselves become responsible for everything, since we turn off spring-boot auto-configuration.
After adding below line in application.properties, it started working
spring.web.resources.static-locations: classpath:/webapp/
But I'm not sure why do we have to add this.
Adding the code, which I think could be relevant. Dependencies are as below:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- Swagger 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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
And main class as
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#SpringBootApplication
#EnableSwagger2
public class ProxyApplication {
public static void main(String[] args) {
SpringApplication.run(ProxyApplication.class, args);
}
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.ghsatpute.proxy"))
.paths(PathSelectors.any())
.build();
}
}
Adding this if it can help somebody. This URL worked for me
http://localhost:8003/v2/api-docs
and for swagger-ui this url worked for me out of the box:
http://localhost:8003/swagger-ui.html
Check if you are using right configured url for swagger specs. The urls like http://localhost:8080/spring-security-rest/api/swagger-ui/
didn't work , and I had been getting 404.
Below are the steps to enable swagger in spring boot application:
Add springfox-swagger2 and springfox-swagger-ui dependencies.
To enable the Swagger2 in your project you should use #EnableSwagger2
Define a docket bean ad below
#Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2).groupName("group-name").apiInfo(apiInfo()).select().paths(predicate()).build();
}
private Predicate<String> predicate() {
return or(regex("/api/v1.*"), regex("/api/v2.*"));
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("The title of the your choice")
.contact("your#email.com").license("Licence name ").version("1.0").build();
}
Swagger UI url pattern:
localhost:<server.port>/<server.servlet.context-path>/swagger-ui.html
For anyone still looking for this, using OpenAPI 3.0, not Springfox, I got it running using WebMvcConfigurationSupport without the need of #EnableWebMvc.
The only Dependency needed:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.8</version>
</dependency>
I initially just got the JSON and a 404 on the UI.
What ultimately worked was adding the right resource handlers to my WebConfig and configuring my SecurityConfig to allow unrestricted access for everyone.
The resource handlers in my WebConfig:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/4.10.3/swagger-initializer.js")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/4.10.3/index.html")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/4.10.3/swagger-ui.css")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/4.10.3/index.css")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/4.10.3/swagger-ui-bundle.js")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/4.10.3/swagger-ui-standalone-preset.js");
}
Important was to add each one specifically (with version and everything, ** didn't work). Otherwise it wouldn't run in the cloud.
I also needed to add the paths "/v3/api-docs/**", "/swagger-ui/**" my SecurityConfig to allow access to these resources. So in my case I added those here:
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.addFilterBefore(...
.authorizeRequests().antMatchers("/v3/api-docs/**", "/swagger-ui/**", "...")...
}
and:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.GET, "/v3/api-docs/**", "/swagger-ui/**", "...");
}
It became working for me after removing #EnableWebMvc
Faced same issue just resolved with change in dependency
Refer https://www.vojtechruzicka.com/documenting-spring-boot-rest-api-swagger-springfox/
compile "io.springfox:springfox-swagger2:2.9.2"
Previously was using - Not working
compile group: 'io.springfox', name: 'springfox-swagger2', version: '3.0.0'
I was stuck for a day with this issue. My issue was incorrect port configuration. Check your application.yml/application.properties file for port configuration. There I had mistakenly added both
server.port , management.server.port with different values 🤣 .