Quando o fastxml jackson desserializa, um erro é relatado para classes internas não estáticas

Java geralmente usa duas bibliotecas, jackson e fastjson, para processar json. A última API é mais conveniente de usar, mas há muitas falhas de segurança.

Hoje, ao usar o jackson para desserializar uma string json, encontrei um problema:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `json.TransferResp$TransforData` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor

Muitos artigos não explicaram claramente, este artigo fez uma experiência. Para a estrutura aninhada, uma classe java contendo uma classe interna é definida para recebê-la. Se a estrutura complexa estiver na forma de um array, o erro acima será relatado ao desserializar.

experimente um

1) classe de entidade java:

@Data
public class TransforResponse {
    private Integer code;
    
    private Map<String, String> defaultData;
    private TransforData data;
    
    @Data
    public static class TransforData{
        private Long encyId;
        private int score;
        private Map<String, String> other;
    }
}

2) teste

private static ObjectMapper objectMapper = new ObjectMapper();

public static void main(String[] args) throws Exception {
    String jsonStr = serialization(); //{\"code\":200,\"data\":{\"encyId\":123,\"other\":{\"a\":\"test\"},\"score\":5}}
    deSerialization(jsonStr); //TransferResp(code=200, data=TransferResp.TransforData(encyId=123, score=5, other={a=test}))
    
    System.out.println("----------");
    String jsonStr2 = serialization2(); //{\"code\":200,\"data\":{\"encyId\":123,\"other\":{\"a\":\"test\"},\"score\":5}}
    deSerialization2(jsonStr2); //TransferResp(code=200, data=TransferResp.TransforData(encyId=123, score=5, other={a=test}))
}
private static TransferResp createObj() {
    TransferResp tr = new TransferResp();
    
    TransforData transforData = tr.new TransforData();
    transforData.setEncyId(123L);
    transforData.setScore(5);
    Map<String, String> hashMap = new HashMap<>(1);
    hashMap.put("a", "test");
    transforData.setOther(hashMap);
    
    tr.setCode(200);
    tr.setData(transforData);

    return tr;
}

private static String serialization() {
    TransferResp tr = createObj();
    String jsonString = JSONObject.toJSONString(tr);
    System.out.println(jsonString);
    return jsonString;
}
private static void deSerialization(String jsonStr) {
    TransferResp parseObject = JSONObject.parseObject(jsonStr, TransferResp.class);
    System.out.println(parseObject.toString());
}

private static String serialization2() throws JsonProcessingException {
    TransferResp tr = createObj();
    String jsonString = objectMapper.writeValueAsString(tr);
    System.out.println(jsonString);
    return jsonString;
}
private static void deSerialization2(String jsonStr) throws JsonParseException, JsonMappingException, IOException {
    TransferResp parseObject = objectMapper.readValue(jsonStr, TransferResp.class);
    System.out.println(parseObject.toString());
}

 Depois de executado é normal.

Experimento 2

1) classe de entidade java

@Data
public class TransferResp {
    private Integer code;
    private List<TransforData> data;
    
    @Data
    public class TransforData{
        private Long encyId;
        private Integer score;
        private Map<String, String> other;
    }
}

2) Teste:

private static ObjectMapper objectMapper = new ObjectMapper();

public static void main(String[] args) throws Exception {
    String jsonStr = serialization(); //{"code":200,"data":[{"encyId":123,"other":{"a":"test"},"score":5}]}
    deSerialization(jsonStr); //TransferResp(code=200, data=[TransferResp.TransforData(encyId=123, score=5, other={a=test})])
    
    System.out.println("----------");
    String jsonStr2 = serialization2(); //{"code":200,"data":[{"encyId":123,"score":5,"other":{"a":"test"}}]}
    deSerialization2(jsonStr2); //error
}
private static TransferResp createObj() {
    TransferResp tr = new TransferResp();
    
    TransforData transforData = tr.new TransforData();
    transforData.setEncyId(123L);
    transforData.setScore(5);
    Map<String, String> hashMap = new HashMap<>(1);
    hashMap.put("a", "test");
    transforData.setOther(hashMap);
    
    List<TransforData> list = new ArrayList<>();
    list.add(transforData);
    tr.setCode(200);
    tr.setData(list);

    return tr;
}

private static String serialization() {
    TransferResp tr = createObj();
    String jsonString = JSONObject.toJSONString(tr);
    System.out.println(jsonString);
    return jsonString;
}
private static void deSerialization(String jsonStr) {
    TransferResp parseObject = JSONObject.parseObject(jsonStr, TransferResp.class);
    System.out.println(parseObject.toString());
}

private static String serialization2() throws JsonProcessingException {
    TransferResp tr = createObj();
    String jsonString = objectMapper.writeValueAsString(tr);
    System.out.println(jsonString);
    return jsonString;
}
private static void deSerialization2(String jsonStr) throws JsonParseException, JsonMappingException, IOException {
    TransferResp parseObject = objectMapper.readValue(jsonStr, TransferResp.class);
    System.out.println(parseObject.toString());
}

运行时会报错:Exceção no thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Não é possível construir instância de `json.TransferResp$TransforData` (embora exista pelo menos um Criador): só pode instanciar interno não estático classe usando o construtor padrão sem argumentos

3) Solução:

A. Use classes internas estáticas

@Data
public class TransferResp {
    private Integer code;
    private List<TransforData> data;
    
    @Data
    public static class TransforData{
        private Long encyId;
        private Integer score;
        private Map<String, String> other;
    }
}

B) Defina a classe interna em um arquivo de classe separado.

Acho que você gosta

Origin blog.csdn.net/liuxiao723846/article/details/129070511
Recomendado
Clasificación