0
votes

The front end sends this json to my API

{  
  "parameters":{  
      "MAIL_BODY":"saffsa",
      "MAIL_FROM":"sffasafs",
      "MAIL_RECEIVED_DATE":"asfasf",
      "MAIL_SUBJECT":"asfafs",
      "MAIL_TO":"ssfafs"
   },
   "templateID":"9093",
   "deliveryChannel":"NONE"
}

Controller:

 @RequestMapping(value = "/previewDocument", method = RequestMethod.POST, produces = "application/pdf")
public byte[] previewDocument(@RequestBody Map<String, String> parameters, @RequestBody String templateID, @RequestBody String deliveryChannel) {
    // TODO
}

But i'm getting this on my backend logs

2019-02-22 10:34:55.068 WARN 9976 --- [nio-8083-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of java.lang.String out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.lang.String out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 15] (through reference chain: java.util.LinkedHashMap["parameters"])]

I don't understand what is the issue. parameters seems to be a Map right? Can someone explain me why this does not work?

1
Not a Spring person, but your JSON content appears to be nested two levels deep. This is probably the cause of the exception. You need single level JSON which can be mapped to key value pairs. - Tim Biegeleisen
remove "@RequestBody String templateID, @RequestBody String deliveryChannel" in your previewDocument method. - Akash Shah
@SHAHAKASH I need those values as well. How do I get them then? - user10996797
create a class with Map<String, String> parameters; String templateId; String deliveryChannel and then use that as the sole parameter annotated with @RequestBody - Lino
create an object like this:- public class MyObject { private Map<String,String> parameters; private String templateID; private String deliveryChannel; } add Setters Getters - Mr Nobody

1 Answers

1
votes

replace Map<String, String> with Map<String, Object> and the parsing will succeed. the inner object gets parsed into a Map<String, String> .
you will need to cast/interrogate the type of the value in the method body something like

if (parameters.get("parameters") instanceof Map) {
  Map<String, String> parametersMap = (Map<String, String>)parameters.get("parameters");
  String body = parametersMap.get("MAIL_BODY");
}