0

I'm using Jersey + Jackson (built in in Dropwizard) to create a series of web services. I directly map objects in Json by passing them to Response object in Jersey:

myObject object = new myObject(fields...);
return Response.ok(object).build();

Fields are correctly annotated in myObject class with JsonProperty("fieldName").

But, in case I have a field that I need to store to database (ex: a password hash), but I do not want to pass in request responses, how can I remove that field when passing the entity to Response object?

I can't annotate the field with JsonIgnore, otherwise that field won't be serialized at all when I map the Json to database (ElasticSearch).

Carmine Giangregorio
  • 943
  • 2
  • 14
  • 35

3 Answers3

2

One option is to simply set the field to null. To configure the ObjectMapper to ignore the field in the JSON altogether when the field is null, you can just do

@Override
public void run(YourConfiguration configuration,
        Environment environment) throws Exception {
    ...
    environment.getObjectMapper().setSerializationInclusion(Include.NON_NULL);
}

As an aside, this security reason a one of the reasons to use DTOs (data transfer objects), an extra entity "view" layer that separates the representation we send out from the persistence layer (db entity object). It may seem redundant to create another object with the same/similar attributes, but the security padding is worth it.

Also, though not an official release yet, Dropwizard 0.8.0 uses Jersey 2, which introduced Entity Filtering, which allows us filter out the data we don't want sent out, without the need to create DTOs. Just thought I'd mention it.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Thanks; I have never used the Entity Filtering, but I think it's the best way to achieve what I need. Could you provide an example of Entity Filtering in Dropwizard (I'm using DW 0.8.0-rc1)? Is it possibile to have entity filtering work only on a single resource/route, and not at global application level? – Carmine Giangregorio Jan 09 '15 at 10:39
  • I just realized that it doesn't support Jackson currently. I've been looking into trying to implement something, but it is far from trivial. I's say just go with a DTO or set it null. If you want a more elegant solution (not having to set the field to null in the resource method), you can use JAX-RS interceptors, but I would think twice before doing this. Something secure like a password, I would keep it as far away from the end process as possible – Paul Samsotha Jan 09 '15 at 12:16
0

You should use both JsonIgnore and JsonProperty to achieve this.

  public class User {

  private String name;
  private String password;

  @JsonProperty    
  public void setPassword(String password) {
    this.password = password;
  }

  @JsonIgnore
  public String getPassword() {
    return this.password;
  }

}

@JsonProperty on setter method will be used in serialization & JsonIgnore on getter method will be used in deserialization.

Manikandan
  • 3,025
  • 2
  • 19
  • 28
0

Actually @Manikandan answer should work for you. See Only using @JsonIgnore during serialization, but not deserialization

In worst case you may try to implement JsonSerializer.

public class MyObjectSerializer extends JsonSerializer<MyObject> {

    @Override
    public void serialize(MyObject value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeString(value.getField1());
        jgen.writeString(value.getField2());
        /* and not include field that you don't want to serialize */
        jgen.writeEndObject();
    }

}

@JsonSerialize(using = MyObjectSerializer.class)
public class MyObject {

    String field1;
    Integer field2;
    String fieldNotToBeSerialized;

    public String getField1() {
        return field1;
    }
    public void setField1(String field1) {
        this.field1 = field1;
    }
    public Integer getField2() {
        return field2;
    }
    public void setField2(Integer field2) {
        this.field2 = field2;
    }
    public String getFieldNotToBeSerialized() {
        return fieldNotToBeSerialized;
    }
    public void setFieldNotToBeSerialized(String fieldNotToBeSerialized) {
        this.fieldNotToBeSerialized = fieldNotToBeSerialized;
    }

}
Community
  • 1
  • 1
Adem Özay
  • 59
  • 2
  • 4