本文目录一览:
Java的json反序列化:Java数据类可以和json数据结构不一致吗?
由于时间关系我也没有写全,这里提供一个思路吧。代码如下:
Account.java:
@Data
public class Account {
private int id;
private String name;
// @PowerfulAnnotation注解是我臆想的
@PowerfulAnnotation("token.id")
private String tokenId;
@PowerfulAnnotation("token.key")
private String key;
}
PowerfulAnnotation.java:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PowerfulAnnotation {
String value() default "";
}
测试类Main.java:
public class Main {
public static void main(String[] args) throws Exception {
Account account = new Account();
String ori = "{\n" +
"\"id\": 11111,\n" +
"\"name\": \"小李\",\n" +
"\"token\": {\n" +
"\"id\": 22222222,\n" +
"\"key\": \"ddddddddd\"\n" +
"}\n" +
"}";
Gson gson = new Gson();
//字符串json转JsonObject
JsonObject jsonObject = gson.fromJson(ori, JsonObject.class);
//反射获取目标对象属性
for (Field field : account.getClass().getDeclaredFields()) {
String fieldName = field.getName();
Class fieldClass = field.getType();
System.out.print("当前field名:[" + fieldName + "],");
System.out.println("当前field类型:[" + fieldClass + "]");
Annotation annotation = field.getDeclaredAnnotation(PowerfulAnnotation.class);
//检查是否有PowerfulAnnotation注解
if (annotation != null) {
PowerfulAnnotation powerful = (PowerfulAnnotation) annotation;
String powerfulValue = powerful.value();
System.out.println("发现PowerfulAnnotation注解,值为:[" + powerfulValue + "]");
String[] tmp = powerfulValue.split("\\.");
//声明一个临时JsonObject,将用于获取下一层json对象
JsonObject tmpJson = jsonObject;
for (int i = 0; i tmp.length; i++) {
//目标值是在powerfulValue的最后一个字段,例如powerfulValue为token.id的话,目标的值就是id,所以先获取token这个jsonObject,并赋值给临时tmpJson
if (i != tmp.length - 1) {
tmpJson = jsonObject.get(tmp[i]).getAsJsonObject();
} else {
//到达powerfulValue的最后一个字段,检查其类型,并赋值给目标对象
Object value = checkFieldType(tmpJson, tmp[i], fieldClass);
//从目标对象中获取目标属性
Field targetField = account.getClass().getDeclaredField(field.getName());
targetField.setAccessible(true);//解除私有限制
System.out.println("将[" + powerfulValue + "]的值[" + value + "]赋给目标对象的[" + fieldName + "]");
//将值赋值给目标属性
targetField.set(account, value);
}
}
}
//属性上没有PowerfulAnnotation注解
else {
//检查当前属性的类型
Object value = checkFieldType(jsonObject, fieldName, fieldClass);
//从目标对象中获取目标属性
Field targetField = account.getClass().getDeclaredField(field.getName());
targetField.setAccessible(true);//解除私有限制
System.out.println("直接将值[" + value + "]赋给目标对象的[" + fieldName + "]");
//将值赋值给目标属性
targetField.set(account, value);
}
System.out.println("*********************************************\n");
}
System.out.println("目标对象最终值:" + account);
}
/**
* 检查当前属性的类型
* (这里由于时间关系,我没有写全,只检查了String、int、boolean类型,全类型应包括boolean、char、byte、short、int、long、float、double,你有时间自己补充一下)
*
* 如果发现当前属性是一个对象,那么应该将JsonObject转换成对应的对象再返回(由于时间关系,这里我也没有试过,总之思路是这样)
*/
private static Object checkFieldType(JsonObject field, String fieldName, Class fieldClass) {
if (fieldClass == String.class) {
return field.get(fieldName).getAsString();
}
if (fieldClass == int.class) {
return field.get(fieldName).getAsInt();
}
if (fieldClass == boolean.class) {
return field.get(fieldName).getAsBoolean();
}
return new Gson().fromJson(field.get(fieldName), fieldClass);
}
}
代码还没写完,主要集中在没有对JsonArray进行处理,当json串里包含数组时会报错,另外一些没写完的我在注释里写了点,你可以参照一下。整体思路还是利用java反射机制进行。
以上代码运行结果:
在JAVA中什么叫序列化和反序列化?
java对象实现了序列化就可以以对象的形式在流中传输。不管是文件流,还是Socket流都可以\x0d\x0a 用ObjectInputStream ObjectOutputStream 来读写对象。\x0d\x0a 并不是所以类都可以序列化,一般需要序列化的对象是那些实体类。什么Bean,pojo,vo貌似都是一个意思吧。。。还是有一些对象是不能序列化的,Socket对象是不能的。还有一些忘记了,还有一些不知道···呵呵~~\x0d\x0a 实现序列化只要实现一个Serializable的接口就行,这是个标志接口,里面没有方法需要实现,主要的作用就是标识这儿类可以序列化·····
求教:java序列化和反序列化
概念:Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。
如何实现Java序列化与反序列化?
1)JDK类库中序列化API
java.io.ObjectOutputStream:表示对象输出流
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream:表示对象输入流
它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回。
2)实现序列化的要求
只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常。
3)实现Java对象序列化与反序列化的方法
假定一个Student类,它的对象需要序列化,可以有如下三种方法:
方法一:若Student类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化
ObjectOutputStream采用默认的序列化方式,对Student对象的非transient的实例变量进行序列化。
ObjcetInputStream采用默认的反序列化方式,对对Student对象的非transient的实例变量进行反序列化。
方法二:若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。
ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。
方法三:若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。
ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。