jackson Spring不能正确地将JSON序列化为Java Map

bwntbbo3  于 2022-11-09  发布在  Spring
关注(0)|答案(3)|浏览(161)

我有一个包含多个radio输入和一个textarea输入的表单,我使用axios从ReactJs客户端发送该表单。请求如下所示:

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
    }

当我在result对象上调用'toString()'方法时,它似乎正确地打印出了map值:

但是当我试图实际操作对象(它被解析为LinkedHashMap)时,我无法访问键或值:

当我尝试使用调试工具打开对象时,它似乎将对自身的引用存储为一个值:

我想要的结果只是一个Map〈String,String〉,它表示JSON,但我不确定为什么会发生这种行为。
任何帮助或提示如何做到这一点在一个更好的方式将不胜感激,谢谢。

e4yzc0pl

e4yzc0pl1#

好的,我发现实现这个功能的最好方法是在axios post请求中解构JSON对象,如下所示:

axios.post("/wellbeing/" + params.wellbeingSurveyType, { ...formAnswers })
        .then(res => {
          // logic
        })
        .catch(err => {
          // logic
        })

如果我只是传递formAnswers对象,效果会更好,它不必要地 Package 对象,即包含单个键-值对“formAnswers”的散列表。
虽然正如《冰雪奇缘》中提到的,最好定义一个专用的表单对象,并将其作为Spring控制器中的参数。

tsm1rwdh

tsm1rwdh2#

如果您将JavaScript对象作为第二个参数传递给axios.post()函数,Axios会自动将该对象序列化为JSON。
因此,使用这行代码:

axios.post("/wellbeing/" + params.wellbeingSurveyType, { formAnswersJson: formAnswers })

您基本上是将键为fromAnswersJson、值为fromAnswers的对象发送到您的rest控制器,Spring会将其反序列化为键为fromAnswersJson、值为fromAnswersMap
要得到你想要的只是这样发送你的请求:

axios.post("/wellbeing/" + params.wellbeingSurveyType, formAnswers )
wwwo4jvm

wwwo4jvm3#

从我在你的打印屏幕上看到的情况来看,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的getter和setter,当然,如果你不使用lombok,你也可以添加自己的。
然后更换控制器中的输入

@PostMapping("{wellbeingSurveyType}")
public WellbeingSurveySubmission submitSurvey(
        @PathVariable WellbeingSurveyType wellbeingSurveyType,
        @RequestBody MyRequestDto request) throws JsonProcessingException {
        request.getUserComment()
        return new WellbeingSurveySubmission(); //ignore this
    }

相关问题