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

Spring Boot Admin使用InstanceExchangeFilterFunction实现下划线转驼峰适配UI咨询

问题原因分析

你的问题核心是全局ObjectMapper配置被业务绑定为下划线命名策略,而SBA UI只能识别驼峰格式的actuator接口返回值,你之前的两种方案分别踩了两个坑:

  1. 直接修改全局MappingJackson2HttpMessageConverter会同时影响业务接口和SBA逻辑,所以出现SBA正常但业务前端崩溃的问题
  2. 定义的InstanceExchangeFilterFunction是空实现,没有对响应内容做实际的格式转换,所以不生效
正确实现方案

核心思路是完全不触碰全局业务的ObjectMapper配置,单独给SBA请求做响应转换:通过InstanceExchangeFilterFunction拦截SBA Server和被监控实例之间的请求,拿到下划线格式的响应后,单独转换为驼峰格式再返回给SBA UI,全程和业务配置隔离。

完整配置代码

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import de.codecentric.boot.admin.server.web.client.InstanceExchangeFilterFunction;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import reactor.core.publisher.Mono;
import java.util.Iterator;
import java.util.Map;

@Configuration
public class SbaSpecialConfig {
    // 单独定义SBA专用ObjectMapper,和业务使用的全局ObjectMapper完全隔离
    private final ObjectMapper sbaObjectMapper = new ObjectMapper();

    @Bean
    public InstanceExchangeFilterFunction snakeToCamelFilter() {
        return (instance, request, next) -> next.exchange(request)
                .flatMap(response -> {
                    // 仅处理JSON格式的响应
                    if (response.headers().contentType().isPresent()
                            && response.headers().contentType().get().includes(MediaType.APPLICATION_JSON)) {
                        return response.bodyToMono(String.class)
                                .map(body -> {
                                    try {
                                        JsonNode rootNode = sbaObjectMapper.readTree(body);
                                        // 递归转换所有下划线key为驼峰
                                        convertKeyToCamel(rootNode);
                                        return sbaObjectMapper.writeValueAsString(rootNode);
                                    } catch (Exception e) {
                                        // 转换失败直接返回原响应避免异常
                                        return body;
                                    }
                                })
                                .map(camelBody -> response.mutate().body(camelBody).build());
                    }
                    // 非JSON响应直接透传
                    return Mono.just(response);
                });
    }

    // 下划线转驼峰工具方法
    private void convertKeyToCamel(JsonNode node) {
        if (node.isObject()) {
            Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> field = fields.next();
                String oldKey = field.getKey();
                String newKey = snakeToCamel(oldKey);
                if (!oldKey.equals(newKey)) {
                    fields.remove();
                    ((ObjectNode) node).set(newKey, field.getValue());
                }
                convertKeyToCamel(field.getValue());
            }
        } else if (node.isArray()) {
            for (JsonNode child : node) {
                convertKeyToCamel(child);
            }
        }
    }

    private String snakeToCamel(String snakeStr) {
        StringBuilder sb = new StringBuilder();
        boolean upperCaseNext = false;
        for (char c : snakeStr.toCharArray()) {
            if (c == '_') {
                upperCaseNext = true;
            } else {
                sb.append(upperCaseNext ? Character.toUpperCase(c) : c);
                upperCaseNext = false;
            }
        }
        return sb.toString();
    }
}

验证说明

  1. 保留你原有业务的全局ObjectMapper下划线配置不需要修改,业务接口不受任何影响
  2. 重启SBA服务后访问metrics、env等功能,页面可以正常加载数据
  3. 如果需要只适配特定接口,可以在过滤器中增加请求路径判断,只处理指定的actuator接口即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:18:03