This tutorial is a follow up to “Consume, produce and ignore JSON properties with Jersey2“. In that previous tutorial we explained the usage of @JsonIgnore and @JsonProperty to manipulate and filter JSON requests and responses using Jersey2 with FasterXML/Jackson. We will extend the provided example (Github) with the @JsonIgnoreProperties annotation.
1. Prerequisites
- Install Apache Tomcat (we use version 8.5). If not already installed, please have a look at these 2 tutorials:
- Install Apache Tomcat on Windows
- Add Tomcat server runtime to EclipseEE (if you work with EclipseEE)
- Install Apache Maven to build the project
- You can just run a “clean install” on the Maven project and deploy the created WAR file to Tomcat directly. Although we recommend to work with an IDE like EclipseEE or IntelliJ to adapt or debug the project
- Some tool to test the REST Api (we use Postman)
- If you import the Maven project to EclipseEE, activate and adapt the Project Facets to use the Dynamic Web Project 3.1, Java 1.8 and JAX-RS 2.0
2. Code step-by-step
We prepared two classes with the same content in terms of properties. The only difference is the usage of the @JsonIgnoreProperties( ignoreUnknown = false ) and @JsonIgnoreProperties( ignoreUnknown = true ). Additionally we use more complex Object types to showcase the JSON to POJO conversion (Date, List). We generate the id attribute randomly and do not want to use the property provided by JSON request. The date will be ignored as well and set to the current server time.
2.1 POST JSON request
{ "id" : 1, "title" : "This is a test post", "categories" : [ "category1", "category2" ], "postedAt" : 1513277265518, "undefinedProperty" : "Dont process me!" }
The JSON data contains all attributes of the POJO and an “undefinedProperty” addition to test the behavior of the @JsonIgnoreProperties annotation.
2.2 REST web service
@Path("/post") public class PostRestService extends ResourceConfig { final static Logger logger = Logger.getLogger( PostRestService.class ); @POST @Path("/ignorePropertiesTrue") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response ignorePropertiesTrue( PostIgnorePropertiesTrue post ) { logger.info( post ); return Response.ok( post, MediaType.APPLICATION_JSON ).build(); } @POST @Path("/ignorePropertiesFalse") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response ignorePropertiesFalse( PostIgnorePropertiesFalse post ) { logger.info( post ); return Response.ok( post, MediaType.APPLICATION_JSON ).build(); } }
The REST web service consists of two methods which each respond to the following POJOs.
2.3 Set @JsonIgnoreProperties false
@JsonIgnoreProperties( ignoreUnknown = false ) public class PostIgnorePropertiesFalse { @JsonIgnore private long id = 0; private String title = null; private List<String> categories = null; private Date postedAt = null; public PostIgnorePropertiesFalse() { id = (int) ( Math.random() * 1000 ); this.categories = new ArrayList<String>(); this.postedAt = new Date(); } @JsonProperty public long getId() { return id; } @JsonIgnore public void setId( long id ) { this.id = id; } public String getTitle() { return title; } public void setTitle( String title ) { this.title = title; } @JsonProperty public Date getPostedAt() { return postedAt; } @JsonIgnore public void setPostedAt( Date postedAt ) { this.postedAt = postedAt; } public List<String> getCategories() { return categories; } public void setCategories( List<String> categories ) { this.categories = categories; } @Override public String toString() { return "Post [id=" + id + ", title=" + title + ", categories=" + categories + ", postedAt=" + postedAt + "]"; }
If we send the POST request with the JSON data defined above to the server, we get an exception:
The exception is thrown because of the “undefinedProperty” defined in the JSON data. However, have a look at the full exception from the stack trace. You get information about the property causing the exception.
SEVERE: Servlet.service() for servlet [jersey2-consume-produce-ignore-json] in context with path [/jersey2-consume-produce-ignore-json] threw exception [org.glassfish.jersey.server.ContainerException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "undefinedProperty" (class com.tutorialacademy.rest.post.PostIgnorePropertiesFalse), not marked as ignorable (3 known properties: "title", "postedAt", "categories"]) at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@32b6dd21; line: 6, column: 25] (through reference chain: com.tutorialacademy.rest.post.PostIgnorePropertiesFalse["undefinedProperty"])] with root cause com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "undefinedProperty" (class com.tutorialacademy.rest.post.PostIgnorePropertiesFalse), not marked as ignorable (3 known properties: "title", "postedAt", "categories"]) at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@32b6dd21; line: 6, column: 25] (through reference chain: com.tutorialacademy.rest.post.PostIgnorePropertiesFalse["undefinedProperty"])
You can catch that exception in order to process or log the request. Now lets try to ignore the undefined property.
2.4 Set @JsonIgnoreProperties true
@JsonIgnoreProperties( ignoreUnknown = true ) public class PostIgnorePropertiesTrue { @JsonIgnore private long id = 0; private String title = null; private List<String> categories = null; private Date postedAt = null; public PostIgnorePropertiesTrue() { id = (int) ( Math.random() * 1000 ); this.categories = new ArrayList<String>(); this.postedAt = new Date(); } @JsonProperty public long getId() { return id; } @JsonIgnore public void setId( long id ) { this.id = id; } public String getTitle() { return title; } public void setTitle( String title ) { this.title = title; } @JsonProperty public Date getPostedAt() { return postedAt; } @JsonIgnore public void setPostedAt( Date postedAt ) { this.postedAt = postedAt; } public List<String> getCategories() { return categories; } public void setCategories( List<String> categories ) { this.categories = categories; } @Override public String toString() { return "Post [id=" + id + ", title=" + title + ", categories=" + categories + ", postedAt=" + postedAt + "]"; }
Using the same POST call we get the following result in Postman:
You can see that the request was successful and we received a correct response. Consequently, the “undefinedProperty” is ignored. You do not get an exception here and have no chance to log a probably incorrect client request. Notice the differences between the request and response with the id or date property. That is attributed to the implementation and @JsonIgnore and @JsonProperty annotations.
3. Conclusion
Both approaches with @JsonIgnoreProperties true and false make sense. If set to true, you only parse JSON properties that match your POJO definition. But you have no chance to log or notify your client that the request consists of wrong or redundant data.
In contrary, you will receive an exception with the exact problem description if set to false. The problem description contains e.g. which property did not match any objects in your POJO etc.
If you have errors or problems, feel free to comment and ask.





