web-dev-qa-db-fra.com

Exception d'analyse syntaxique Jackson - (bien qu'il existe au moins un créateur): aucune méthode constructeur / usine d'argument de chaîne à désérialiser de la valeur de chaîne

  • Version de démarrage de printemps: 1.5.10
  • Version Jackson: 2.9.5
  • Version de Lombok: 1.18.0

J'ai un scénario où j'envoie une charge utile à l'aide de kafka. En recevant cette charge utile, j'essaie de déterminer si la charge utile du récepteur et de l'expéditeur est identique ou non.

J'ai d'abord créé une classe qui sera transmise comme charge utile. La structure de la classe est indiquée ci-dessous. La version du plugin lombok utilisée est 1.18.0.

@Builder
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDummyClass implements Serializable{

    private static final long serialVersionUID = -4181985100899233094L;
    private String data;
    private String id;
}

Pour le pojo ci-dessus, j'ai créé un test unitaire où je passe une chaîne et j'essaie de convertir cela de String en objet qui est travailler sans problème.

@Test
public void shouldBeAbleToConvertStringToDesiredObjectType() throws IOException {
    String s = "{\r\n  \"data\" : \"foo\",\r\n  \"id\" : \"xyz\"\r\n}";
    MyDummyClass myDummyClass = convertValue(s, MyDummyClass.class);
    assertThat(myDummyClass.getData(), is("foo"));
}

La configuration jackson mapper est également donnée ci-dessous.

private static final ObjectMapper mapper = new ObjectMapper();

static {
    mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    mapper.disable(FAIL_ON_UNKNOWN_PROPERTIES);
    mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    mapper.enable(ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
    mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    // Skip the Null Values
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.disableDefaultTyping();

    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); //YYYY-MM-DDThh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45.003+01:00)
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    mapper.setDateFormat(dateFormat);
}

Venons-en maintenant à l'énoncé du problème principal. Donc, dans mon autre cas de test où j'envoie une charge utile via kafka et après avoir reçu la réponse de la rubrique kafka, j'essaie de convertir les données entrantes Chaîne données à la souhaitée MyDummyClass type de classe. Dans mon cas de test, j'ai mis la déclaration de l'enregistreur pour voir quelle valeur je reçois. Je peux voir que j'obtiens exactement la même valeur de chaîne mentionnée dans le cas de test ci-dessus. Mais lors de l'analyse de ce texte à désiré MyDummyClass type J'obtiens une erreur (bien qu'il existe au moins un créateur): pas de méthode constructeur/usine d'argument de chaîne à désérialiser de la valeur de chaîne.

@Test
public void messageWithAnyContractObjectCanBeConvertedToSameObjectAtTheListenerEnd() throws InterruptedException, IOException, JSONException {
    String correlationID = UUID.randomUUID().toString();
    String id = UUID.randomUUID().toString();
    MyDummyClass actualPayload = MyDummyClass.builder().data("foo").id("xyz").build();
    Message message = MessageBuilder.withAnyMessage()
            .withNoHeader(BaseHeader.builder().ID(id).correlationID(correlationID).sendToDestination("my-topic").build())
            .payload(actualPayload)
            .build();
    messagePublisher.publishMessage(message, DEFAULT_PUBLISHER_OPTIONS);

    String recordedString = records.poll(10, TimeUnit.SECONDS).value();
    LOGGER.info("Receiving Response {}", recordedString);
    MyDummyClass recordedValue = convertValue(recordedString, MyDummyClass.class);

    assertThat(recordedValue.getData(), is(actualPayload.getData()));
}

Journal d'erreur détaillé: enter image description here

6
SUMIT

Enfin, j'ai pu résoudre ce problème. Ce problème était le résultat d'un code incorrect écrit à côté de mon code éditeur où, d'abord, je chiffrais ma charge utile en convertissant ma charge utile entrée en objet json (en utilisant jackson), plus tard, je stockais à nouveau cette charge utile json à l'intérieur de l'objet avec en-tête et essayais de convertir cet objet en chaîne (à nouveau en utilisant le convertisseur jackson). Dans ce processus, je convertissais la charge utile entière en chaîne deux fois, par conséquent j'introduisais \r\n dans ma charge utile que j'envoyais via kafka. Lors de la reconversion en objet de json en objet, cet extra \r\n était à l'origine du problème que j'ai collé plus tôt.

Comme solution, j'ai stocké l'objet json déjà converti dans un autre objet avec annotation jackson @ JsonRawData. Cela empêche l'ajout de \r\n.

7
SUMIT