dubboJackson序列化统一配置

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.jaxrs.cfg.AnnotationBundleKey;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.fasterxml.jackson.jaxrs.json.JsonEndpointConfig;
import com.fasterxml.jackson.jaxrs.util.ClassKey;
import org.jboss.resteasy.annotations.providers.NoJackson;
import org.jboss.resteasy.annotations.providers.jackson.Formatted;
import org.jboss.resteasy.util.DelegatingOutputStream;
import org.jboss.resteasy.util.FindAnnotation;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Custom Jackson Provider which ignoring unknown properties,doing not write null value by default.
 *
 * @author 01375295
 */
@Provider
@Consumes({"application/*+json", "text/json"})
@Produces({"application/*+json", "text/json"})
public class CotpResteasyJackson2Provider extends JacksonJaxbJsonProvider {
    public CotpResteasyJackson2Provider() {
        super(getObjectMapper(), DEFAULT_ANNOTATIONS);
    }

    private static synchronized ObjectMapper getObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        /*
          该特性决定是否在writeValue()方法之后就调用JsonGenerator.flush()方法。
          当我们需要先压缩,然后再flush,则可能需要false。
           objectMapper.disable(SerializationFeature.FLUSH_AFTER_WRITE_VALUE);
         */

        //setting ignore unknown properties.
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        //setting do not write null value of object.
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.disable(SerializationFeature.WRITE_NULL_MAP_VALUES);
        objectMapper.setTimeZone(TimeZone.getDefault());
        return objectMapper;
    }


    @Override
    public boolean isReadable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
        if (FindAnnotation.findAnnotation(aClass, annotations, NoJackson.class) != null) {
            return false;
        }
        return super.isReadable(aClass, type, annotations, mediaType);
    }

    @Override
    public boolean isWriteable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
        if (FindAnnotation.findAnnotation(aClass, annotations, NoJackson.class) != null) {
            return false;
        }
        return super.isWriteable(aClass, type, annotations, mediaType);
    }

    // Currently we need to override readFrom and writeTo because Jackson 2.2.1 does not cache correctly
    // It does not allow to have a ContextResolver that chooses different mappers per Java type.

    private static class ClassAnnotationKey {
        private AnnotationBundleKey annotations;
        private ClassKey classKey;
        private int hash;

        private ClassAnnotationKey(Class<?> clazz, Annotation[] annotations) {
            this.annotations = new AnnotationBundleKey(annotations, AnnotationBundleKey.class);
            this.classKey = new ClassKey(clazz);
            this.hash = this.annotations.hashCode();
            this.hash = 31 * this.hash + this.classKey.hashCode();
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            } else if (o != null && this.getClass() == o.getClass()) {
                ClassAnnotationKey that = (ClassAnnotationKey) o;
                if (!this.annotations.equals(that.annotations)) {
                    return false;
                } else {
                    return this.classKey.equals(that.classKey);
                }
            } else {
                return false;
            }
        }

        @Override
        public int hashCode() {
            return this.hash;
        }
    }

    protected final ConcurrentHashMap<ClassAnnotationKey, JsonEndpointConfig> _readers
            = new ConcurrentHashMap<ClassAnnotationKey, JsonEndpointConfig>();

    @Override
    public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
            throws IOException {
        ClassAnnotationKey key = new ClassAnnotationKey(type, annotations);
        JsonEndpointConfig endpoint;
        endpoint = _readers.get(key);
        // not yet resolved (or not cached any more)? Resolve!
        if (endpoint == null) {
            ObjectMapper mapper = locateMapper(type, mediaType);
            endpoint = _configForReading(mapper, annotations, type);
            _readers.put(key, endpoint);
        }
        ObjectReader reader = endpoint.getReader();
        JsonParser jp = _createParser(reader, entityStream);
        // If null is returned, considered to be empty stream
        if (jp == null || jp.nextToken() == null) {
            return null;
        }
        // [Issue#1]: allow 'binding' to JsonParser
        if (((Class<?>) type) == JsonParser.class) {
            return jp;
        }
        return reader.withType(genericType).readValue(jp);
    }

    protected final ConcurrentHashMap<ClassAnnotationKey, JsonEndpointConfig> _writers
            = new ConcurrentHashMap<ClassAnnotationKey, JsonEndpointConfig>();

    @Override
    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
                        MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
            throws IOException {
        entityStream = new DelegatingOutputStream(entityStream) {
            @Override
            public void flush() throws IOException {
                // don't flush as this is a performance hit on Undertow.
                // and causes chunked encoding to happen.
            }
        };
        ClassAnnotationKey key = new ClassAnnotationKey(type, annotations);
        JsonEndpointConfig endpoint;
        endpoint = _writers.get(key);

        // not yet resolved (or not cached any more)? Resolve!
        if (endpoint == null) {
            ObjectMapper mapper = locateMapper(type, mediaType);
            endpoint = _configForWriting(mapper, annotations, type);

            // and cache for future reuse
            _writers.put(key, endpoint);
        }

        ObjectWriter writer = endpoint.getWriter();
        boolean withIndentOutput = false; // no way to replace _serializationConfig

        // we can't cache this.
        if (annotations != null) {
            for (Annotation annotation : annotations) {
                if (annotation.annotationType().equals(Formatted.class)) {
                    withIndentOutput = true;
                    break;
                }
            }
        }

        /* 27-Feb-2009, tatu: Where can we find desired encoding? Within
         *   HTTP headers?
         */
        JsonEncoding enc = findEncoding(mediaType, httpHeaders);
        JsonGenerator jg = writer.getFactory().createGenerator(entityStream, enc);

        try {
            // Want indentation?
            if (writer.isEnabled(SerializationFeature.INDENT_OUTPUT) || withIndentOutput) {
                jg.useDefaultPrettyPrinter();
            }
            // 04-Mar-2010, tatu: How about type we were given? (if any)
            JavaType rootType = null;

            if (genericType != null && value != null) {
                /* 10-Jan-2011, tatu: as per [JACKSON-456], it's not safe to just force root
                 *    type since it prevents polymorphic type serialization. Since we really
                 *    just need this for generics, let's only use generic type if it's truly
                 *    generic.
                 */
                if (genericType.getClass() != Class.class) { // generic types are other impls of 'java.lang.reflect.Type'
                    /* This is still not exactly right; should root type be further
                     * specialized with 'value.getClass()'? Let's see how well this works before
                     * trying to come up with more complete solution.
                     */
                    rootType = writer.getTypeFactory().constructType(genericType);
                    /* 26-Feb-2011, tatu: To help with [JACKSON-518], we better recognize cases where
                     *    type degenerates back into "Object.class" (as is the case with plain TypeVariable,
                     *    for example), and not use that.
                     */
                    if (rootType.getRawClass() == Object.class) {
                        rootType = null;
                    }
                }
            }

            // Most of the configuration now handled through EndpointConfig, ObjectWriter
            // but we may need to force root type:
            if (rootType != null) {
                writer = writer.withType(rootType);
            }
            value = endpoint.modifyBeforeWrite(value);
            writer.writeValue(jg, value);
        } finally {
            jg.close();
        }
    }


}

1、在service中加入以上类;

2、在service的META-INF下创建services文件夹

3、在services文件夹下创建javax.ws.rs.ext.Providers文件

4、javax.ws.rs.ext.Providers中写入上述类的引用

引用的依赖:

<!-- 使用json序列化 -->
    <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-jackson2-provider</artifactId>
      <version>3.0.17.Final</version>
    </dependency>

 <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.0</version>
        </dependency>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值