我正在实现restful API,我希望调用者指定一个人喜欢序列化的特定属性,如/dogs/1?fields=name,breed
。因此,如果狗有更多属性而不是名称和品种,我使用像jackson这样的标准序列化库,如何在运行时序列化时告诉jackson忽略其余的属性?
换句话说,告诉jackson在运行时动态忽略某些属性的方法是什么?
答案 0 :(得分:3)
您没有指定Jackson库的版本,因此我假设您使用的是2.2.0或最新版本。在杰克逊这不是一件容易的事,但我们可以做到这一点,例如BasicClassIntrospector。下面的源代码显示了它应该是什么样子。例如,我们有一个POJO类:
class User {
private String name;
private String surname;
// getters/setters
}
我们必须定义新的BasicClassIntrospector,它只返回我们需要的字段的bean定义对象:
class ExclusionAnnotationIntrospector extends BasicClassIntrospector {
private Collection<String> properties;
public ExclusionAnnotationIntrospector(Collection<String> properties) {
this.properties = properties;
}
@Override
public BasicBeanDescription forSerialization(SerializationConfig serializationConfig,
JavaType javaType, MixInResolver mixInResolver) {
BasicBeanDescription beanDesc = super.forSerialization(serializationConfig, javaType,
mixInResolver);
deleteUnwantedProperties(beanDesc);
return beanDesc;
}
private void deleteUnwantedProperties(BasicBeanDescription beanDesc) {
List<BeanPropertyDefinition> beanProperties = new ArrayList<BeanPropertyDefinition>(
beanDesc.findProperties());
for (BeanPropertyDefinition bpd : beanProperties) {
String name = bpd.getName();
if (!properties.contains(name)) {
beanDesc.removeProperty(name);
}
}
}
}
现在,我们必须使用上面的introspector创建新的ObjectMapper类。我们必须在构造函数中定义我们需要的属性:
class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper(Collection<String> properties) {
this._serializationConfig = getSerializationConfig().with(
new ExclusionAnnotationIntrospector(properties));
}
}
最后,示例用法:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.introspect.BasicBeanDescription;
import com.fasterxml.jackson.databind.introspect.BasicClassIntrospector;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
public class JacksonProgram {
public static void main(String[] args) throws Exception {
User user = new User();
user.setName("Tom");
user.setSurname("Garnier");
CustomObjectMapper onlyNameSerializer = new CustomObjectMapper(toSet("name"));
CustomObjectMapper onlySurnameSerializer = new CustomObjectMapper(toSet("surname"));
CustomObjectMapper fullUserSerializer = new CustomObjectMapper(toSet("name", "surname"));
System.out.println(onlyNameSerializer.writeValueAsString(user));
System.out.println(onlySurnameSerializer.writeValueAsString(user));
System.out.println(fullUserSerializer.writeValueAsString(user));
}
private static Set<String> toSet(String... params) {
HashSet<String> set = new HashSet<String>();
for (String item : params) {
set.add(item);
}
return set;
}
}
以上程序打印:
{"name":"Tom"}
{"surname":"Garnier"}
{"name":"Tom","surname":"Garnier"}
答案 1 :(得分:0)
我建议您查看http://flexjson.sourceforge.net/ (特别是使用包含/排除部分)
示例:
public String toJsonWithIncludes(Object obj, String...includes) {
return new JSONSerializer()
.include(includes)
.exclude("data.*","*.class")
.serialize(obj);
}
...
toJsonWithIncludes(obj, "name","breed");