当我从 @RestControler 返回对象时如何在 json 中保持映射键顺序

Posted

技术标签:

【中文标题】当我从 @RestControler 返回对象时如何在 json 中保持映射键顺序【英文标题】:How to keep map key order in json when I return object from @RestControler 【发布时间】: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 请求时 - 顺序已损坏。

如何解决这个问题?

【问题讨论】:

看看docs.spring.io/spring-boot/docs/current/reference/html/… @PillHead,对不起? 【参考方案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 文件。

【讨论】:

以上是关于当我从 @RestControler 返回对象时如何在 json 中保持映射键顺序的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2 - 从 RestControler 返回 rx.Observable

获取对象时如何处理“匹配查询不存在”

处理恢复购买时如何处理旧交易?

映射数组时如何为 React 子级指定键

Vim:在寄存器中存储多个命令时如何处理换行符?

侦听firebase数据库节点时如何处理kotlin中的竞争条件