如何从JSON字段名获取Java对象字段的名称

huangapple go评论76阅读模式
英文:

How to get Java's object field's name from JSON fields name

问题

以下是翻译好的内容:

我想要在响应中过滤掉一些字段。过滤操作应该在将 Java 对象序列化为 JSON 之前执行。
考虑以下情况:

public class Entity {

    @JsonProperty("some_property")
    String someProperty;

    @JsonProperty("nested_entity")
    @OneToMany(mappedBy = "entity", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    NestedEntity nestedEntity;

    // 其他字段,例如 fieldA,fieldB
}

API 端点:

get api/entity/{id}?fields=some_property,field_a

现在的要求是,在输出中,我们只应该过滤掉 someProperty 和 fieldA 这两个字段。就像这样:

{
    "some_property": "foo",
    "field_a": "bar"
}

但是,由于这些是 JSON 字段,而不是 Java 对象字段,我不能通过反射来进行过滤或获取这些字段。我们是否有办法实现这一点,即根据 JSON 字段来过滤 Java 对象?

附:在序列化之前进行过滤的优点是,除非需要这些字段,否则可以避免 lazy-fields 的数据库调用。

提前感谢您的帮助!

英文:

I want to filter out some fields in the response. Filtering should be done before the Java object is serialised into the JSON.
Consider:

public class Entity {

    @JsonProperty("some_property")
    String someProperty;

    @JsonProperty("nested_entity")
    @OneToMany(mappedBy = "entity", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    NestedEntity nestedEntity;

    // other fields for eg fieldA, fieldB
}

API endpoint

get api/entity/{id}?fields=some_property,field_a

Now the ask is, in the o/p we should filter out only someProperty and fieldA. Like

{
    "some_property": "foo",
    "field_a": "bar"
}

But since these are JSON fields not Java object fields I can't filter or get these fields them by Reflection. Is there a way we can achieve this, i.e. filtering of Java object based on json fields ?

FYI: The advantage of filtering before serialization is that the lazy-fields' DB calls are saved unless these fields are required

Thanks in advance!

答案1

得分: 1

关于使用`@JsonFilter`建议来支持空的`fields`或没有字段过滤的建议以及为了支持这一点添加了JacksonConfiguration

    @JsonFilter("entityFilter")
    public class Entity {

        @JsonProperty("some_property")
        String someProperty;
        // 其他字段,例如 fieldA,fieldB
    }
---

    @Configuration
    public class JacksonConfiguration { 
        public JacksonConfiguration(ObjectMapper objectMapper) {
            objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
        } 
    }
---

    public class FieldMapper {
        
        @SneakyThrows
        public static Dto getFilteredFields(Dto make, String fields[]) {
            ObjectMapper objectMapper = new ObjectMapper();
            if(ArrayUtils.isNotEmpty(fields)) {
                FilterProvider filters = new SimpleFilterProvider().addFilter(
                        "entityFilter", SimpleBeanPropertyFilter.filterOutAllExcept(fields)
                );
                objectMapper.setFilterProvider(filters);
            } else {
                objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
            }
            JsonNode j = objectMapper.readTree(objectMapper.writeValueAsString(make));
            return objectMapper.convertValue(j, Dto.class);
        }
    }

-----

    // 控制器代码用于获取带有字段dto的api/entity/{id}?fields=some_property,field_a
    Dto filteredFields = getFilteredFields(dto, fields);
    return filteredFields;
英文:

On the suggestion of @robocode using @JsonFilter and also to support empty fields or no fields filtering added JacksonConfiguration

@JsonFilter("entityFilter")
public class Entity {

    @JsonProperty("some_property")
    String someProperty;
    // other fields for eg fieldA, fieldB
}

@Configuration
public class JacksonConfiguration { 
    public JacksonConfiguration(ObjectMapper objectMapper) {
        objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
    } 
}

public class FieldMapper {
    
    @SneakyThrows
    public static Dto getFilteredFields(Dto make, String fields[]) {
        ObjectMapper objectMapper = new ObjectMapper();
        if(ArrayUtils.isNotEmpty(fields)) {
            FilterProvider filters = new SimpleFilterProvider().addFilter(
                    "entityFilter", SimpleBeanPropertyFilter.filterOutAllExcept(fields)
            );
            objectMapper.setFilterProvider(filters);
        } else {
            objectMapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false));
        }
        JsonNode j = objectMapper.readTree(objectMapper.writeValueAsString(make));
        return objectMapper.convertValue(j, Dto.class);
    }
}

// controller code to get the dto for api/entity/{id}?fields=some_property,field_a
Dto filteredFields = getFilteredFields(dto, fields);
return filteredFields

huangapple
  • 本文由 发表于 2020年10月16日 03:23:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/64378410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定