Java - 如何处理大型可空字段集的NullPointerException?

时间:2016-01-11 15:37:27

标签: java json soap

假设我有10个独特的POJO,每个POJO有10个唯一命名的字段。

此POJO是反序列化的SOAP响应。我想将SOAP POJO中的字段“复制”到表示JSON对象的POJO,然后序列化该POJO。

让我们将SOAP对象命名为o0 ... o9
让我们将SOAP字段命名为f0 ... f9

让我们命名我们的JSON对象jo
让我们将我们的JSON字段命名为f0 ... f99

最后,所有字段都是值的容器,因此每个字段都有一个.getValue()方法。

假设我们所有的字段都有getter和setter,根据我的理解,执行此操作的唯一方法是硬编码以下内容:

jo.setF0(o0.getF0().getValue());
jo.setF1(o0.getF1().getValue());
...
jo.setF49(o4.getF9().getValue());
...
jo.setF99(o9.getF9().getValue());

现在,问题是属于o0 ... o9的任何字段都可能为null,这将导致NullPointerException。

有没有办法在不编写100个try / catch块的情况下解决这个问题?

2 个答案:

答案 0 :(得分:0)

也许你可以阻止nullPointer,测试对象在设置值之前是否为null。

o0.getF0!=null ? o0.getF0().getValue(): null;

看一下像https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/BeanUtils.html这样的框架来复制属性。

答案 1 :(得分:0)

这是一个简单的e bean值复制器实现,它复制源和目标中都存在的所有非null属性:

public class BeanValueCopier {

    static final Map<Class<?>, Map<String, PropertyDescriptor>> beanPropertiesByType = new ConcurrentHashMap<>();

    public static void copyNonNullValues(Object src, Object dest) {
        try {
            Map<String, PropertyDescriptor> sourceMap = propertyMap(src.getClass());
            Map<String, PropertyDescriptor> targetMap = propertyMap(dest.getClass());
            for (Map.Entry<String, PropertyDescriptor> entry : sourceMap.entrySet()) {
                final String propertyName = entry.getKey();
                if (targetMap.containsKey(propertyName)) {
                    final PropertyDescriptor sourceDesc = entry.getValue();
                    final PropertyDescriptor targetDesc = targetMap.get(propertyName);
                    if (targetDesc.getPropertyType().equals(sourceDesc.getPropertyType()) && sourceDesc.getReadMethod() != null && targetDesc.getWriteMethod() != null) {
                        final Object value = sourceDesc.getReadMethod().invoke(src);
                        if (value != null) targetDesc.getWriteMethod().invoke(dest, value);
                    }
                }
            }
        } catch (InvocationTargetException | IllegalAccessException | IntrospectionException e) {
            throw new IllegalStateException(e);
        }
    }

    private static Map<String, PropertyDescriptor> propertyMap(Class<?> beanClass) throws IntrospectionException {
        Map<String, PropertyDescriptor> beanProperties = beanPropertiesByType.get(beanClass);
        if (beanProperties == null) {
            beanProperties = new HashMap<>();
            for (PropertyDescriptor propertyDescriptor : Introspector.getBeanInfo(beanClass, Object.class).getPropertyDescriptors()) {
                beanProperties.put(propertyDescriptor.getName(), propertyDescriptor);
            }

            beanPropertiesByType.put(beanClass, beanProperties);
        }
        return beanProperties;
    }
}

显然,这仍然存在很多问题:并发,原始类型的处理,异常处理等,但它应该让你开始

这使用JavaBeans Introspector机制