You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vaadin 23生产模式下如何配置外部目录存储OSM瓦片文件

解决Vaadin Spring Boot应用外部加载OSM瓦片的方案

核心思路

通过Spring Boot的静态资源映射功能,将JAR外的本地瓦片目录直接暴露为Web可访问路径,避开Vaadin默认的JAR内资源打包逻辑,同时让Leaflet通过该路径加载瓦片。


步骤1:配置Spring Boot静态资源映射

创建Spring配置类,将外部瓦片目录映射为Web访问路径:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.PostConstruct;
import java.io.File;

@Configuration
public class TileResourceConfig implements WebMvcConfigurer {
    // 可通过application.properties配置路径,这里示例用应用启动目录下的external-osm-tiles文件夹
    private final String externalTilesDir = System.getProperty("user.dir") + "/external-osm-tiles/";

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 将外部目录映射到/tiles/**路径
        registry.addResourceHandler("/tiles/**")
                .addResourceLocations("file:" + externalTilesDir)
                .setCachePeriod(3600); // 可选,设置瓦片缓存时长
    }

    @PostConstruct
    public void ensureTileDirExists() {
        // 启动时自动创建瓦片目录,避免404
        File dir = new File(externalTilesDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
    }
}

如果需要更灵活的路径配置,可通过application.properties注入:

# application.properties
osm.tiles.dir=./external-osm-tiles/

然后修改配置类注入路径:

@Value("${osm.tiles.dir}")
private String tilesDir;

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/tiles/**")
            .addResourceLocations("file:" + tilesDir)
            .setCachePeriod(3600);
}

步骤2:配置Leaflet加载外部瓦片

在Vaadin组件中初始化Leaflet时,将瓦片请求路径指向映射后的Web路径:

import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.page.JavaScript;
import com.vaadin.flow.router.Route;

@Route("map-view")
@JavaScript("https://unpkg.com/leaflet@1.9.4/dist/leaflet.js")
public class MapView extends Div {
    public MapView() {
        setId("map-container");
        setWidthFull();
        setHeight("700px");

        // 初始化Leaflet地图,瓦片路径用映射后的/tiles/**
        getElement().executeJs("""
            var map = L.map('map-container').setView([39.9042, 116.4074], 12);
            L.tileLayer('/tiles/{z}/{x}/{y}.png', {
                maxZoom: 18,
                attribution: '© OpenStreetMap contributors'
            }).addTo(map);
        """);
    }
}

步骤3:确保Maven不打包外部瓦片目录

在pom.xml中配置资源排除,避免误将外部目录打包进JAR:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <!-- 如果外部目录不在src/main/resources下,可跳过此配置 -->
                <exclude>external-osm-tiles/**</exclude>
            </excludes>
        </resource>
    </resources>

    <plugins>
        <plugin>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-maven-plugin</artifactId>
            <version>23.2.7</version>
            <executions>
                <execution>
                    <goals>
                        <goal>prepare-frontend</goal>
                        <goal>build-frontend</goal>
                    </goals>
                </execution>
            </executions>
            <!-- 无需配置extraJars/resourcesDirectory,外部目录由Spring直接访问 -->
        </plugin>
    </plugins>
</build>

关键注意事项

  • 部署到服务器时,需确保外部瓦片目录的绝对路径正确,且应用进程有读写权限
  • 如果瓦片命名规则不是{z}/{x}/{y}.png,需同步修改Leaflet的tileLayer路径参数
  • Vaadin默认不会拦截/tiles/**这类自定义路径,无需额外配置路由放行

内容的提问来源于stack exchange,提问作者Алексей Жуков

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:30:23