1

Currently when inputting a json object as the body of a POST request, Jersey will ignore any key/value pairs that it does not recognize.

Example:

public class TestObject{
    private String value1;
    private Integer value2;

    // appropriate getters and setters
}

JSON object:

{
"value1":"test",
"value2":1,
"value3":"wrong"
}

In the above case, Jersey will accept the two expected values and create the TestObject ignoring the "value3" input.

Is there a way to force Jersey to throw an exception instead of ignoring the value if anything in the JSON object is not recognized?

Edit:

My Controller would look something like this:

@POST
@Consumes("application/json")
public Response handleTestObject(TestObject testObject){
//method execution here
}

So I'm relying on Jersey to convert the json input to a TestObject

Stitch86
  • 13
  • 4
  • Instead of sending a "wrong" in the body of the POST, why don't you try sending a different status code. For example if "wrong" means that a value was not filled, you could send 400 (bad request). – Tom Piaggio Jan 31 '18 at 16:59
  • That value3 is a part of the user input, not my response – Stitch86 Jan 31 '18 at 17:03
  • What are u using to convert Json to object? – Indraneel Bende Jan 31 '18 at 17:30
  • https://stackoverflow.com/questions/31094305/java-gson-getting-the-list-of-all-keys-under-a-jsonobject . I feel Jersey would be using either Jackson/gson for conversion. Accept a string and before you convert to object, check all the keys. If invalid return 400 . The above link will help u check the keys – Indraneel Bende Jan 31 '18 at 17:41
  • Before trying the above. Try to convert json to object urself using Jackson or gson. I am pretty sure it should throw an exception – Indraneel Bende Jan 31 '18 at 17:52
  • I added more info to the original post. I am relying on Jersey to convert the json to the object. I'm specifically looking for a way for Jersey to throw the exception for an unrecognized value rather than rewriting my application to handle the conversion myself. – Stitch86 Jan 31 '18 at 18:42

1 Answers1

0

When you use jackson for conversion, it should actually throw an exception by default if unknown parameters are passed. I've tried this with jackson 2.26:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.26</version>
</dependency>

And it threw the following exception without any further configuration:

Unrecognized field "value3" (class de.jan.model.TestObject), not marked as ignorable (one known property: "test"])
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@2ff055a5; line: 1, column: 25] (through reference chain: de.jan.model.TestObject["value3"])%

So in case you're not constrained to anything else, you might just switch to jackson for conversion.

If you're already using jackson but still don't get this exception, you (or some library you're using) might have disabled this behaviour somewhere. To bring it back, you can add the following annotation to your class TestObject:

 @JsonIgnoreProperties(ignoreUnknown = false)

which will cause jackson to throw an exception for additional fields when deserialising instances of this particular class.

To configure this behaviour for all objects, you need to create a custom ObjectMapper resolver like this:

@Provider
@Produces("application/json")
public class ObjectMapperResolver implements ContextResolver<ObjectMapper> {

    private final ObjectMapper mapper;

    public ObjectMapperResolver() {
        mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }
}  

and register this class in your ResourceConfig.

If you're using gson, there is probably not much you can do. There is an open issue for supporting unknown properties handlers but so far it hasn't made it to the release. You can find more information about this, including a code snipped to manually check for additional fields, in their issue tracker

Jan Gassen
  • 3,406
  • 2
  • 26
  • 44
  • Thanks! This is great! My only issue is that I would like to catch the error and send my own message back to the client. I have a Provider that implements an ExceptionMapper and it's not catching the Jackson exception. Do you have any suggestions? – Stitch86 Feb 02 '18 at 19:29
  • I think you can find an answer for that here https://stackoverflow.com/questions/5833147/jersey-jackson-exception-problem-with-exceptionmapper – Jan Gassen Feb 02 '18 at 19:33