Spring - HttpMessageConversionException 使用 ResponseEntity 和 Map<String,JSONobject>

Posted

技术标签:

【中文标题】Spring - HttpMessageConversionException 使用 ResponseEntity 和 Map<String,JSONobject>【英文标题】:Spring - HttpMessageConversionException using ResponseEntity with Map<String,JSONobject> 【发布时间】:2022-01-04 20:36:00 【问题描述】:

我遇到了一个关于访问 Map 中的 JSONobject 的问题。

基本上我正在尝试在这样的控制器方法中构建 Json 回复:


    "item1": 
        "type1": 2,
        "type5": 1
    ,
    "item6": 
        "type3": 32,
        "type26": 7,
        "type5": 9
        (being the number of keys inside of each key/value an object with several key/value entries)
    

这是控制器:

@PostMapping(value="/endpoint")
    public ResponseEntity<?> aggData(@RequestBody List<ValidNum> nums)
        try 
            Map<String, JSONObject> data = dataService.aggData(numsData);
            AggSuccess callSuccessResp = new AggSuccess(data);
            return new ResponseEntity<>(callSuccessResp, HttpStatus.OK);
         catch (Error e) 
            AggError callErrorResp = new AggError(e.getMessage());
            return new ResponseEntity<AggregatedDataError>(callErrorResp, HttpStatus.BAD_REQUEST);
        
    

这是服务实现

@Override
    public Map<String,JSONObject> aggregateData(List<ValidNum> numsData) 
        Map<String,JSONObject> aggData = new HashMap<>();

        for (ValidNum vn : numsData) 

            if (aggData.get(vn.item) == null) 
                JSONObject itemTypesCount = new JSONObject();
                aggData.put(vn.item, itemTypesCount.put(vn.type, 1));
             else 
                JSONObject itemData = aggData.get(vn.item);
                Long typeValue  = (Long) itemData.get(vn.type);
                itemData.put(vn.type, typeValue+1);
                aggData.put(vn.item, itemData);
            
        

        return aggData;
    

ValidNum 类

public class ValidNum 

    public String nr;
    public String item;
    public String type;

    public ValidNumber(String nr, String item, String type) 
        this.nr = nr;
        this.item = item;
        this.type = type;
    


AggSuccess 响应类(我认为问题所在)

public class AggSuccess 
    public Map<String,JSONObject> aggSuccess;

    public AggSuccess(Map<String, JSONObject> aggSuccess) 
        this.aggSuccess = aggSuccess;
    


问题是我总是得到一个错误,除非我将它添加到应用程序属性中:spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false 我不希望这样,因为我不希望数据看起来像这样:


    "item1": ,
    "item6": 

评论该条目我收到以下错误:

ERROR 26551 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.json.JSONObject]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.json.JSONObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: package.AggDataSuccess["aggSuccess"]->java.util.HashMap["item1"])] with root cause
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.json.JSONObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: package.AggDataSuccess["aggSuccess"]->java.util.HashMap["item1"])

最奇怪的是,在控制器的 callSuccessResp 中调试,在将数据发送回邮递员之前,我得到了正确的 json 值:


    "item1": 
        "type1": 2,
        "type5": 1
    ,
    "item6": 
        "type3": 32,
        "type26": 7,
        "type5": 9
    

那么,我该怎么做才能让响应实体正确读取和序列化 JSON 对象?

【问题讨论】:

【参考方案1】:

Jackson 默认不支持org.json 类。尝试使用 Jackson 的 com.fasterxml.jackson.databind.node.ObjectNode 来构建您的 JSON 对象。

【讨论】:

以上是关于Spring - HttpMessageConversionException 使用 ResponseEntity 和 Map<String,JSONobject>的主要内容,如果未能解决你的问题,请参考以下文章

Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC

学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签

Spring--Spring入门

Spring框架--Spring事务管理和Spring事务传播行为

Spring框架--Spring事务管理和Spring事务传播行为

Spring框架--Spring JDBC