【问题标题】:how to wrap exception on jackson serialization如何在杰克逊序列化上包装异常
【发布时间】:2019-09-28 12:04:00
【问题描述】:

如果某个 getter 抛出异常,如何使用 Jackson 序列化对象?

例子:

public class Example {
     public String getSomeField() {
          //some logic which will throw in example NPE
          throw new NullPointerException();
     }
}

理想情况下,我想得到JSON

{"someField":"null"}

{"someField":"NPE"}

【问题讨论】:

  • 添加自定义序列化器。虽然如果你的吸气剂抛出异常,我会质疑你的代码的健全性......
  • 你想捕捉解析异常吗?使用 ObjectMapper 异常

标签: java json exception serialization jackson


【解决方案1】:

可能最通用的方法是实现自定义BeanPropertyWriter。您可以通过创建BeanSerializerModifier 类来注册它。下面的示例显示了如何做到这一点。

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;

import java.util.List;
import java.util.stream.Collectors;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        SimpleModule module = new SimpleModule();
        module.setSerializerModifier(new BeanSerializerModifier() {
            @Override
            public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
                if (beanDesc.getBeanClass() == Response.class) {
                    return beanProperties.stream()
                            .map(SilentExceptionBeanPropertyWriter::new)
                            .collect(Collectors.toList());

                }

                return super.changeProperties(config, beanDesc, beanProperties);
            }
        });

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(module);


        System.out.println(mapper.writeValueAsString(new Response(1, "ONE")));
        System.out.println(mapper.writeValueAsString(new Response(-1, "MINUS")));
        System.out.println(mapper.writeValueAsString(new Response(-1, null)));
    }
}

class SilentExceptionBeanPropertyWriter extends BeanPropertyWriter {

    public SilentExceptionBeanPropertyWriter(BeanPropertyWriter base) {
        super(base);
    }

    @Override
    public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {
        try {
            super.serializeAsField(bean, gen, prov);
        } catch (Exception e) {
            Throwable cause = e.getCause();
            gen.writeFieldName(_name);
            gen.writeString(cause.getClass().getName() + ":" + cause.getMessage());
        }
    }
}


class Response {

    private int count;
    private String message;

    public Response(int count, String message) {
        this.count = count;
        this.message = message;
    }

    public int getCount() {
        if (count < 0) {
            throw new IllegalStateException("Count is less than ZERO!");
        }
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getMessage() {
        if (message == null) {
            throw new NullPointerException("message can not be null!");
        }
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

以上示例打印:

{"count":1,"message":"ONE"}
{"count":"java.lang.IllegalStateException:Count is less than ZERO!","message":"MINUS"}
{"count":"java.lang.IllegalStateException:Count is less than ZERO!","message":"java.lang.NullPointerException:message can not be null!"}

【讨论】:

    猜你喜欢
    • 2012-11-07
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 2017-06-04
    相关资源
    最近更新 更多