2

I’m trying to use a OpenFeign client to hit an API, get some JSON, and convert it to a POJO array.

Previously I was simply getting a string of JSON and using Gson to convert it to the array like so

FeignInterface {
    String get(Request req);
}
String json = feignClient.get(request);
POJO[] pojoArray = new Gson().fromJson(json, POJO[].class);

This was working. I would like to eliminate the extra step and have feign auto decode the JSON and return a POJO directly though, so I am trying this

FeignInterface {
    POJO[] get(Request req);
}
POJO[] pojoArray = feignClient.getJsonPojo(request);`

I am running into this error

feign.codec.DecodeException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 2 path $

Both methods used the same builder

feignClient = Feign.builder()
     .encoder(new GsonEncoder())
     .decoder(new GsonDecoder())
     .target(FeignInterface.class, apiUrl);

Anyone have any ideas?

shanjib_
  • 65
  • 7
  • 1
    Could you share an example `JSON` payload? It looks like it is not sent as `JSON` but rather as `String` so it starts from `"` instead of `[` or `{`. Probably you need to register some kind of interceptor which will let you remove `"` from incoming payload. See [“Expected BEGIN_OBJECT but was STRING at line 1 column 1”](https://stackoverflow.com/questions/28418662/expected-begin-object-but-was-string-at-line-1-column-1/28418787) – Michał Ziober Mar 05 '19 at 22:32
  • Why do you want an array specifically? It's more usual to use a `Collection` or `List`. – chrylis -cautiouslyoptimistic- Mar 05 '19 at 22:57
  • @chrylis I do convert it to a `List` afterwards, but regardless I don't understand why it isn't returning as an array – shanjib_ Mar 06 '19 at 14:45
  • @MichałZiober [\r\n {\r\n "key": "value",\r\n etc etc – shanjib_ Mar 06 '19 at 14:48
  • It does not look well. You can only have `new lines` in values. See [How do I handle newlines in JSON?](https://stackoverflow.com/questions/42068/how-do-i-handle-newlines-in-json) – Michał Ziober Mar 06 '19 at 15:45
  • Have you fixed your problem? What was the final way to fix it? – Michał Ziober Mar 11 '19 at 20:12
  • 1
    @MichałZiober your original comment about it being a `String` was correct. I implemented a new `feign.codec.Decoder` and using that I was able to make the Feign client return the json as a pojo array. – shanjib_ Mar 12 '19 at 19:01
  • @shanjib_, great to hear that. If you think my answer was helpful, please, consider to read [How does accepting an answer work?](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). It will make clear for others that this is a way to go. – Michał Ziober Mar 12 '19 at 19:13

1 Answers1

0

You have broken JSON payload. Before serialising you need to remove all unsupported characters. Feign allows this:

If you need to pre-process the response before give it to the Decoder, you can use the mapAndDecode builder method. An example use case is dealing with an API that only serves jsonp, you will maybe need to unwrap the jsonp before send it to the Json decoder of your choice:

public class Example {
  public static void main(String[] args) {
    JsonpApi jsonpApi = Feign.builder()
         .mapAndDecode((response, type) -> jsopUnwrap(response, type), new GsonDecoder())
         .target(FeignInterface.class, apiUrl);
  }
}

So, you need to do the same in your configuration and:

  • trim response and remove all whitespaces at the beginning and end of payload.
  • remove all new_line characters like: \r\n, \r, \n

Use online tool to be sure your JSON payload is valid and ready to be deserialised .

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146