簡體   English   中英

Java Reflection訪問公共字段

[英]Java Reflection accessing public fields

我正在為List類編寫一個自定義的Serializer(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();
    }
}
}

MyTest的

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();
    }
}

請寫下問題,你想在輸出中有什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM