【问题标题】:How to keep map key order in json when I return object from @RestControler当我从 @RestControler 返回对象时如何在 json 中保持映射键顺序
【发布时间】:2018-06-04 05:31:17
【问题描述】:

我想保持地图条目的顺序,因此我在上下文中添加了以下 bean:

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
    return objectMapper;
}

我还有以下控制器:

@Autowired
private ObjectMapper objectMapper;
@GetMapping(value = "/mapping", produces = "application/json")
public ResponseEntity<MappingDTO> getMapping(HttpServletRequest request) {
    MappingDTO mappingDTO = mappingService.getMapping();
    String str = objectMapper.writeValueAsString(mappingDTO); // added this line for test perpose
    return ResponseEntity.ok(mappingDTO);
}

dto:

public class MappingDTO {
    private String id;
    private Map<String, List<MappingEntry>> entries;
    ...

str 变量包含具有正确顺序的正确 json,但是当我执行 Get 请求时 - 顺序已损坏。

如何解决这个问题?

【问题讨论】:

标签: java spring spring-mvc spring-boot jackson


【解决方案1】:

看看下面的链接

ObjectMapper configuration

它提供了有关如何配置默认映射器或使用自定义映射器的说明。

如果你想完全替换默认的 ObjectMapper,要么 定义该类型的@Bean 并将其标记为@Primary...

因此我认为您缺少@Primary 注释

【讨论】:

  • 其实我试过这个注解但是结果是一样的。在调试中,我看到 spring 使用相同的映射器,但结果 - 不同
  • 在您的代码库中是否还有其他 ObjectMapper 定义正在被使用?
  • 不,我没有 ObjectMapper 的其他定义。至少明确
  • 链接建议的另一个选项是设置环境变量 spring.jackson.serialization.ORDER_MAP_ENTRIES_BY_KEYS=true
  • 其实我的问题是错误的。这只是谷歌浏览器 json 预览按字母顺序对 json 键进行排序
【解决方案2】:

只需使用 LinkedHashMap 来存储您的值,它将保持插入顺序:

@RestController
public class TestController {
    class Dto {
        private Map<String, List<Integer>> entries = new LinkedHashMap<>();

        public Dto() {
            final List<Integer> l1 = new ArrayList<>();
            l1.add(2);
            l1.add(1);
            entries.put("A", l1);
            final List<Integer> l2 = new ArrayList<>();
            l2.add(4);
            l2.add(6);
            entries.put("C", l2);
            final List<Integer> l3 = new ArrayList<>();
            l3.add(5);
            l3.add(3);
            entries.put("B", l3);
        }

        public Map<String, List<Integer>> getEntries() {
            return entries;
        }
    }

    @GetMapping("json")
    public ResponseEntity<Dto> getJson() {
        return ResponseEntity.ok(new Dto());
    }
}

/json的请求会得到{"entries":{"A":[2,1],"C":[4,6],"B":[5,3]}},但是如果你使用普通的Map,结果会是{"entries":{"A":[2,1],"B":[5,3],"C":[4,6]}}

这假设您希望保留 插入 顺序(从您的问题中不清楚)。但是,如果您更喜欢按键对地图进行排序,请改用 TreeMap

【讨论】:

    【解决方案3】:

    假设您希望按字典顺序对键进行排序,请添加

    spring.jackson.serialization.order-map-entries-by-keys=true
    

    application.properties 文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-01
      • 2021-01-09
      • 1970-01-01
      相关资源
      最近更新 更多