jackson常用注解和spring中的配置

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
肥肥小浣熊