Jackson常用注解学习

读写注解

@JsonProperty(value = "***")

属性使用的注解,用来表示外部属性名字,就时使用别名序列化,而不是对象的属性名

public class Student {

    private int id;

    @JsonProperty("s_name")
    private String name;

    private int age;

    private boolean gender;
。。。
}

请求时使用:

{"id":12,"s_name":"zhangsan","age":11,"gender":true}

@JsonAutoDetect:实体类使用的注解,用于设置实体类属性的自动发现机制,发现的字段才能被序列和反序列;(自己的理解:对象的反序列化和setter方法,或者构造方法有关系,序列化和getter方法有关系)

默认情况下:先去查看被public修饰的字段,如果没有用public修饰,但拥有public修饰的getter、setter方法也能被发现;

自动检测,(作用在类上)来开启/禁止自动检测。

fieldVisibility:字段的可见级别   

ANY:任何级别的字段都可以自动识别  

NONE:所有字段都不可以自动识别   

NON_PRIVATE:非private修饰的字段可以自动识别  

PROTECTED_AND_PUBLIC:被protected和public修饰的字段可以被自动识别   

PUBLIC_ONLY:只有被public修饰的字段才可以被自动识别     

DEFAULT:可见的设置都会被发现,包括继承的属性;(自己测试好像都能检测到)

@Jsonignore

作用在字段或者方法上,在序列化和反序列化时,忽略一个字段;

@JsonIgnoreProperties

作用在类上,可以指定多个字段忽略

@JsonIgnoreType

作用在类上,忽略这个类,不会被序列化和反序列化

读注解

@JsonAnySetter(对应的写注解时@JsonAnyGetter)

用于接收实体类没有的属性,主要使用在set方法(set方法必须有两个参数)和属性上

public class Student {

    private int id;

    private String name;

    private int age;

    private boolean gender;
    @JsonAnySetter
    private Map<String,Object> properties = new HashMap<>();


    public Map<String, Object> getProperties() {
        return properties;
    }
    //@JsonAnySetter
    public void setProperties(String fieldName,Object value) {
        this.properties.put(fieldName,value);
    }
。。。
}

@JsonCreator

作用于方法,通常用来标注构造方法或静态工厂方法上,使用该方法来构建实例,默认的是使用无参的构造方法,通常是和@JsonProperty或@JacksonInject配合使用

public static class TestPOJO{
	private String name;
	private int age;

	@JsonCreator
	public TestPOJO(@JsonProperty("full_name") String name,@JsonProperty("age") int age){
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
}
--------------------------------------------------------------------------
public enum SessionInteractionType {


    GIFT,
  
    GAME,
   
    PROP;

    @JsonCreator
    public static SessionInteractionType forValue(int value) {
        return values()[value];
    }

    @JsonValue
    public int toValue() {
        return ordinal();
    }
}

@JacksonInject

作用于属性、方法、构造函数上,用来反序列化时标记已经被注入的属性,注入时需要手动注入的。

public class PersonInject {

    public long   id   = 0;
    public String name = null;

    @JacksonInject
    public String source = null;

}
InjectableValues inject = new InjectableValues.Std().addValue(String.class, "jenkov.com");
PersonInject personInject = new ObjectMapper().reader(inject)
                        .forType(PersonInject.class)
                        .readValue(new File("data/person.json"));

@JsonDeserialize(对应的写注解是@JsonSerialize)

作用于方法和字段上,通过Converter进行自定义的转化。Converter是jackson包中的一个接口,子接口有StdConverter;

public class CurrencyRate {
  private String pair;
  private double rate;
  @JsonSerialize(converter = LocalDateTimeToStringConverter.class)
  @JsonDeserialize(converter = StringToLocalDatetimeConverter.class)
  private LocalDateTime lastUpdated;
    .............
}
public class LocalDateTimeToStringConverter extends StdConverter<LocalDateTime, String> {
  static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);

  @Override
  public String convert(LocalDateTime value) {
      return value.format(DATE_FORMATTER);
  }
}

注:DateTimeFormatter是线程安全的;

public class StringToLocalDatetimeConverter extends StdConverter<String, LocalDateTime> {

  @Override
  public LocalDateTime convert(String value) {
      return LocalDateTime.parse(value, LocalDateTimeToStringConverter.DATE_FORMATTER);
  }
}

注:java8中时间的应用

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd kk:mm:ss");
        String format = dateTimeFormatter.format(now);
        System.out.println("format = " + format);
        String format1 = now.format(dateTimeFormatter);
        System.out.println("format1 = " + format1);
        格式化时上边两种方式效果一样
        String nowString = "2019-05-09 10:40:27";
        LocalDateTime.parse(nowString,dateTimeFormatter);
        解析时上边的方法返回的时LocalDateTime
        而dateTimeFormatter.parse方法的返回值类型是TemporalAccessor(此类型是一个接口)需要强转

写注解

@JsonInclud

可以过滤属性的值,null,empty不进行序列化

@JsonAnyGetter

@JsonPropertyOrder

作用在类上,被用来指明当序列化时需要对属性做排序

alphabetic属性,布尔类型,表示是否采用字母拼音顺序排序,默认是false,即不排序

@JsonRawValue

写入原始的值

例:字段 Sting content字段;接受一个json

使用

ObjectMapper.writeValueAsString();方法

当使用注解是content='{"author":"Peter", "content":"Test content"}'}

不使用注解的是

content":"{\"author\":\"Peter\", \"content\":\"Test content\"}"}

及序列化后的效果不一样;

@JsonValue

序列化时,调用方法序列化

@JsonSerialize

 

-------------------------------------------------------------------------------------------------------------------------------

常用的java序列化的注解

@Enumerated

属性value的值默认是:

EnumType.ORDINAL表示Emum的下表序列(从0开始)

可以修改为

EnumType.STRING表示Emum的对应的字符串

@Convert

用于数据库属性类型与java存储的类型做转换,例如枚举类型,在存储到数据库时或者在数据库取出来时,不用手动转换。

必须实现接口AttributeConverter<X,Y>

package javax.persistence;
 
public interface AttributeConverter<X,Y> {

	public Y convertToDatabaseColumn (X attribute);
 
	public X convertToEntityAttribute (Y dbData);
}

convertToDatabaseColumn(X attribute)用于把输入的类型转成数据库存储的类型

convertToEntityAttribute (Y dbData) 用于把数据库搜出来的类型转成实体中想要的类型

package com.xhx.springboot.enums;
 
public enum GenderEnum{
    MAN("1","男"),WOMAN("2","女");
    GenderEnum(String code,String value){
        this.code = code;
        this.value = value;
    }
    private String code;
    private String value;
    private String description;
 
    public String getCode() {
        return this.code;
    }
    public String getValue() {
        return this.value;
    }
    public String getDescription() {
        return this.description;
    }
 
}
package com.xhx.springboot.converters;
 
import com.xhx.springboot.enums.GenderEnum;
 
import javax.persistence.AttributeConverter;
import java.util.Arrays;
 
public class GenderEnumConverter implements AttributeConverter<GenderEnum,String> {
    @Override
    public String convertToDatabaseColumn(GenderEnum genderEnum) {
        return genderEnum.getCode();
    }
 
    @Override
    public GenderEnum convertToEntityAttribute(String s) {
        return Arrays.stream(GenderEnum.values()).filter(en -> en.getCode().equals(s)).findFirst().orElse(null);
    }
}
package com.xhx.springboot.entity;
 
import com.xhx.springboot.converters.GenderEnumConverter;
import com.xhx.springboot.enums.GenderEnum;
 
import javax.persistence.*;
 
/**
 * @author xuhaixing
 * @date 2018/4/28 10:29
 */
@Entity
@Table(name = "USER")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private int id;
    private String name;
    private int age;
    @Convert(
            converter = GenderEnumConverter.class
    )
    private GenderEnum gender;
    @Version
    private int version;
 。。。。。。
}

@Converter

用在AttributeConverter的实现类上

里面有autoApply属性

如果autoApply的属性是ture,则所有实体类的相关属性都会与本转化器关联;

如果autoApply的属性是false,则需要转换的属性必须添加@Convert注解与Converter进行关联

Jackson核心操作类ObjectMapper

线程安全的ObjectMapper

ObjectMapper类提供了很多方法操作JSON,这个类是线程安全的,推荐是用单例,注入方式,保证对象能够复用

还有其他类:JsonParser,JsonGenerator等,用这些类可以很容易的从String,File,Streams,URL等读取和写入JSON。

注意:在JSON序列化和反序列化的时候,会调用对象的getter/setter方法。所以需要在处理对象上要加上getter/setter,否则会出错。

Object对象转Json

方法:

  1. writeValue()
  2. writeValueAsBytes()
  3. writeValueAsString()
  4. .writeWithDefaultPrettyPrinter().writeValueAsString()  格式化输出

JSON转为Object

方法:

  • readValue(str,User.class)

用Reader反序列化Josn,转Object对象

jackson可以用抽象类ReaderBufferedReaderCharArrayReaderFilterReaderInputStreamReaderPipedReaderStringReader,反序列化Json数据

@Test
public void jsonToUserByReader() throws IOException {
  String str = "{\n"
    + "  \"id\" : 1,\n"
    + "  \"name\" : \"liuhailin\",\n"
    + "  \"createDate\" : 1509537316534,\n"
    + "  \"money\" : 100.001\n"
    + "}";

  Reader reader = new StringReader( str );
  User user = mapper.readValue( reader, User.class );
  System.out.println( user );
}

JSON转HashMap

@Test
public void jsonToUserMap() throws IOException {
  String str = "{\n"
    + "  \"id\" : 1,\n"
    + "  \"name\" : \"liuhailin\",\n"
    + "  \"createDate\" : 1509537316534,\n"
    + "  \"money\" : 100.001\n"
    + "}";

  HashMap userMap = mapper.readValue( str, HashMap.class );
  System.out.println( userMap.get( "id" ) );
  System.out.println( userMap.get( "name" ) );
  System.out.println( userMap.get( "createDate" ) );
  System.out.println( userMap.get( "money" ) );
}

从文件/流中读取 JSON

@Test
public void jsonToUserFromInputStreamReader() throws IOException {
  File userFile = new File( "user.json" );
  InputStream inputStream = new FileInputStream( userFile );
  InputStreamReader inputStreamReader = new InputStreamReader( inputStream, Charset.forName( "utf8" ) );
  User user = mapper.readValue( inputStreamReader, User.class );
  System.out.println( user );
}

InputStreamReader可以设定编码

@Test
public void jsonToUserFromByteArray() throws IOException {
  String str = "{\n"
    + "  \"id\" : 1,\n"
    + "  \"name\" : \"liuhailin\",\n"
    + "  \"createDate\" : 1509537316534,\n"
    + "  \"money\" : 100.001\n"
    + "}";
  byte[] array = str.getBytes();

  User user = mapper.readValue( array, User.class );
  System.out.println( user );
}

 

参考:牛人的博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值