0

I'm writing a simple REST service which expects a POST containing a Json. The service should refuse any Json not containing exactly the keys it expects. I'm using JAX-RS on a JBoss EAP 7.1 and have been unable to do this. Code example:

import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/")
@Stateless
@Produces("text/plain")
public class TestAccess
{
  @POST
  @Path("test/")
  @Consumes(MediaType.APPLICATION_JSON)
  public String consumeJson(TestClass c)
  {
    return c.toString();
  }

}
public class TestClass
{
  public String first;
  public String second;

  public String toString()
  {
    return (first + ", " + second);
  }
}

Previously I wrote consumeJson to expect expect a JsonObject and parsed that using a Jackson ObjectMapper. Doing this resulted in an error when receiving a Json missing keys. I think the way I'm doing it now is a "cleaner" way to do it as now the parameter list clearly shows what kind of Object the Json should describe. However, I don't want to check every single field first thing in the method nor do I want to add a isValid() method to every Object I get this way.

The example {"first" : "contentOfFirst"} returns "contentOfFirst, null" instead of failing.

EDIT: To clarify, I attempted something like this:

import javax.validation.constraints.NotNull;

public class TestClass
{
  @NotNull
  public String first;
  @NotNull
  public String second;

  public String toString()
  {
    return (first + ", " + second);
  }
}

This did not change the outcome, instead of failing (as it was supposed to) the POST still got the response "contentOfFirst, null". I'm aware these annotations still need a validator to validate them. I was (falsely?) under the impression that Jboss provides such a validator.

MrThaler
  • 124
  • 8

2 Answers2

1

Turns out I missed that you need another annotation to enforce the checks:

  @POST
  @Path("test/")
  @Consumes(MediaType.APPLICATION_JSON)
  public String consumeJson(@Valid TestClass c)
  {
    return c.toString();
  }

That's all that's needed for JBoss to actually enforce the checks.

It should be noted that JBoss doesn't like the use of @Valid and generic classes (like List<PathSegment>) in the same parameter list.

MrThaler
  • 124
  • 8
0

Modern jackson versions have @JsonCreator & @JsonProperty to do some validation during deserialization, e.g. for you case:

public class TestClass
{
    @JsonCreator
    TestClass(
            @JsonProperty(value = "first", required = true) Integer first,
            @JsonProperty(value = "second", required = true) Integer second) {
        this.first = first;
        this.second= second;
    }
    public String first;
    public String second;

    public String toString()
    {
        return (first + ", " + second);
    }
}

More robust solution would be to use Bean Validation

y_ug
  • 904
  • 6
  • 8
  • As noted in my original post I'm aware of annotations like `@NotNull`. I was unsuccessful in utilizing those, however. The framework doesn't seem to respect the annotations. – MrThaler Jan 21 '20 at 12:03
  • I didn't write anyting about `@NotNull`, sorry. It is for documentation purposes. There is a [separate thread on this issue](https://stackoverflow.com/questions/34094039/using-notnull-annotation-in-method-argument). Please check documentation for [JsonCreator](https://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonCreator.html). Or create failing testcase. – y_ug Jan 21 '20 at 12:18