2015-10-12 63 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