Search code examples
javaspring-bootrestclientwebclient

Unrecognized token 'message': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')


When I send a post request, I get this error.

Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'message': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
 at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 9]

and this is Stack Trace:

Stack trace:
        at org.springframework.http.codec.json.AbstractJackson2Decoder.processException(AbstractJackson2Decoder.java:242) ~[spring-web-5.3.12.jar:5.3.12]
        at org.springframework.http.codec.json.AbstractJackson2Decoder.decode(AbstractJackson2Decoder.java:198) ~[spring-web-5.3.12.jar:5.3.12]
        at org.springframework.http.codec.json.AbstractJackson2Decoder.lambda$decodeToMono$1(AbstractJackson2Decoder.java:179) ~[spring-web-5.3.12.jar:5.3.12]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:125) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:295) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:159) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.11.jar:3.4.11]
        at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:400) ~[reactor-netty-core-1.0.12.jar:1.0.12]
        at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:419) ~[reactor-netty-core-1.0.12.jar:1.0.12]
        at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:473) ~[reactor-netty-core-1.0.12.jar:1.0.12]
        at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:702) ~[reactor-netty-http-1.0.12.jar:1.0.12]

I have such a this JSON which sending to the server from client.

{
  "message": "string",
  "originator": "string",
  "receivers": "string"
}

and this is my service layer method which generate Webclient codes in there.

   @Override
    public Mono<ResponseEntity<? extends ResponseResource>> sendSms(BulkSmsRequestResourceTest request) {
        if (request == null) {
            return Mono.just(new ResponseEntity<>(
                    new ErrorResponseResource(
                            "Transaction failed unsuccessfully!",
                            400),
                    HttpStatus.BAD_REQUEST));
        }
        Mono<BulkSmsRequestResourceTest> bulkSmsRequestResourceMono = webClientBuilder.build()
                .post()
                .uri(sendSmsService)
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .body(Mono.just(request), BulkSmsRequestResourceTest.class)
                .retrieve()
                .bodyToMono(BulkSmsRequestResourceTest.class);
        bulkSmsRequestResourceMono.subscribe();
        return Mono.just((new ResponseEntity<>(new SuccessResponseResource("Transaction done successfully", 200), HttpStatus.OK)));
    }

although I am getting error, but data successfully stored into database.

This is me dto class

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BulkSmsRequestResourceTest {

    @JsonProperty("message")
    private String message;

    @JsonProperty("receivers")
    private String receivers;
    
    @JsonProperty("originator")
    private String originator;

}

and this is my server response code:

@Override
public String save(BulkSmsRequestDto bulkSmsRequestDto) {
if (bulkSmsRequestDto == null) {
    return "message unsuccess sended";
}
BulkSms bulkSms = BulkSms.builder()
        .message(bulkSmsRequestDto.getMessage())
        .phoneNumber(bulkSmsRequestDto.getReceivers())
        .originator(bulkSmsRequestDto.getOriginator())
        .build();
this.bulkSmsRepository.save(bulkSms);
return "message success sended";
}

Solution

  • It seems to me that you are sending a message property that is not expected at all by the service you are calling.

    You are setting BulkSmsRequestResourceTest as both the body request and also the body response. Are you sure that the server is expecting message property in the request and will also include message in the response?


    Your additional code just shows this is in fact true. Your server is answering with a simple String ("message success sended"), but you are expecting it to be an object (BulkSmsRequestResourceTest). Please update your code to the following one:

    @Override
    public Mono<ResponseEntity<? extends ResponseResource>> sendSms(BulkSmsRequestResourceTest request) {
       if (request == null) {
           return Mono.just(new ResponseEntity<>(
                   new ErrorResponseResource(
                           "Transaction failed unsuccessfully!",
                           400),
                   HttpStatus.BAD_REQUEST));
       }
       Mono<String> bulkSmsRequestResourceMono = webClientBuilder.build()
               .post()
               .uri(sendSmsService)
               .contentType(MediaType.APPLICATION_JSON)
               .accept(MediaType.APPLICATION_JSON)
               .body(Mono.just(request), BulkSmsRequestResourceTest.class)
               .retrieve()
               .bodyToMono(String.class);
       bulkSmsRequestResourceMono.subscribe();
       return Mono.just((new ResponseEntity<>(new SuccessResponseResource("Transaction done successfully", 200), HttpStatus.OK)));
    }