java - Java 反射访问公共字段
问题描述
我正在为 List 类编写一个自定义序列化程序(Jackson JSON),这个列表可以用不同的类类型推断出来,所以我需要使用反射来获取对象字段值。
注意,所有这些类都有公共值(没有 setter 和 getter),所以调用 getter 不是一个选项。
这是我到目前为止得到的:
package com.xxx.commons.my.serializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.apache.commons.lang3.reflect.FieldUtils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.List;
public class ListSerializer extends StdSerializer<List> {
public ListSerializer() {
super(List.class);
}
@Override
public void serialize(List aList, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (aList != null) {
jsonGenerator.writeStartObject();
for (int index = 0 ; index < aList.size(); index++) {
try {
Object next = aList.get(index);
List<Field> fields = FieldUtils.getAllFieldsList(next.getClass());
Object object = next.getClass().newInstance();
for (int j = 0 ; j < fields.size(); j ++ ) {
jsonGenerator.writeObjectField(String.format("%s[%s]",fields.get(j).getName(),index) , object);
}
} catch (Exception e) {
e.printStackTrace();
}
}
jsonGenerator.writeEndObject();
}
}
}
我的测试
package com.xxx.commons.my.serializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Test;
public class ListSerializerTest {
private ObjectMapper mapper = new ObjectMapper();
@Test
public void test() throws Exception {
SimpleModule module = new SimpleModule();
module.addSerializer(new ListSerializer());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.registerModule(module);
MyTempClassParent parent = new MyTempClassParent();
parent.mylist.add(new MyTempClass("1","2","3"));
String json = mapper.writeValueAsString(parent);
System.out.println(json);
}
}
示例类:
public class MyTempClass {
public MyTempClass() {
}
public MyTempClass(String value1, String value2, String value3) {
this.valueA = value1;
this.valueB = value2;
this.valueC = value3;
}
public String valueA;
public String valueB;
public String valueC;
}
public class MyTempClassParent {
public List<MyTempClass> mylist = new LinkedList<>();
}
写这个的任何想法或替代方案?
解决方案
也许您应该只使用 ObjectMapper 和设置属性访问器来访问每个字段:
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
MyDtoAccessLevel dtoObject = new MyDtoAccessLevel();
String dtoAsString = mapper.writeValueAsString(Arrays.asList(dtoObject));
System.out.println(dtoAsString);
结果:[{"stringValue":null,"intValue":0,"floatValue":0.0,"booleanValue":false}] dto:
class MyDtoAccessLevel {
private String stringValue;
int intValue;
protected float floatValue;
public boolean booleanValue;
// NO setters or getters
--edit 通过反射从对象中获取值:
@Override
public void serialize(List aList, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (aList != null) {
jsonGenerator.writeStartObject();
for (int index = 0 ; index < aList.size(); index++) {
try {
Object next = aList.get(index);
List<Field> fields = FieldUtils.getAllFieldsList(next.getClass());
for (int j = 0 ; j < fields.size(); j ++ ) {
jsonGenerator.writeObjectField(String.format("%s[%s]",fields.get(j).getName(),index) , fields.get(j).get(next));
}
} catch (Exception e) {
e.printStackTrace();
}
}
jsonGenerator.writeEndObject();
}
}
请写出问题,你想在输出中有什么。
推荐阅读
- django - 在生产 Django 部署中添加不可为空的字段
- javascript - 将 DIV 分配给 php 变量并在多个隐藏输入上循环
- javascript - 打开 mdDialog 时,它会向下滚动对话框而不是在顶部显示部分
- python - ValueError:无法为具有形状“(?,1)”的张量“TargetsData / Y:0”提供形状(10,)的值
- python - 如何在 Python 3.5 的 zip 存档中存储一个大的 numpy 数组?
- c# - ASPNET Core HttpPost [FromBody] 参数始终为空
- java - 计算 CountDownTimer 在 java 中启动后使用的时间?
- c# - MailKit:邮件客户端显示在移动时收到的消息并且不保留原始标志
- vba - 文件未保存到 VBA 中新建的文件夹中
- node.js - npm audit 卡在 ENOAUDIT 上