【问题标题】:Spring fails to return JSON response with null keySpring 无法返回带有 null 键的 JSON 响应
【发布时间】:2015-10-12 07:08:53
【问题描述】:

下面是我写的代码。

@RequestMapping(value = "/getData", method = RequestMethod.GET)   
public @ResponseBody Map<String,String> test() throws IOException {   
Map<String,String> map = new HashMap<String,String>();
map.put("key","value");
map.put(null, "Key's Value"); //**This highlighted code causing the problem, if I remove this then it works fine.**    
    return map;  
}

当我点击 URL localhost:8080/myapp/getData 我收到以下回复

10.5.1 500 内部服务器错误 服务器遇到了一个意外情况,导致它无法完成请求。

即使 Spring 也不会打印任何服务器端异常!

我想知道 Spring 无法处理 key 为 null 的 JSON 响应的根本原因。

【问题讨论】:

    标签: java json spring spring-mvc


    【解决方案1】:

    如果你想要一个空键,请按照这个

    http://www.baeldung.com/jackson-map-null-values-or-null-key

    class MyDtoNullKeySerializer extends JsonSerializer<Object> {
        @Override
        public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused) throws IOException, JsonProcessingException {
            jsonGenerator.writeFieldName("");
        }
    }
    
    
    @Test
    public void givenAllowingMapObjectWithNullKey_whenWriting_thenCorrect() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.getSerializerProvider().setNullKeySerializer(new MyDtoNullKeySerializer());
    
        MyDto dtoObject = new MyDto();
        dtoObject.setStringValue("dtoObjectString");
    
        Map<String, MyDto> dtoMap = new HashMap<String, MyDto>();
        dtoMap.put(null, dtoObject);
    
        String dtoMapAsString = mapper.writeValueAsString(dtoMap);
    
        assertThat(dtoMapAsString, containsString("\"\""));
        assertThat(dtoMapAsString, containsString("dtoObjectString"));
    }
    

    【讨论】:

      【解决方案2】:

      JSON 对象键必须是符合规范的字符串。因此,null 不允许作为 JSON 对象键。所以它失败的原因是因为您返回的内容无法序列化为有效的 JSON 结构。

      不过,Jackson 允许您使用自定义序列化程序,并且您可以创建一个处理 null 键的序列化程序。 dom farr 的回答描述了如何做到这一点。

      【讨论】:

      • 我理解为什么它会失败,尽管 Spring 应该在服务器端生成异常,因为它很难找到。我提供的代码是复制问题的示例代码。实际上,我必须通过大量代码行才能找到根本原因。
      【解决方案3】:
      @RequestMapping(value = "/getData", method = RequestMethod.GET) 
          @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
          public @ResponseBody String test() throws IOException {   
          Map<String,String> map = new HashMap<String,String>();
            ObjectMapper mapper = new ObjectMapper();
              mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
              mapper.setSerializationInclusion(Include.NON_NULL);
              mapper.getSerializerProvider().setNullKeySerializer(new MyNullKeySerializer());
              map.put("key","value");
              map.put(null, "Key's Value");    
              return mapper.writeValueAsString(map);  
          }
      
      class MyNullKeySerializer extends JsonSerializer<Object>
      {
        @Override
        public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused) 
            throws IOException, JsonProcessingException
        {
          jsonGenerator.writeFieldName("");
        }
      }
      

      注意:

      默认情况下,Jackson 不允许使用 null 键对 Map 进行序列化。如果您有任何疑问,请参阅本网站。 http://www.baeldung.com/jackson-map-null-values-or-null-key

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-23
        • 1970-01-01
        • 1970-01-01
        • 2016-06-03
        • 2020-10-07
        • 1970-01-01
        相关资源
        最近更新 更多