读写注解
@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
方法:
- writeValue()
- writeValueAsBytes()
- writeValueAsString()
- .writeWithDefaultPrettyPrinter().writeValueAsString() 格式化输出
JSON转为Object
方法:
- readValue(str,User.class)
用Reader反序列化Josn,转Object对象
jackson可以用抽象类Reader类BufferedReader,CharArrayReader,FilterReader,InputStreamReader,PipedReader,StringReader,反序列化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 );
}
参考:牛人的博客