json 如何排除 Jackson 不使用注释的字段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13764280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I exclude fields with Hymanson not using annotations?
提问by Roman
I need to exclude some fields by names before rendering. The list of fields is dynamic, so I can't use annotations.
我需要在渲染之前按名称排除一些字段。字段列表是动态的,所以我不能使用注释。
I've tried to create custom serializer but I can't get field name there.
我试图创建自定义序列化程序,但我无法在那里获取字段名称。
In GSON I've used ExclusionStrategy, but Hymanson has no such functionality. Is there an equivalent?
在 GSON 中我使用过ExclusionStrategy,但 Hymanson 没有这样的功能。有等价物吗?
回答by Programmer Bruce
The below example of excluding fields by name is from my blog post, Gson v Hymanson - Part 4. (Search for the PropertyFilterMixIn.) This example demonstrates using a FilterProviderwith a SimpleBeanPropertyFilterto serializeAllExcepta user-specified list of field names.
以下按名称排除字段的示例来自我的博客文章 Gson v Hymanson - Part 4。(搜索PropertyFilterMixIn。)此示例演示如何将 aFilterProvider与 aSimpleBeanPropertyFilter一起serializeAllExcept用于用户指定的字段名称列表。
@JsonFilter("filter properties by name")
class PropertyFilterMixIn {}
class Bar
{
public String id = "42";
public String name = "Fred";
public String color = "blue";
public Foo foo = new Foo();
}
class Foo
{
public String id = "99";
public String size = "big";
public String height = "tall";
}
public class HymansonFoo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.getSerializationConfig().addMixInAnnotations(
Object.class, PropertyFilterMixIn.class);
String[] ignorableFieldNames = { "id", "color" };
FilterProvider filters = new SimpleFilterProvider()
.addFilter("filter properties by name",
SimpleBeanPropertyFilter.serializeAllExcept(
ignorableFieldNames));
ObjectWriter writer = mapper.writer(filters);
System.out.println(writer.writeValueAsString(new Bar()));
// output:
// {"name":"James","foo":{"size":"big","height":"tall"}}
}
}
(Note: The relevant API may have changed slightly with a recent Hymanson release.)
(注意:相关 API 可能在最近的 Hymanson 版本中略有变化。)
While the example does use a seemingly unnecessary annotation, the annotation is not applied to the fields to be excluded. (To help get the API changed to simplify the necessary configuration a bit, please don't hesitate to vote for implementation of issue HymanSON-274.
尽管该示例确实使用了看似不必要的注释,但该注释并未应用于要排除的字段。(为了帮助更改 API 以稍微简化必要的配置,请不要犹豫投票支持问题HymanSON-274 的实现。
回答by monitorjbl
I wrote a library to deal with a similar use case. I needed to programmatically ignore fields based on the user requesting data. The normal Hymanson options were just too heavy-handed, and I hated the way it made my code look.
我写了一个库来处理类似的用例。我需要根据用户请求数据以编程方式忽略字段。普通的 Hymanson 选项过于严厉,我讨厌它使我的代码看起来的方式。
The library makes this a whole lot easier to understand. It allows you to simply do this:
图书馆让这一切更容易理解。它允许您简单地执行以下操作:
import com.fasterxml.Hymanson.databind.ObjectMapper;
import com.fasterxml.Hymanson.databind.module.SimpleModule;
import com.monitorjbl.json.JsonView;
import com.monitorjbl.json.JsonViewSerializer;
import static com.monitorjbl.json.Match.match;
//initialize Hymanson
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);
//get a list of the objects
List<MyObject> list = myObjectService.list();
String json;
if(user.getRole().equals('ADMIN')){
json = mapper.writeValueAsString(list);
} else {
json = mapper.writeValueAsString(JsonView.with(list)
.onClass(MyObject.class, match()
.exclude("*")
.include("name")));
}
System.out.println(json);
The code is available on GitHub, hope it helps!
代码在 GitHub 上,希望对你有帮助!
回答by Prakash Angappan
If you have filters defined on two or more pojo, you can try this:
如果你在两个或多个 pojo 上定义了过滤器,你可以试试这个:
@JsonFilter("filterAClass")
class AClass
{
public String id = "42";
public String name = "Fred";
public String color = "blue";
public int sal = 56;
public BClass bclass = new BClass();
}
//@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonFilter("filterBClass")
class BClass
{
public String id = "99";
public String size = "90";
public String height = "tall";
public String nulcheck =null;
}
public class MultipleFilterConcept {
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
// Exclude Null Fields
mapper.setSerializationInclusion(Inclusion.NON_NULL);
String[] ignorableFieldNames = { "id", "color" };
String[] ignorableFieldNames1 = { "height","size" };
FilterProvider filters = new SimpleFilterProvider()
.addFilter("filterAClass",SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames))
.addFilter("filterBClass", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames1));
ObjectWriter writer = mapper.writer(filters);
System.out.println(writer.writeValueAsString(new AClass()));
}
}
回答by StaxMan
Hymanson relies on annotations for most things like this; but you do not have to directly annotate value classes. You can also use "mix-in annotations" (see http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html).
Hymanson 依赖注释来处理大多数这样的事情;但您不必直接注释值类。您还可以使用“混合注释”(参见http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html)。
And then there are a few options you can use beyond basic @JsonIgnore(per-property) or @JsonIgnoreProperties(per-class), see http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html
然后,除了基本@JsonIgnore(每个属性)或@JsonIgnoreProperties(每个类)之外,您还可以使用一些选项,请参阅http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html
回答by Ryan Bohn
I wrote a library called Squiggly Filter, which selects fields based on a subset of the Facebook Graph API syntax. For example, to select the zipCode of the address field of the user object, you would use the query string ?fields=address{zipCode}. One of the advantages of Squiggly Filter is that as long as you have access to the ObjectMapper that renders the json, you do not to have to modify the code of any of your controller methods.
我编写了一个名为Squiggly Filter的库,它根据 Facebook Graph API 语法的子集选择字段。例如,要选择用户对象的地址字段的邮政编码,您将使用查询字符串?fields=address{zipCode}。Squiggly Filter 的优点之一是,只要您可以访问呈现 json 的 ObjectMapper,您就不必修改任何控制器方法的代码。
Assuming, you are using the servlet API, you can do the following:
假设您正在使用 servlet API,您可以执行以下操作:
1) Register a filter
1) 注册过滤器
<filter>
<filter-name>squigglyFilter</filter-name>
<filter-class>com.github.bohnman.squiggly.web.SquigglyRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>squigglyFilter</filter-name>
<url-pattern>/**</url-pattern>
</filter-mapping>
2) Initialize the ObjectMapper
2)初始化ObjectMapper
Squiggly.init(objectMapper, new RequestSquigglyContextProvider());
3) You can now filter your json
3)你现在可以过滤你的json
curl https://yourhost/path/to/endpoint?fields=field1,field2{nested1,nested2}
More information on Squiggly Filter is available on github.
有关 Squiggly 过滤器的更多信息,请访问github。

