Spring Boot JsonMappingException:对象为null

时间:2019-02-18 10:04:35

标签: json spring spring-boot jackson

我有一个@RestController返回net.sf.json.JSONObject:

experiment.hs:585:1: error:
    parse error (possibly incorrect indentation or mismatched brackets)
    |
585 | flatten (UNode l x) = [l] ++ flatten x 
    | ^

当JSONObject包含空引用时,将引发以下异常:

@PostMapping("/list")
public JSONObject listStuff(HttpServletRequest inRequest, HttpServletResponse inResponse) {
    JSONObject json = new JSONObject();
    ...
    return json;
}

这是我们现在要清理的遗留代码,在某些时候,我们将摆脱显式的JSON操作,但这将是一个巨大的变化,因为现在我想摆脱异常。 我尝试了以下解决方案:

  1. 在Spring的Object Mapper中定义Could not write JSON: Object is null; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Object is null (through reference chain: net.sf.json.JSONObject[\"list\"]->net.sf.json.JSONArray[0]->net.sf.json.JSONObject[\"object\"]->net.sf.json.JSONNull[\"empty\"])" -在我的Include.NON_NULL中定义这段代码:
WebMvcConfigurationSupportClass
  1. 在application.yml中设置以下属性: @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { ObjectMapper webObjectMapper = objectMapper.copy(); webObjectMapper.setSerializationInclusion(Include.NON_NULL); converters.add(new MappingJackson2HttpMessageConverter(webObjectMapper)); }
  2. 检查spring.jackson.default-property-inclusion=non_null的版本-依赖关系树中唯一的版本是2.9.7。

以上方法均无济于事。

关于如何告诉Spring忽略net.sf.json.JSONObjects中的空值的任何建议?

2 个答案:

答案 0 :(得分:1)

Include.NON_NULL不起作用,因为JSONNull代表null,但不是null 本身。来自documentation

  

JSONNull等效于JavaScript调用null的值,而   Java的null等于JavaScript调用的值   未定义。

此对象以Singleton的形式实现,它有两种方法:isArrayisEmpty,其中isEmpty有问题,因为它引发异常。以下代码段显示了其实现:

public boolean isEmpty() {
   throw new JSONException("Object is null");
}

最好的方法是为NullSerializer类型定义JSONNull。下面的示例显示了我们如何配置它:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.NullSerializer;
import net.sf.json.JSONArray;
import net.sf.json.JSONNull;
import net.sf.json.JSONObject;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        SimpleModule netSfJsonModule = new SimpleModule("net.sf.json");
        netSfJsonModule.addSerializer(JSONNull.class, NullSerializer.instance);

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.registerModule(netSfJsonModule);

        JSONObject object = new JSONObject();
        object.accumulate("object", JSONNull.getInstance());

        JSONArray jsonArray = new JSONArray();
        jsonArray.add(object);

        JSONObject json = new JSONObject();
        json.accumulate("list", jsonArray);

        System.out.println(mapper.writeValueAsString(json));
    }
}

上面的代码显示:

{
  "list" : [ {
    "object" : null
  } ]
}

另请参阅:

  1. Maven: missing net.sf.json-lib
  2. How do you override the null serializer in Jackson 2.0?

答案 1 :(得分:0)

这不是理想的解决方案,而是一种解决方法。由于无法覆盖默认的映射器/转换器行为,所以我更改了JSONObject的结构,因此在其生成过程中添加了以下行:

listElt.put("object", "");

产生: { "list" : [ { "object" : "" } ] }

这仅在我对此字段的值不感兴趣而我不感兴趣的情况下才可以。 我个人更喜欢@MichałZiober的解决方案-它优雅而通用。不幸的是,这对我不起作用。