通过将@JsonProperty值传递给对象映射器来标识属性

时间:2015-09-09 05:47:43

标签: java json spring hibernate jackson

我正在使用spring和hibernate。我有一个包含很多字符串成员变量的类(DTO)。我试图实现这个类的搜索。用户应该能够按每个字段进行搜索。我使用jackson json mapper来序列化和反序列化对象。无论如何使用JsonProperty值来识别fieldName?

这是一个例子:我的DTO

public class SampleDTO{
  private String field1;
  private String field2;
  private String field3;
  private String field4;
  @JsonProperty("FIELD_1")
  public String getField1(){
    return field1;
  }
  @JsonProperty("FIELD_2")
  public String getField2(){
    return field2;
  }
  @JsonProperty("FIELD_3")
  public String getField3(){
    return field3;
  }
  @JsonProperty("FIELD_4")
  public String getField4(){
    return field4;
  }
}

让这成为我的搜索功能

public Set<T> search(String fieldName, String searchKeyword) {
   String originalFieldName = someMagicFunction(fieldName);
   //if fieldName= "FIELD_1", someMagicFunction should return "field1"
   Criteria criteria = session.createCriteria(T.class);
   criteria.add(Restrictions.eq(originalFieldName, searchKeyword));
   return new HashSet<T>(criteria.list());
} 

任何实施都没问题。我正在寻找一种处理这类案件的好方法。感觉就像手动查找字段涉及太多打字&#34;。

2 个答案:

答案 0 :(得分:2)

你基本上想要使用反射。在字段查找方面,有两种可能性:

  • @JsonProperty注释的值
  • 该字段的真实姓名

在第一种情况下,你可能想要使用一些额外的库来减轻使用反射+注释时的痛苦,但原始代码看起来更像是这样:

    SampleDTO dto = new SampleDTO();
    // setup some values here

    Field[] fields = r.getClass().getFields();

    for(Field f : fields) {
        JsonProperty jsonProperty = f.getDeclaredAnnotation(JsonProperty.class);

        if (jsonProperty != null && jsonProperty.value().equals("FIELD_1")) {
            return (String) f.get(dto);
        }

        // throw exception since passed field name is illegal
     }        

在第二个中它会更容易:

    SampleDTO dto = new SampleDTO();
    // setup some values here

    String field1Value = (String) r.getClass().getField("field1").get(dto);

答案 1 :(得分:0)

如果有人感兴趣,这就是我解决问题的方法。我将此代码添加到DAO的构造函数中。

try {

  BeanInfo beanInfo = Introspector.getBeanInfo(T.class);
  Method[] methods = T.class.getMethods();
  PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
  for(PropertyDescriptor propertyDescriptor: propertyDescriptors) {
    //I'm looking for string fields only
   if (propertyDescriptor.getPropertyType().equals( String.class)) {
   //My annotations are on methods
    for(Method method: methods) {
    if(propertyDescriptor.getReadMethod().equals(method)) {
      JsonProperty jsonProperty = method.getAnnotation(JsonProperty.class);
      if (jsonProperty != null) {
        //jsonFieldMapping is a Map<String,String> 
        //will be saving the mapping in the format {"FIELD_1":"field1", "FIELD_2":"field2"}
        jsonFieldMapping.put(jsonProperty.value(), propertyDescriptor.getDisplayName());
      } else {
        logger.debug("jsonProperty is null");
      }
    }
  }
}
  }
  // just printing out the values identified from class
  for(String key: jsonFieldMapping.keySet()) {
logger.debug("key: " + key + "value: " + jsonFieldMapping.get(key));

  }
} catch (IntrospectionException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

所以,我的神奇方法将是

public String getField(String jsonFieldName){
  if (jsonFieldMapping.containsKey(jsonFieldName)) {
      return jsonFieldMapping.get(jsonFieldName);
    } else {
      throw new IllegalArgumentException("searching field not found");
    }
}

我没有完全测试过这段代码。看起来日志中的值是正确的。