【问题标题】:@jsonview fail on unknown properties@jsonview 在未知属性上失败
【发布时间】:2016-07-15 18:22:32
【问题描述】:

我需要使用@JsonView 在反序列化时抛出异常。

我的 POJO:

public class Contact
{
    @JsonView( ContactViews.Person.class )
    private String personName;

    @JsonView( ContactViews.Company.class )
    private String companyName;
}

我的服务:

public static Contact createPerson(String json) {

    ObjectMapper mapper = new ObjectMapper().configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , true );

    Contact person = mapper.readerWithView( ContactViews.Person.class ).forType( Contact.class ).readValue( json );

    return person;
}


public static Contact createCompany(String json) {

    ObjectMapper mapper = new ObjectMapper().configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , true );

    Contact company = mapper.readerWithView( ContactViews.Company.class ).forType( Contact.class ).readValue( json );

    return company;
}

我需要实现的是,如果我想创建一个 Person,我只需要传递“personName”。如果我通过'companyName',我需要抛出异常。如何使用@JsonView 实现这一目标?有没有其他选择?

【问题讨论】:

  • 你可以尝试创建2个类CompanyContact extends ContactPersonContact extends Contact
  • @varren - 你的意思是 'CompanyContact' 和 'PersonContact' 的 2 个新类?
  • 是的,如果你有这样的选项,它将有助于分离逻辑
  • @varren - 我目前只有这种结构。我面临的问题是我将有很多视图——比如具有不同值集的人、公司、用户等。我必须以这种方式创建很多类。我想知道是否可以使用 JsonView 避免它

标签: java spring jackson objectmapper


【解决方案1】:

我认为@JsonView 不足以为您解决这个问题。这里有更多信息为什么:UnrecognizedPropertyException is not thrown when deserializing properties that are not part of the view

但我只是查看了源代码,并通过@JsonView 和自定义BeanDeserializerModifier 的组合设法“破解”了这个问题。它不漂亮,但这是必不可少的部分:

public static class MyBeanDeserializerModifier extends BeanDeserializerModifier {

    @Override
    public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, 
                     BeanDescription beanDesc, BeanDeserializerBuilder builder) {
        if (beanDesc.getBeanClass() != Contact.class) {
            return builder;
        }

        List<PropertyName> properties = new ArrayList<>();
        Iterator<SettableBeanProperty> beanPropertyIterator = builder.getProperties();
        Class<?> activeView = config.getActiveView();


        while (beanPropertyIterator.hasNext()) {
            SettableBeanProperty settableBeanProperty = beanPropertyIterator.next();
            if (!settableBeanProperty.visibleInView(activeView)) {
                properties.add(settableBeanProperty.getFullName());
            }
        }

        for(PropertyName p : properties){
            builder.removeProperty(p);
        }

        return builder;
    }
}

这是在对象映射器上注册它的方法:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new MyBeanDeserializerModifier());
mapper.registerModule(module);

这对我有用,我现在得到 UnrecognizedPropertyException:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "companyName" (class Main2$Contact), not marked as ignorable (one known property: "personName"])

【讨论】:

  • 非常感谢!!!你为我节省了数小时挖掘大量帖子的时间。有效!再次感谢!!
猜你喜欢
  • 2018-03-01
  • 1970-01-01
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
相关资源
最近更新 更多