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

如何让Spring Config Server返回嵌套结构JSON响应而非解析路径?

Getting Spring Config Server to Return Nested JSON Instead of Flattened Property Paths

Hey there, let's tackle this problem where Spring Config Server is returning flattened key-value pairs in the source section of its response, but you need the nested JSON structure that matches your original YAML. Here's what you can do:

First, Let's Recap the Issue

Your YAML in GitLab looks like this:

holidays:
  US:
    - 03/19/2020
    - 03/20/2020
    - 05/18/2020

But the Config Server response gives you flattened keys like holidays.US[0] instead of the nested holidays.US array. You want the source to mirror the original YAML's structure.

Solution 1: Enable Pretty-Printing (Simplest Fix)

Spring Cloud Config Server has a built-in property that can make it return nested JSON instead of flattened paths. Just add this to your Config Server's application.yml or application.properties:

For YAML:

spring:
  cloud:
    config:
      server:
        git:
          pretty-print: true

For properties:

spring.cloud.config.server.git.pretty-print=true

This tells the server to serialize the properties into their natural nested structure rather than flattening them into dot-separated keys. Restart your Config Server, and you should see the nested JSON in the response.

Solution 2: Use the Native Profile (For Local or Cloned Repos)

If you're using a local clone of your GitLab repo (or a native file system source), enabling the native profile can also preserve the nested structure. Here's how to set it up:

  1. Add the native profile to your Config Server's active profiles:
spring:
  profiles:
    active: native
  cloud:
    config:
      server:
        native:
          search-locations: file:///path/to/your/gitlab/repo/clone
  1. Restart the server. This approach uses the native property source handler, which respects the YAML's nested structure by default.

Solution 3: Custom Response Converter (If All Else Fails)

If the above solutions don't work for your setup (e.g., older Spring Cloud versions), you can create a custom HTTP message converter to transform the flattened source into nested JSON. Here's a step-by-step implementation:

  1. Create a custom converter class that extends MappingJackson2HttpMessageConverter:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cloud.config.server.environment.Environment;
import org.springframework.cloud.config.server.environment.PropertySource;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class NestedPropertySourceConverter extends MappingJackson2HttpMessageConverter {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException {
        if (object instanceof Environment) {
            Environment configEnvironment = (Environment) object;
            // Process each property source to convert flattened keys to nested structure
            configEnvironment.getPropertySources().forEach(this::convertFlattenedSourceToNested);
        }
        super.writeInternal(object, outputMessage);
    }

    private void convertFlattenedSourceToNested(PropertySource propertySource) {
        Map<String, Object> flattenedSource = (Map<String, Object>) propertySource.getSource();
        Map<String, Object> nestedSource = new HashMap<>();

        for (Map.Entry<String, Object> entry : flattenedSource.entrySet()) {
            String[] keyParts = entry.getKey().split("\\.");
            Map<String, Object> currentLevel = nestedSource;

            for (int i = 0; i < keyParts.length; i++) {
                String part = keyParts[i];
                if (i == keyParts.length - 1) {
                    // Handle array indices like "US[0]"
                    if (part.contains("[")) {
                        String arrayKey = part.substring(0, part.indexOf("["));
                        int index = Integer.parseInt(part.substring(part.indexOf("[") + 1, part.indexOf("]")));
                        // Initialize or get the list for the array key
                        List<Object> array = (List<Object>) currentLevel.computeIfAbsent(arrayKey, k -> new ArrayList<>());
                        // Ensure the list has enough elements to set the index
                        while (array.size() <= index) {
                            array.add(null);
                        }
                        array.set(index, entry.getValue());
                    } else {
                        currentLevel.put(part, entry.getValue());
                    }
                } else {
                    // Move to the next nested level
                    currentLevel = (Map<String, Object>) currentLevel.computeIfAbsent(part, k -> new HashMap<>());
                }
            }
        }

        propertySource.setSource(nestedSource);
    }
}
  1. Register the converter in your Config Server's configuration:
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new NestedPropertySourceConverter());
    }
}

This converter intercepts the Config Server's response, transforms the flattened source map into a nested structure, and then sends the modified response back.

Testing the Fix

After applying any of these solutions, hit your Config Server's endpoint (e.g., http://your-config-server:8888/simpleyml/default) and check the source section. It should now show the nested holidays object with the US array, matching your original YAML structure.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 16:02:46