flow
flow copied to clipboard
Swagger UI shows a blank page
Description of the bug / feature
In a Vaadin 18 + Spring app, swagger-ui page is not showing (returns a blank page) with errors in the console.
Minimal reproducible example
- Create a v18 Java project from start.vaadin.com
- Add the dependency
<dependencies>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.5.5</version>
</dependency>
- Change Vaadin mapping to a different path using
vaadin.urlMapping
inapplication.properties
. For example,
vaadin.url-mapping=/ui/*
- Run the server, and open http://localhost:8080/swagger-ui.html
Expected behavior
The Swagger UI page is opened
Actual behavior
Only a blank page is displayed with the following errors in the console
Versions:
- Vaadin / Flow version: 18.0.6
- Java version: 11
- OS version: Windows
Note, that Swagger UI seems to work fine in v14.X
Same error on
- Java version: 15
- OS version: Mac
The issue is most likely a generic one even though it's technically a Spring add-on issue.
It needs to be exactly vaadin.urlMapping
. vaadin.url-mapping
will not work, even though your IDE might suggest it. It's not a regular Spring Boot configuration property and as such it's treated a bit differently that than you might expect.
I am using vaadin flow 23, Java 17, Spring boot 2.7.0 and config not work.

Error message:

I think we don't need change vaadin base URL but we need config to set Vaadin servlet URL mapping having lowest priority in Spring. So it won't block other servlet mappings as CXF/swagger.
URL mapping priority maybe (Low to High): Spring servlet -> Vaadin servlet -> CXF/Swagger.
I figured it out. And it appears to be a bug, but there is a simple way to avoid it.
Vaadin version 22.0.18
Spring Boot version 2.4.6
I had the following application.yaml
vaadin:
url-mapping: /web/*
The problem is in this code below. Specifically in the name of the setting and how to get it by com.vaadin.flow.spring.RootMappedCondition
.
public class RootMappedCondition implements Condition {
public static final String URL_MAPPING_PROPERTY = "vaadin.urlMapping";
@Override
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {
return isRootMapping(
context.getEnvironment().getProperty(URL_MAPPING_PROPERTY));
}
We have the name of the setting "vaadin.urlMapping"
in camelCase, and according to the Spring Boot
specification it handles it by Relaxed Binding
rules and for it vaadin.url-mapping == vaadin.urlMapping
BUT the way to get the setting context.getEnvironment().getProperty(URL_MAPPING_PROPERTY)
knows nothing about these rules and only sees vaadin.urlMapping
To get the setting correctly, you need to get the VaadinConfigurationProperties
bean from the context, but at this stage it is not in the context and the setting will not be resolved by Relaxed Binding
rules from Spring Boot
So at this point you can easily bypass this problem and use the configuration name vaadin.urlMapping
in application.yaml
.
Sounds like what was fixed in https://github.com/vaadin/flow/pull/13791
The issue still happens even we change url-mapping. It is better to fix on issue #12949
@letrthang, I have the same setup (based on your screenshots) and it works for me. spring/issues#602 contains some details why simply changing the orders of the URL mappings for Vaadin and Spring's resource handlers won't help.
Also, judging from your screenshot, the issue in your case is that Spring handles Vaadin's path at /ui/
, so letting Vaadin ignore requests to certain URLs and let them pass on to Spring, wouldn't really help. Or has the error changed now?
Also, I can confirm that in the latest Vaadin version both vaadin.urlMapping
and vaadin.url-mapping
work now.
@Frettman it still doesn't work for me. I cannot access restful resource using postman and also swagger UI page doesn't show up.


@letrthang, that error from your first screenshot is not from Vaadin; Vaadin would show something like in the image from this Stackoverflow question.
Your error looks like something from Spring, so to me it seems like you have another issue.
Have you tried accessing /swagger-ui/index.html
directly? That's where /swagger-ui.html
should get redirected to.
@Frettman i created a test endpoint in vaadin demo project here, swagger still not work.
https://github.com/letrthang/vaadin23-flow-pro-components/blob/main/src/main/java/com/example/application/data/endpoint/TestSwaggerImpl.java

result:

Postman to send request also taken control by Vaadin handler:

@tarekoraby @denis-anisimov may i know you have any plan to fix this issue ?
@mshabarov, can someone from the Flow team please provide an update on this issue?
This seems to work fine.
npx @vaadin/cli init swag-test
cd swag-test
# Add springdoc-openapi-ui dependency
# Add url mapping
mvn
opening http://localhost:4444/swagger-ui.html shows the swagger UI
this config now will work with vaadin 23.2.1
vaadin.url-mapping=/web/*
springdoc.api-docs.path=/api/api-docs
springdoc.swagger-ui.path=/api/swagger-ui.html
However I prefer to get same config as Vaadin 14 as below which Vaadin home is root URL and allow to exclude swagger from root url (for now, this config is not working):
vaadin.url-mapping=/*
springdoc.api-docs.path=/api/api-docs
springdoc.swagger-ui.path=/api/swagger-ui.html
Anyway, there is other issue with open-api and Hilla:
Both springdoc-openapi-ui and Hilla using swagger-core and swagger-models with different versions, so causing swagger crashing.
Below config will work:
<properties>
<java.version>17</java.version>
<vaadin.version>23.2.1</vaadin.version>
<hilla.version>1.2.1</hilla.version>
</properties>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.7</version>
<!-- avoid conflict with hilla -->
<exclusions>
<exclusion>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
Below config will not work:
<properties>
<java.version>17</java.version>
<vaadin.version>23.2.1</vaadin.version>
<hilla.version>1.2.1</hilla.version>
</properties>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.11</version>
<!-- avoid conflict with hilla -->
<exclusions>
<exclusion>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
java.lang.NoSuchMethodError: 'io.swagger.v3.oas.models.media.ComposedSchema io.swagger.v3.oas.models.media.ComposedSchema.addAllOfItem(io.swagger.v3.oas.models.media.Schema)'
at dev.hilla.generator.OpenAPIObjectGenerator.lambda$parseNonEndpointClassAsSchema$24(OpenAPIObjectGenerator.java:524) ~[endpoint-1.2.1.jar:na]

I submitted new issue to Hilla here: https://github.com/vaadin/hilla/issues/551
Without the url mapping it seems that the Vaadin handler is invoked before the Swagger handler, preventing the swagger ui from showing. If this order is removed https://github.com/vaadin/flow/blob/master/vaadin-spring/src/main/java/com/vaadin/flow/spring/VaadinServletConfiguration.java#L61 the Swagger UI is shown but instead Vaadin views fail to render because of a 404
@Artur-, it's what I described in detail in vaadin/spring#602 and an attempt at a solution in vaadin/spring#604. Let's just say setting the URL mapping is much easier ;)
Thanks, I was just wondering if there really is no concept of "I want to handle some of the paths that match this mapping so ask me and if I say 'no thanks', then ask the next handler".
It sounds really impossible to be able to answer upfront "Will Vaadin handle this request" without actually letting Vaadin handle the request and see. The static cases like routes are easy, the dynamic code that you are able to add here and there is not.
So if the resource handler and the Vaadin handler could be combined so that if the first returns 404, the second one is consulted then magically everything would work..
This is fixed in https://github.com/vaadin/flow/pull/14579 but not in a fully automatic way. You can define paths to exclude, e.g. vaadin.excludeUrls=/swagger-ui/**
and those will not be handled by the vaadin servlet when it is mapped to /*