I have a Spring Boot controller that consumes JSON:
@PostMapping(
value = "/shipdetails")
public ResponseEntity acceptShip(@RequestBody Ship ship, HttpServletRequest request) {
shipService.checkShip(ship);
return new ResponseEntity<>(HttpStatus.OK);
}
There is a corresponding Ship Entity:
public class Ship implements Serializable {
@JsonProperty("Name")
private String name;
@JsonProperty("Owner")
private String owner;
public Ship(String name, String owner) {
this.name = name;
this.owner = owner; }
public Ship() {
}
// Getters and Setters removed for brevity
And finally the service:
@Service
public class ShipService {
Boolean checkShip(Ship ship) {
if (ship.getName().equals("Queen Mary")) {
// do something
}
//edited for brevity
Sample invalid JSON:
{
"name_wrong":"test name",
"owner":"Lloyds Shipping"
}
Currently the error I get on the stacktrace if I send invalid JSON is (service layer) : Cannot invoke "String.equals(Object)" because the return value of "com.ships.Ship.getName()" is null
.
Jackson needs the no-args constructor for de-serialization.
When inspecting in the debugger the Ship entity has a owner set, but not a name set, so its not the the whole entity is null – just one field.
I tried my Ship entity without a default no args constructor so you could not even pass entity with a null field to the service but then it fails with even valid JSON.
How and where should the exception for invalid JSON be handled?
2
Answers
Rather than viewing the issue as being a misnamed field, think of it as instead being two issues: a missing property (
name
) and an extra property (name_wrong
).Spring Boot is configured by default to ignore any extra properties. And unless you tell the controller that the
name
property is required (e.g. by using the@NotNull
bean validation annotation on thename
field), it will happily accept a null value for this property.Missing required property
The
NullPointerException
is happening since you’re attempting to callequals
on thenull
name
field.There are a few different fixes for this. First, you could add a bean validation to the required fields:
Alternatively, you could change the equals method to be null-safe:
Extra property
There are several ways to have Spring reject the extra
name_wrong
property.If you want the application to always reject unknown properties (unless a particular bean opts out of it), you can configure it globally:
application.yml
Need to add few annotations and checks for the validation of the request body json.
1. Add dependency in pom.xml for the below annotations-
2. @Valid with Request Body
3. @NotNull with the mandatory attributes
4. Additional null check before equals method
Output with Invalid json:
Input
Output:
You will get a 400 Bad request status with the long error stack trace includes something like this