Java 传递到Jersey+;时从实体中删除字段;杰克逊
我正在使用Jersey+Jackson(内置Dropwizard)创建一系列web服务。我通过将对象传递给Jersey中的响应对象,直接映射Json中的对象:Java 传递到Jersey+;时从实体中删除字段;杰克逊,java,json,jersey,jackson,dropwizard,Java,Json,Jersey,Jackson,Dropwizard,我正在使用Jersey+Jackson(内置Dropwizard)创建一系列web服务。我通过将对象传递给Jersey中的响应对象,直接映射Json中的对象: myObject object = new myObject(fields...); return Response.ok(object).build(); 字段在myObject类中使用JsonProperty(“fieldName”)正确注释 但是,如果我有一个字段需要存储到数据库(例如:密码散列),但我不想传入请求响应,那么在将实
myObject object = new myObject(fields...);
return Response.ok(object).build();
字段在myObject类中使用JsonProperty(“fieldName”)正确注释
但是,如果我有一个字段需要存储到数据库(例如:密码散列),但我不想传入请求响应,那么在将实体传递到响应对象时如何删除该字段
我不能用JsonIgnore对字段进行注释,否则当我将Json映射到数据库(ElasticSearch)时,该字段将不会被序列化。一个选项是简单地将字段设置为
null
。要将ObjectMapper
配置为在字段为null时完全忽略JSON中的字段,只需执行以下操作
@Override
public void run(YourConfiguration configuration,
Environment environment) throws Exception {
...
environment.getObjectMapper().setSerializationInclusion(Include.NON_NULL);
}
另一方面,这种安全性是使用DTO(数据传输对象)的原因之一,DTO是一个额外的实体“视图”层,它将我们发送的表示与持久性层(db实体对象)分离。创建另一个具有相同/相似属性的对象似乎是多余的,但安全填充是值得的
另外,虽然还不是正式发布,但它使用了Jersey 2,它允许我们过滤掉我们不想发送的数据,而无需创建DTO。我只是想提一下。您应该同时使用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;
}
}
@setter方法上的JsonProperty将用于序列化,getter方法上的JsonIgnore将用于反序列化 实际上@Manikandan的答案应该适合你。看 在最坏的情况下,您可以尝试实现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;
}
}
公共类MyObjectSerializer扩展JsonSerializer{
@凌驾
public void serialize(MyObject值、JsonGenerator jgen、SerializerProvider提供程序)引发IOException、JsonProcessingException{
jgen.writeStartObject();
writeString(value.getField1());
writeString(value.getField2());
/*并且不包括您不想序列化的字段*/
jgen.writeEndObject();
}
}
@JsonSerialize(使用=MyObjectSerializer.class)
公共类MyObject{
字符串字段1;
整型字段2;
字符串字段不进行序列化;
公共字符串getField1(){
返回字段1;
}
公共无效集合字段1(字符串字段1){
此字段1=字段1;
}
公共整数getField2(){
返回字段2;
}
公共无效集合字段2(整数字段2){
this.field2=field2;
}
公共字符串getFieldNotToBeSerialized(){
返回字段不进行序列化;
}
public void setFieldNotToBeSerialized(字符串字段nottobeserialized){
this.fieldNotToBeSerialized=fieldNotToBeSerialized;
}
}
谢谢,但在这种情况下,即使在应用程序的“内部”,我也不会得到密码字段;我需要它在登录时验证用户。你说的“在”应用程序内部是什么意思。您可以直接在应用程序内使用对象。它将具有密码值。我将对象直接存储在JS上。如果我添加JsonIgnore来获得;当我将对象映射到JSON时,更新时会丢失密码字段;我从未使用过实体过滤,但我认为这是实现我所需要的最好方法。能否提供Dropwizard中实体筛选的示例(我使用的是DW 0.8.0-rc1)?实体筛选是否可能只在单个资源/路由上工作,而不在全局应用程序级别工作?我刚刚意识到它目前不支持Jackson。我一直在研究如何实现一些东西,但这绝非小事。我的意思是使用DTO或将其设置为null。如果您想要一个更优雅的解决方案(不必在resource方法中将字段设置为null),可以使用JAX-RS拦截器,但在这样做之前我会三思。一些安全的东西,比如密码,我会让它尽可能远离最终进程