【问题标题】:Trying to deserialize json array into java String using Jackson in Spring-boot尝试在 Spring-boot 中使用 Jackson 将 json 数组反序列化为 java String
【发布时间】:2020-09-07 05:00:22
【问题描述】:

我是 Spring-boot 的新手,正在尝试在 Spring-boot 应用程序中使用 Jackson 将 json 数组反序列化为 java String。类似的东西

{"history": ["historyA", "historyB"]} (JSON Request Body) -> String history;

但是,记录了以下错误消息。

Cannot deserialize instance of `java.lang.String` out of START_ARRAY token

我的控制器类似于

@RestController
public class PatientController {
    @PostMapping
    public void create(@RequestBody @Valid Patient patient) {
        mapper.create(patient);
    }
}

我的 POJO 类似于:

@Data
@NoArgsConstructor
public class Patient {
    @JsonDeserialize(contentUsing = PatientHistoryDeserializer.class, contentAs = List.class)
    private String history;

我的 Json Deserializer 类似于:

public class PatientHistoryDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        List<String> histories = new LinkedList<>();
        if (p.getCurrentToken() == JsonToken.START_ARRAY) {
            while (p.getCurrentToken() != JsonToken.END_ARRAY) {
                String history = p.getValueAsString();
                if(history.contains("#"))
                    throw new ClientError(HttpServletResponse.SC_BAD_REQUEST, "invalid...");
                histories.add(history);
            }
        }
        return String.join("#", histories);
    }
}

我的目标可以实现吗?或者关于如何转换的任何建议?

【问题讨论】:

  • 您可以正常反序列化为List,并在getter中加入所有字符串并返回。
  • 为此我有自己的 JsonSerializer。顺便说一句,是否有可能一开始就将他们加入二传手?

标签: java json spring spring-boot jackson


【解决方案1】:

可以这样完成

public class PatientHistoryDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
       if (jsonParser.currentToken() == JsonToken.START_ARRAY) {
           List<String> histories = new ArrayList<>();
           jsonParser.nextToken();

           while (jsonParser.hasCurrentToken() && jsonParser.currentToken() != JsonToken.END_ARRAY) {
              histories.add(jsonParser.getValueAsString());
              jsonParser.nextToken();
           }
          return String.join("#", histories);
       }
       return null;
    }
}

和用法想

@JsonDeserialize(using = PatientHistoryDeserializer.class)
String histories;

contentUsingcontentAs 的用途与这里的用例略有不同。让我们看下面的例子。

class Histories {
    Map<String, String> content;
}

JSON 是这样的

{"content": { "key" : ["A","B"]}}

并且您想将其反序列化为具有 (key = "A#B") 的地图

有两种方法可以做到这一点,编写自定义反序列化器或使用contentUsing 属性来指定应如何反序列化您的值

@JsonDeserialize(contentUsing = PatientHistoryDeserializer.class)
Map<String, String> content;

同样,您可以使用其他注释属性,例如 keyUsing 来作为地图的键。

【讨论】:

  • 您的代码完美运行!谢谢你向我解释。你真的拯救了我的一天!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-31
  • 2019-02-16
  • 2013-04-09
  • 2018-06-02
相关资源
最近更新 更多