Java Spring无法返回带有null键的JSON响应
下面是我写的代码Java Spring无法返回带有null键的JSON响应,java,json,spring,spring-mvc,Java,Json,Spring,Spring Mvc,下面是我写的代码 @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.pu
@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;
}
@RequestMapping(value=“/getData”,method=RequestMethod.GET)
public@ResponseBody Map test()引发IOException{
Map Map=newhashmap();
地图放置(“键”、“值”);
map.put(null,“Key's Value”);//**这段突出显示的代码导致了问题,如果我删除它,它就可以正常工作。**
返回图;
}
当我点击URLlocalhost:8080/myapp/getData
我收到以下答复
10.5.1 500内部服务器错误
服务器遇到意外情况,无法满足请求
甚至Spring也不会打印任何服务器端异常
我想知道Spring无法处理键为null的JSON响应的根本原因。根据规范,JSON对象键必须是字符串。因此,不允许将
null
作为JSON对象键。因此,它失败的原因是您返回的内容无法序列化为有效的JSON结构
但是,Jackson允许您使用自定义序列化程序,您可以创建一个处理
null
键的序列化程序。dom farr的回答描述了如何做到这一点。如果需要空键,请遵循以下步骤
类MyDtoNullKeySerializer扩展了JsonSerializer{
@凌驾
public void serialize(对象nullKey、JsonGenerator、JsonGenerator、SerializerProvider unused)引发IOException、JsonProcessingException{
jsonGenerator.writeFieldName(“”);
}
}
@试验
public void givenAllowingMapObjectWithNullKey\u在编写时\u thenCorrect()引发JsonProcessingException{
ObjectMapper mapper=新的ObjectMapper();
getSerializerProvider().setNullKeySerializer(新的MyDtoNullKeySerializer());
MyDto dtoObject=新的MyDto();
设置字符串值(“dtoObjectString”);
Map dtoMap=newhashmap();
dtoMap.put(null,dtoObject);
字符串dtoMapAsString=mapper.writeValueAstring(dtoMap);
资产(DTomapassString,containssString(“\”\”);
资产(dtoMapAsString,containsString(“dtoObjectString”);
}
@RequestMapping(value=“/getData”,method=RequestMethod.GET)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
public@ResponseBody String test()引发IOException{
Map Map=newhashmap();
ObjectMapper mapper=新的ObjectMapper();
configure(SerializationFeature.WRITE\u NULL\u MAP\u值,false);
mapper.setSerializationInclusion(Include.NON_NULL);
getSerializerProvider().setNullKeySerializer(新的MyNullKeySerializer());
地图放置(“键”、“值”);
put(null,“键的值”);
返回mapper.writeValueAsString(map);
}
类MyNullKeySerializer扩展了JsonSerializer
{
@凌驾
public void序列化(对象nullKey、JsonGenerator、JsonGenerator、SerializerProvider未使用)
抛出IOException、JsonProcessingException
{
jsonGenerator.writeFieldName(“”);
}
}
注:
默认情况下,Jackson不允许使用空键对映射进行序列化。如果您有任何疑问,请访问本网站 我理解为什么它会失败,尽管Spring应该在服务器端生成异常,因为很难找到它。我提供的代码是复制问题的示例代码。在现实生活中,我不得不通过大量的代码来找到根本原因。
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"));
}
@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("");
}
}