Spring 没有正确地将 JSON 序列化为 Java 映射
Spring doesn't correctly serialize JSON to Java Map
我有一个包含多个无线电输入和一个文本区域输入的表单,我使用来自 ReactJs 客户端的 axios 发送这些输入。请求如下所示:
axios.post("/wellbeing/" + params.wellbeingSurveyType, { formAnswersJson: formAnswers })
.then(res => {
// logic
})
.catch(err => {
// logic
})
'formAnswers' 对象如下所示:
然后我收到来自 Spring 控制器的请求,如下所示:
@PostMapping("{wellbeingSurveyType}")
public WellbeingSurveySubmission submitSurvey(
@PathVariable WellbeingSurveyType wellbeingSurveyType,
@RequestBody String formAnswersJson) throws JsonProcessingException {
var result = new ObjectMapper().readValue(formAnswersJson, HashMap.class);
return new WellbeingSurveySubmission(); //ignore this
}
当我在结果对象上调用 'toString()' 方法时,它似乎正确地打印出了地图值:
但是当我尝试对对象(被解析为 LinkedHashMap)进行实际操作时,我无法访问键或值:
当我尝试使用调试工具打开对象时,它似乎将对自身的引用存储为一个值:
我想要的结果只是一个代表 JSON 的 Map 但我不确定为什么会发生这种行为。
任何有关如何更好地执行此操作的帮助或提示,我们将不胜感激,谢谢。
如果你将一个JavaScript对象作为第二个参数传递给axios.post()
函数,Axios会自动为你将该对象序列化为JSON。
因此,使用这行代码:
axios.post("/wellbeing/" + params.wellbeingSurveyType, { formAnswersJson: formAnswers })
您基本上是将带有键 fromAnswersJson
和值 fromAnswers
的对象发送到您的其余控制器,并且 Spring 将像带有键 [=13= 的 Map
一样反序列化它] 和值 fromAnswers
要得到你想要的,只需像这样发送你的请求:
axios.post("/wellbeing/" + params.wellbeingSurveyType, formAnswers )
好吧,我发现完成这项工作的最佳方法是解构 axios post 请求中的 JSON 对象,如下所示:
axios.post("/wellbeing/" + params.wellbeingSurveyType, { ...formAnswers })
.then(res => {
// logic
})
.catch(err => {
// logic
})
效果更好,就好像我只是传递 formAnswers 对象一样,它不必要地包装对象,即包含单个 key-value 对 'formAnswers'.
的哈希图
尽管如 The Frozen One 所述,最好定义一个专用的表单对象并将其作为 spring 控制器中的参数。
从我在您的打印屏幕上看到的情况来看,java 中从 String 到 Map 的转换似乎并不顺利。
就个人而言,我在处理请求时不会那样工作。我创建了一个 dto 对象并将其作为输入提供给控制器。事实上,你的变量名称是一个数字,这使得它变得有点复杂,因为 java 不能接受它作为一个有效的变量名称,但可能(没有测试它)可以通过使用 @JsonProperty 来克服。所以我的解决方案如下
@Getter
@Setter
public class MyRequestDto {
@JsonProperty("user-comment")
private String userComment;
@JsonProperty("0")
private String zero;
@JsonProperty("1")
private String one;
@JsonProperty("2")
private String two;
...
}
我添加了 lombok getters 和 setters 当然如果你不使用 lombok 你可以添加你自己的。
然后替换控制器中的输入
@PostMapping("{wellbeingSurveyType}")
public WellbeingSurveySubmission submitSurvey(
@PathVariable WellbeingSurveyType wellbeingSurveyType,
@RequestBody MyRequestDto request) throws JsonProcessingException {
request.getUserComment()
return new WellbeingSurveySubmission(); //ignore this
}
我有一个包含多个无线电输入和一个文本区域输入的表单,我使用来自 ReactJs 客户端的 axios 发送这些输入。请求如下所示:
axios.post("/wellbeing/" + params.wellbeingSurveyType, { formAnswersJson: formAnswers })
.then(res => {
// logic
})
.catch(err => {
// logic
})
'formAnswers' 对象如下所示:
然后我收到来自 Spring 控制器的请求,如下所示:
@PostMapping("{wellbeingSurveyType}")
public WellbeingSurveySubmission submitSurvey(
@PathVariable WellbeingSurveyType wellbeingSurveyType,
@RequestBody String formAnswersJson) throws JsonProcessingException {
var result = new ObjectMapper().readValue(formAnswersJson, HashMap.class);
return new WellbeingSurveySubmission(); //ignore this
}
当我在结果对象上调用 'toString()' 方法时,它似乎正确地打印出了地图值:
但是当我尝试对对象(被解析为 LinkedHashMap)进行实际操作时,我无法访问键或值:
当我尝试使用调试工具打开对象时,它似乎将对自身的引用存储为一个值:
我想要的结果只是一个代表 JSON 的 Map
任何有关如何更好地执行此操作的帮助或提示,我们将不胜感激,谢谢。
如果你将一个JavaScript对象作为第二个参数传递给axios.post()
函数,Axios会自动为你将该对象序列化为JSON。
因此,使用这行代码:
axios.post("/wellbeing/" + params.wellbeingSurveyType, { formAnswersJson: formAnswers })
您基本上是将带有键 fromAnswersJson
和值 fromAnswers
的对象发送到您的其余控制器,并且 Spring 将像带有键 [=13= 的 Map
一样反序列化它] 和值 fromAnswers
要得到你想要的,只需像这样发送你的请求:
axios.post("/wellbeing/" + params.wellbeingSurveyType, formAnswers )
好吧,我发现完成这项工作的最佳方法是解构 axios post 请求中的 JSON 对象,如下所示:
axios.post("/wellbeing/" + params.wellbeingSurveyType, { ...formAnswers })
.then(res => {
// logic
})
.catch(err => {
// logic
})
效果更好,就好像我只是传递 formAnswers 对象一样,它不必要地包装对象,即包含单个 key-value 对 'formAnswers'.
的哈希图尽管如 The Frozen One 所述,最好定义一个专用的表单对象并将其作为 spring 控制器中的参数。
从我在您的打印屏幕上看到的情况来看,java 中从 String 到 Map 的转换似乎并不顺利。
就个人而言,我在处理请求时不会那样工作。我创建了一个 dto 对象并将其作为输入提供给控制器。事实上,你的变量名称是一个数字,这使得它变得有点复杂,因为 java 不能接受它作为一个有效的变量名称,但可能(没有测试它)可以通过使用 @JsonProperty 来克服。所以我的解决方案如下
@Getter
@Setter
public class MyRequestDto {
@JsonProperty("user-comment")
private String userComment;
@JsonProperty("0")
private String zero;
@JsonProperty("1")
private String one;
@JsonProperty("2")
private String two;
...
}
我添加了 lombok getters 和 setters 当然如果你不使用 lombok 你可以添加你自己的。
然后替换控制器中的输入
@PostMapping("{wellbeingSurveyType}")
public WellbeingSurveySubmission submitSurvey(
@PathVariable WellbeingSurveyType wellbeingSurveyType,
@RequestBody MyRequestDto request) throws JsonProcessingException {
request.getUserComment()
return new WellbeingSurveySubmission(); //ignore this
}