2015-10-12 41 views
2

下面是我写的代码。Spring无法使用null键返回JSON响应

@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无法处理JSON响应并将其作为null的根本原因。

回答

1

根据规范,JSON对象键必须是字符串。因此null不允许作为JSON对象键。所以它失败的原因是因为你所返回的内容不能被序列化为一个有效的JSON结构。

但是,杰克逊允许您使用自定义序列化器,您可以创建一个处理null键。 dom farr的答案描述了如何做到这一点。

+0

我明白为什么它会失败,虽然Spring应该会在服务器端产生异常,因为它很难找到。我提供的代码是复制问题的示例代码。实际上,我不得不通过大量的代码行来找到根源。 – Zaid

2

如果你想有一个空键按照此

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

注:

默认情况下,杰克逊不允许地图的系列化与null键。如果您有任何疑问,请参考本网站。 http://www.baeldung.com/jackson-map-null-values-or-null-key