2015-01-08 1 views
0

Я использую Джерси + Джексон (встроенный в Dropwizard), чтобы создать серию веб-сервисов. Я непосредственно на карте объекты в Json, передавая их в объект ответа в Джерси:Удалить поле из сущности при переходе на Джерси + Джексон

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

поля правильно аннотированный в классе MyObject с JsonProperty («FIELDNAME»).

Но в случае, если у меня есть поле, которое мне нужно сохранить в базе данных (например, хеш-пароль), но я не хочу передавать ответы на запрос, как я могу удалить это поле при передаче объекта в Response объект?

Я не могу аннотировать поле с помощью JsonIgnore, иначе это поле не будет сериализовано вообще, когда я буду сопоставлять Json с базой данных (ElasticSearch).

ответ

2

Один из вариантов - просто установить поле null. Чтобы настроить ObjectMapper игнорировать поле в формате JSON в целом, когда поле является пустым, вы можете просто сделать

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

Как в стороне, это из соображений безопасности один из причин использовать DTOs (объекты передачи данных), дополнительный слой «вид», который разделяет представление, которое мы отправляем, из слоя сохранения (объект сущности db). Может показаться излишним создать другой объект с теми же/похожими атрибутами, но это полезно.

Кроме того, еще не официальный релиз Dropwizard 0.8.0 использует Jersey 2, в котором вводится Entity Filtering, что позволяет нам отфильтровывать данные, которые мы не хотим отправлять, без необходимости создавать DTO. Просто подумал, что я упоминаю об этом.

+0

Thanks; Я никогда не использовал Фильтрацию объектов, но я думаю, что это лучший способ добиться того, что мне нужно. Не могли бы вы привести пример фильтрации объектов в Dropwizard (я использую DW 0.8.0-rc1)? Возможно ли, чтобы фильтрация объектов работала только на одном ресурсе/маршруте, а не на глобальном уровне приложения? –

+0

Я только что понял, что сейчас он не поддерживает Джексона. Я пытаюсь что-то реализовать, но это далеко не тривиально. Я говорю, просто пойдите с DTO или установите его нулевым. Если вы хотите более элегантное решение (не нужно устанавливать поле null в методе ресурса), вы можете использовать перехватчики JAX-RS, но я подумал бы дважды, прежде чем делать это. Что-то вроде пароля, я бы держал его как можно дальше от конечного процесса –

+1

Объекты DTO +1. – Natan

0

Чтобы достичь этого, вы должны использовать JsonIgnore и JsonProperty.

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 на инкубационном методе будет использоваться в сериализации & JsonIgnore по методу геттерного будет использоваться в десериализации.

+0

Спасибо, но в этом случае я не получу поле пароля даже «внутри» приложения; и мне нужно это для проверки пользователя при входе в систему. –

+0

Что вы подразумеваете под «внутри» приложения. Вы можете использовать объект непосредственно внутри аппликации. Он будет иметь значение пароля. – Manikandan

+0

Я хранил объект прямо на JS. Если я добавлю JsonIgnore; когда я сопоставляю объект с JSON, я бы потерял поле пароля при обновлении. –

0

Фактически ответ @Manikandan должен работать на вас. См. Only using @JsonIgnore during serialization, but not deserialization

В худшем случае вы можете попробовать реализовать 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; 
    } 

}