Reputation: 1343
I have the following class, which I am using as a request payload :
public class SampleRequest {
private String fromDate;
private String toDate;
// Getters and setters removed for brevity.
}
I am trying to use it with this resource below (just trying to print it to screen to see things happen) :
@PostMapping("/getBySignatureOne")
public ResponseEntity<?> getRequestInfo(@Valid @RequestBody SampleRequest signatureOneRequest) {
System.out.println(signatureOneRequest.getToDate);
System.out.println(signatureOneRequest.getFromDate);
}
This is the JSON request I send up :
{
"fromDate":"2019-03-09",
"toDate":"2019-03-10"
}
This is the error I get :
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.test.app.payload.SampleRequest` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('fromDate'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.test.app.payload.SampleRequest` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('fromDate')
at [Source: (PushbackInputStream); line: 1, column: 2]]
I'd love to know what's wrong here, I suspect its an issue with constructors, or that I am missing some annotation somewhere, but I am honestly unsure of where I have gone wrong.
Upvotes: 32
Views: 127671
Reputation: 139
In my case it was incorrect method usage: I used ObjectMapper::convertValue
, but should've used ObjectMapper::readValue
to convert my JSON from Rabbit to POJO.
As a result of the mistake this error appeared:
java.lang.IllegalArgumentException: Cannot construct instance of
com.hrsinternational.tng4.common.attributes.dto.order.BookingDatesResource
(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"...."}') at [Source: UNKNOWN; byte offset: #UNKNOWN]
Upvotes: 5
Reputation: 1934
In my case i was missing the No Args contructor
@Data
@AllArgsConstructor
@NoArgsConstructor
for those who are not using Lombok do add no args constructor in the mapping pojo
public ClassA() {
super();
// TODO Auto-generated constructor stub
}
also dont forget to add the Bean of Restemplate in main file if you are using the same
Upvotes: 9
Reputation: 380
Hi you need to write custom deserializer as it not able to parse String (fromDate and toDate) to Date
{ "fromDate":"2019-03-09", "toDate":"2019-03-10" }
this link has a tutorial to get started with custom deserializer https://www.baeldung.com/jackson-deserialization
Deserializer could be written like this.
public class CustomDateDeserializer extends StdDeserializer<Date> {
private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Date deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
String date = jsonparser.getText();
try {
return formatter.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}}
You can register the deserializer at Class itself like this.
@JsonDeserialize(using = ItemDeserializer.class)
public class Item { ...}
Or either you can register custom deserializer manually like this
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Item.class, new ItemDeserializer());
mapper.registerModule(module);
Upvotes: 5
Reputation: 26076
You need a constructor with all parameters:
public SampleRequest(String fromDate, String toDate) {
this.fromDate = fromDate;
this.toDate = toDate;
}
Or using @AllArgsConstructor
or @Data
from lombok.
Upvotes: 25