简体   繁体   中英

Spring - HttpMessageConversionException using ResponseEntity with Map<String,JSONobject>

I'm facing an issue regarding the acess to a JSONobject inside a Map<String,JSONobject>.

Basically I'm trying to build a Json reply in a controller method like this:

{
    "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)
    }
}

This is the controller:

@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);
        }
    }

This is the service implementation

@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;
    }

The ValidNum class

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;
    }

}

The AggSuccess response class (where I think problem is)

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

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

}

The problem is that I'm allways getting an error unless I add this to the application properties: spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false and I don't want that because I don't wan't data to look like this:

{
    "item1": {},
    "item6": {}
}

Commenting that entry I get the following error:

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"])

and the weirdest part is the fact that debugging in the controller's callSuccessResp, right before sending data back to postman, I get the correct json value:

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

So, what can I do to get the response entity to read and serialize the JSONobject properly?

Jackson doesn't support org.json classes by default. Try to build your JSON Object using Jackson's com.fasterxml.jackson.databind.node.ObjectNode instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM