美文网首页程序员java进阶干货Java 杂谈
jackson常用注解和spring中的配置

jackson常用注解和spring中的配置

作者: 江江的大猪 | 来源:发表于2017-12-01 15:14 被阅读1502次

    spring默认使用的是jackson处理json的序列化和反序列化,有一些细节和小坑,基于spring4和jackson2.8做一些说明

    @JsonIgnore

    @JsonIgnore是jackson的注解,jackson1版本和2版本没有区别,通常当做标志注解(没有要赋值的属性),常用于属性上

    json序列化反序列化都会忽略该属性


    @JsonIgnoreProperties

    @JsonIgnoreProperties是Jackson的注解,jackson1版本和2版本有区别,1版本只能放在类上,2版本类、方法、属性都可以,为了保持习惯,一般还是都放在类上

    • ignoreUnknown属性,默认为false,此时反序列化json字符串时,有bean中没有的字段,就会抛出异常
    • value属性,默认为空,可以放入要忽略的字段,作用和@JsonIgnore一样,可以统一管理忽略字段
    • demo:@JsonIgnoreProperties(ignoreUnknown = true, value = {"id","name"})

    @JsonProperty

    @ JsonProperty是Jackson的注解,jackson1版本和2版本区别很大,常用于属性上

    • value属性,1、2版本一样,默认为"",代表该属性序列化和反序列化时的key值
    • required属性,2.0版本新增属性,默认false,2.6版本之后只能用于@JsonCreator中。例子中required=true,当反序列化时,json串中没有x或y,就会报错。不实用,一般不用该属性
    /**
     * Note that as of 2.6, this property is only used for Creator
     * Properties, to ensure existence of property value in JSON:
     * for other properties (ones injected using a setter or mutable
     * field), no validation is performed. Support for those cases
     * may be added in future.
     * State of this property is exposed via introspection, and its
     * value is typically used by Schema generators, such as one for
     * JSON Schema.
     */
    public class MyClass {
        @JsonCreator
        public MyClass(@JsonProperty(value = "x", required = true) Integer x, @JsonProperty(value = "value_y", required = true) Integer y) {
            this.x = x;
            this.y = y;
        }
        private Integer x;
        private Integer y;
    }
    
    • defaultValue属性,2.5版本新增属性,jackson2.8该属性依然没有作用
    /**
     * It is possible that in future this annotation could be used for value
     * defaulting, and especially for default values of Creator properties,
     * since they support {@link #required()} in 2.6 and above.
     * /
    
    • access属性,2.6版本新增属性,默认Access.AUTO(不控制序列化反序列化权限),此外还有READ_ONLY(仅可以序列化)、WRITE_ONLY(仅可以反序列化)、READ_WRITE(序列化反序列化都可以),一共四种。分别控制序列化反序列化的权限,所以JsonProperty注解使用该属性可以取代JsonIgnore注解,控制的更加精细。

    PS:access的源码注释中说明JsonIgnore优先于access属性,但是我在测试的时候,对同一个属性同时使用这两个注解,则两个注解都失效了,不知道为什么?????

    /**源码中的注释
     * Note that while this annotation modifies access to annotated property,
     * its effects may be further overridden by {@link JsonIgnore} property:
     * if both annotations are present on an accessors, {@link JsonIgnore}
     * has precedence over this property.
     */
    @Test
    public void testSerial() throws JsonProcessingException {
        JsonBean jsonBean = new JsonBean();
        jsonBean.setAaa("aaa");
        jsonBean.setBbb("bbb");
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(jsonBean));
    }
    @Test
    public void testDeserial() throws IOException {
        String json = "{\"aaa\":\"aaa\",\"bbb\":\"bbb\"}";
        ObjectMapper mapper = new ObjectMapper();
        JsonBean jsonBean = mapper.readValue(json, JsonBean.class);
        System.out.println(jsonBean);
    }
    @Data //lombok插件注解,自动生成set、get、toString等方法
    class JsonBean {
        @JsonProperty(access = JsonProperty.Access.READ_ONLY)
        @JsonIgnore
        private String aaa;
        private String bbb;
    }
    

    对序列化反序列化的控制总结:

    1. JsonIgnoreProperties放到类上,集中管理属性参不参与json转换
    2. JsonIgnore放到类的属性上,控制该属性参不参与json转换,文档中说放到set方法或者get方法上表现不一样,但是我测试的时候,放到get、set、属性上表现的都一样,都是不参加json的序列化反序列化
    3. JsonProperty放到类的属性上,通过access可以分开控制该属性参不参与json的序列化或反序列化

    Spring中对jackson的配置

    Spring中使用@ResponseBody和@RequestBody都会在converter中用到jackson,所以需要配置converter中使用的jackson

    <mvc:annotation-driven>
        <mvc:message-converters>
            1:<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                        <property name="targetObject">
                            <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                                <property name="serializationInclusion" value="NON_NULL"/>
                            </bean>
                        </property>
                        <property name="targetMethod" value="configure"/>
                        <property name="arguments">
                            <list>
                                <value>FAIL_ON_UNKNOWN_PROPERTIES</value>
                                <value>false</value>
                            </list>
                        </property>
                    </bean>
                </property>
            </bean>
            2:<bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    
    1. 该bean用来处理@ResponseBody和@RequestBody的json转换,通过Spring的MethodInvokingFactoryBean来生成ObjectMapper实例,该bean的配置相当于: new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 设置DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false之后,bean中就无需使用@JsonIgnoreProperties(ignoreUnknown = true)
    2. 该bean用来处理使用@ResponseBody的Controller返回String,默认情况使用的时iso8859-1的编码,需要改成UTF-8
    肥肥小浣熊

    相关文章

      网友评论

        本文标题:jackson常用注解和spring中的配置

        本文链接:https://www.haomeiwen.com/subject/wrlwbxtx.html