简体   繁体   English

Java Reflection为Java Pojo设置Value

[英]Java Reflection to set Value for the java pojo

Goal : 目标:

set value for the given java bean at run time and generate JSON Object or JSON array.

the above is my goal and i have tried some thing like the below : 以上是我的目标,我已经尝试过以下操作:

package com.hexgen.tools;

import java.lang.reflect.Method;

import com.google.gson.Gson;

public class ConvertPOJOToJSON {
    public Object creatJSONObject(String className) throws IllegalArgumentException, IllegalAccessException, InstantiationException, Exception {
        Class<?> objectClass = null;
        Object clsObject =null;
        try {
            objectClass = Class.forName(className);
            clsObject = objectClass.newInstance();
             for(Method m : objectClass.getMethods())
                  if (m.getName().startsWith("set") && m.getParameterTypes().length == 1 && m.getModifiers()==23)
                     m.invoke(clsObject, "myValue");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return clsObject;
    }
public static void main(String[] args) {
    Gson gson = new Gson();
    ConvertPOJOToJSON pojoToJSON = new ConvertPOJOToJSON();
    try {
        System.out.println("JSON OBJECT : "+gson.toJson(pojoToJSON.creatJSONObject("com.hexgen.ro.request.CreateRequisitionRO")));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

The Output of the above class : 以上类的输出:

JSON OBJECT : {"isAllocable":false}

there are many fields in the class i gave com.hexgen.ro.request.CreateRequisitionRO but only one boolean value is set to false and returns the value. 我给com.hexgen.ro.request.CreateRequisitionRO的类中有很多字段,但是只有一个布尔值设置为false并返回该值。

i have some constant value to set for the fields say if the field type is Integer than set some default integer value like so

EDIT : 编辑:

I have created a enum like the following : 我创建了一个如下的枚举:

package com.hexgen.tools; 包com.hexgen.tools;

import java.math.BigDecimal; 导入java.math.BigDecimal; import java.math.BigInteger; 导入java.math.BigInteger; import org.joda.time.LocalDate; 导入org.joda.time.LocalDate;

public enum DefaultParamValues {
    STRING("HEXGEN"),
    INTEGER(123),
    DATE(new LocalDate()),
    BOOLEAN(true),
    LONGVALUE(123123),
    BIGDECIMAL(new BigDecimal("100000"));

    private  String defaultString;
    private  int defaultInteger;
    private  LocalDate defaultDate;
    private  boolean defaultBoolean;
    private  long defaultLong;
    private  BigDecimal defaultBigDecimal;

    private DefaultParamValues(String strDefaultValue) {
        defaultString = strDefaultValue;
    }
    private DefaultParamValues(int intDefaultValue) {
        defaultInteger = intDefaultValue;
    }
    private DefaultParamValues(LocalDate dateDefaultValue) {
        defaultDate = dateDefaultValue;
    }
    private DefaultParamValues(boolean booleanDefaultValue) {
        defaultBoolean = booleanDefaultValue;
    }
    private DefaultParamValues(long longDefaultValue) {
        defaultLong = longDefaultValue;
    }
    private DefaultParamValues(BigDecimal bigIntegerDefaultValue) {
        defaultBigDecimal = bigIntegerDefaultValue;
    }
    public String getDefaultString() {
        return defaultString;
    }
    public int getDefaultInt() {
        return defaultInteger;
    }
    public LocalDate getDefaultDate() {
        return defaultDate;
    }

    public boolean getDefaultBoolean() {
        return defaultBoolean;
    }
    public long getDefaultLong() {
        return defaultLong;
    }
    public BigDecimal getDdefaultBigDecimal() {
        return defaultBigDecimal;
    }

}

created one more method like the following : 还创建了如下另一种方法:

public Object creatObjectWithDefaultValue(String className) throws IllegalArgumentException, IllegalAccessException, InstantiationException {
        DefaultParamValues defaultParamValues = null;
        Class<?> objectClass = null;
        Object clsObject =null;
        try {
            objectClass = Class.forName(className);
            clsObject = objectClass.newInstance();
             Field[] fields = objectClass.getDeclaredFields();

             for(Field f:fields){
                  if(!f.isAccessible()){
                        f.setAccessible(true);
                        Class<?> type = f.getType();
                        if(! Modifier.isFinal(f.getModifiers()) && type.equals(Integer.class)){
                            f.set(clsObject, defaultParamValues.INTEGER);  
                        } else if( !Modifier.isFinal(f.getModifiers()) && type.equals(java.math.BigDecimal.class)){
                            f.set(clsObject, defaultParamValues.BIGDECIMAL);  
                        } else if(! Modifier.isFinal(f.getModifiers()) && type.equals(org.joda.time.LocalDate.class)){
                            f.set(clsObject,defaultParamValues.DATE);  
                        }  else if(! Modifier.isFinal(f.getModifiers()) && type.equals(boolean.class)){
                            f.set(clsObject, defaultParamValues.BOOLEAN);  
                        } else if(! Modifier.isFinal(f.getModifiers()) && type.equals(java.lang.String.class)){
                            f.set(clsObject, defaultParamValues.STRING);  
                        }
                        else if(! Modifier.isFinal(f.getModifiers()) && type.equals(long.class)){
                            f.set(clsObject, defaultParamValues.LONGVALUE);  

                        }
                       //f.setAccessible(false);
                     }

               }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return clsObject;
    }

to set the default values but i get the following exception: 设置默认值,但我得到以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.math.BigDecimal field com.hexgen.ro.request.CreateRequisitionRO.transSrlNo to com.hexgen.tools.DefaultParamValues
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
    at java.lang.reflect.Field.set(Field.java:657)
    at com.hexgen.tools.JsonConverter.creatObjectWithDefaultValue(JsonConverter.java:93)
    at com.hexgen.tools.JsonConverter.main(JsonConverter.java:201)

Please help me to find the solution. 请帮助我找到解决方案。

Best Regards 最好的祝福

If your looking for a lightweight library which can do this and more including allowing you to do your own filtering to find Methods/Fields. 如果您正在寻找一个轻量级的库,它可以做到这一点以及更多,包括允许您进行自己的过滤以查找“方法/字段”。 I wrote an open source library which has no 3rd party dependencies and is available on Maven Central. 我写了一个没有第三方依赖的开源库,可以在Maven Central上使用。

Checkout https://github.com/gondor/reflect 结帐https://github.com/gondor/reflect

As for your issue it appears your setting the "Enum" constant and not the inner value of the enum. 对于您的问题,您似乎在设置“ Enum”常量,而不是枚举的内部值。 Wouldn't it DefaultParamValues.BIGDECIMAL.getDdefaultBigDecimal() 它不是DefaultParamValues.BIGDECIMAL.getDdefaultBigDecimal()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM