gpt4 book ai didi

java - 任何人都可以建议一些在 Restful 服务中支持部分表示的最佳实践吗

转载 作者:行者123 更新时间:2023-12-01 23:36:38 25 4
gpt4 key购买 nike

我正在实现restful API,我希望调用者指定想要序列化的特定属性,例如/dogs/1?fields=name,breed。因此,如果狗除了名称和品种之外还有更多属性,并且我正在使用像 jackson 这样的标准序列化库,我如何告诉 jackson 在运行时序列化时忽略其余属性?

换句话来说,告诉 jackson 在运行时动态忽略某些属性的方法是什么?

最佳答案

您没有指定 Jackson 库的版本,因此我假设您使用的是 2.2.0 或最新版本。在 jackson ,这不是一件容易的事,但我们可以做到,例如,使用 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);
}
}
}
}

现在,我们必须使用上面的内省(introspection)器创建新的 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"}

关于java - 任何人都可以建议一些在 Restful 服务中支持部分表示的最佳实践吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18580592/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com