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

基于SpringBoot与GeoServer REST API的SLD文件编辑功能实现求助

SLD文件在线编辑功能实现方案

需求说明

  • 访问http://localhost:8055/edit-style/{stylere}时,页面展示带保存按钮的编辑表单,表单加载对应{stylere}.sld文件内容
  • SLD文件内容取自GeoServer REST接口http://10.56.56.66:8081/geoserver/rest/styles/{stylere}.sld
  • 前端通过调用后端GET接口http://localhost:8055/{stylere}获取文件内容
  • 点击保存按钮时,通过PUT请求提交修改内容,更新GeoServer中的SLD文件

1. 完整SpringBoot后端代码

package exp.tries;

import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@RestController
public class StyleController {

    private final WebClient webClient;

    public StyleController(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.baseUrl("http://10.56.56.66:8081/geoserver/rest/styles")
                .defaultHeader(HttpHeaders.AUTHORIZATION, createBasicAuthHeader())
                .build();
    }

    private String createBasicAuthHeader() {
        String auth = "geoserver:geoserver";
        byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8));
        return "Basic " + new String(encodedAuth);
    }

    @GetMapping(value = "/{style}", produces = MediaType.TEXT_PLAIN_VALUE)
    public Mono<String> getStyleContent(@PathVariable String style) {
        return webClient.get()
                .uri("/" + style + ".sld")
                .accept(MediaType.APPLICATION_XML)
                .retrieve()
                .bodyToMono(String.class);
    }

    @GetMapping("/edit-style/{stylere}")
    public ClassPathResource getEditStylePage(@PathVariable String stylere) {
        return new ClassPathResource("/templates/edit_style.html");
    }

    @PutMapping(value = "/{style}", consumes = MediaType.APPLICATION_XML_VALUE)
    public Mono<ResponseEntity<String>> updateStyle(@PathVariable String style, @RequestBody String newContent) {
        return webClient.put()
                .uri("/" + style + ".sld")
                .contentType(MediaType.APPLICATION_XML)
                .body(BodyInserters.fromValue(newContent))
                .retrieve()
                .toEntity(String.class)
                .map(response -> {
                    if (response.getStatusCode().is2xxSuccessful()) {
                        return ResponseEntity.ok("SLD文件内容已更新");
                    } else {
                        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                                .body("更新SLD文件内容时出错");
                    }
                })
                .onErrorReturn(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                        .body("请求GeoServer时发生错误"));
    }
}

后端修正点说明

  • 调整GET接口的produces为TEXT_PLAIN_VALUE,避免JSON格式解析问题
  • 补全PUT接口并整合到Controller中,修正语法错误
  • 为PUT请求添加contentType配置,与GeoServer接口要求匹配
  • 优化错误处理逻辑,返回明确的状态信息

2. 修正后的前端HTML代码

<!DOCTYPE html>
<html>
<head>
    <title>SLD文件编辑</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/codemirror.min.css">
</head>
<body>
    <h1>编辑SLD文件</h1>
    <form id="sldForm">
        <textarea id="sldContent" rows="10" cols="80"></textarea>
        <br>
        <button type="button" onclick="saveChanges()">保存</button>
    </form>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/codemirror.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.62.0/mode/xml/xml.min.js"></script>

    <script>
        // 从URL路径提取样式名称
        const urlParts = window.location.pathname.split('/');
        const styleName = urlParts[urlParts.length - 1];
        const apiUrl = `/${styleName}`;

        const sldContentTextarea = document.getElementById('sldContent');
        const codeMirrorInstance = CodeMirror.fromTextArea(sldContentTextarea, {
            mode: 'xml',
            lineNumbers: true,
            theme: 'default',
            indentUnit: 4,
            lineWrapping: true
        });

        // 加载SLD内容
        function fetchAndSetContent() {
            fetch(apiUrl)
                .then(response => {
                    if (!response.ok) throw new Error(`HTTP错误: ${response.status}`);
                    return response.text();
                })
                .then(content => {
                    codeMirrorInstance.setValue(content);
                })
                .catch(error => {
                    console.error('加载SLD内容失败:', error);
                    alert('加载SLD内容失败,请检查控制台');
                });
        }

        // 保存修改
        function saveChanges() {
            const newContent = codeMirrorInstance.getValue();
            fetch(apiUrl, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/xml'
                },
                body: newContent
            })
            .then(response => {
                if (!response.ok) throw new Error(`HTTP错误: ${response.status}`);
                return response.text();
            })
            .then(message => {
                alert(message);
            })
            .catch(error => {
                console.error('保存SLD内容失败:', error);
                alert('保存SLD内容失败,请检查控制台');
            });
        }

        document.addEventListener('DOMContentLoaded', fetchAndSetContent);
    </script>
</body>
</html>

前端修正点说明

  • 修复Codemirror XML模式脚本的URL拼写错误
  • 优化URL解析逻辑,使用pathname避免完整URL干扰
  • 调整PUT请求的Content-Type为application/xml,匹配后端接口要求
  • 增强错误处理,添加明确的用户提示
  • 增加Codemirror编辑配置,提升编辑体验

3. 必要依赖检查

确保SpringBoot项目中已添加WebFlux依赖(Maven示例):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

内容的提问来源于stack exchange,提问作者Piterek237

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:03:12