как обернуть исключение при сериализации Джексона - PullRequest
1 голос
/ 28 сентября 2019

Как сериализовать объект с Jackson, если один из получателей выдает исключение?

Пример:

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

В идеале я хотел бы получить JSON:

{"someField":"null"}

или

{"someField":"NPE"}

1 Ответ

0 голосов
/ 28 сентября 2019

Вероятно, наиболее распространенным способом будет реализация пользовательских 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!"}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...