2

I'm using Reflection to read properties and their values of a class. There are Strings, Booleans and properties of a class type. How to get the value of the class type.

User.java

private String firstName;
private String lastName;
private SupportLangauge flang;
private SupportLangauge mlang;

SupportLanguage.java

private String languageCode;
private Boolean flang;
private Boolean mlang;

I am able to save the data of flang, mlang using reflection, but unable to read value. When I do read, the object is being returned. See sample below.

Result:

       "flang": "com.sample.entity.user.SupportLanguage@3080037d
          [\r\n     languageCode=EN_US\r\n]",
       "mlang": "com.sample.entity.user.SupportLanguage@3080037d
          [\r\n  languageCode=EN_US\r\n]",

My code below for saving the language types.

SavingUser.java

for (User user : CollectionsUtilService.nullGuard(userList)) {
 PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(
   user.getClass()).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (fieldValueMap.containsKey(propertyDescriptor.getName())) {
if   (propertyDescriptor.getPropertyType().getName().
 equalsIgnoreCase("com.sample.entity.user.SupportLanguage")) {
                    String langString =   fieldValueMap.
             get(propertyDescriptor.getName());
             SupportLanguage s = new SupportLanguage();
                    s.setLanguageCode(langString);
                    propertyDescriptor.getWriteMethod().invoke(user, s);
                }                   

            }
        }
    }

My Code for Reading the value;

RenderingUser.java

               if (propertyDescriptor.getPropertyType().
                 getName().equalsIgnoreCase
               ("com.sample.entity.
                  user.SupportLanguage")) {
                  Method m = propertyDescriptor.getReadMethod();
                  SupportLanguage s = new SupportLanguage();
                  System.out.println("m.invoke(SupportLanguage) " 
                  +  m.invoke(s));  
DevOps Junky
  • 287
  • 1
  • 5
  • 22
  • You get the output `com.sample.entity.user.SupportLanguage@3080037d` because class `SupportLanguage` doesn't override the `toString()` method; see [How do I print my Java object without getting “SomeType@2f92e0f4”?](http://stackoverflow.com/questions/29140402/how-do-i-print-my-java-object-without-getting-sometype2f92e0f4) – Jesper Jun 22 '15 at 07:50

3 Answers3

1

if you implement the Java Bean standard (i.e. have getter methods with proper names) then I recommend the Apache BeanUtils package.

The PropertyUtils.getSimpleProperty(Object, String) will get you the property you need and there is also an easy way to get nested properties

lastly, you have one neat method that gives oyu ALL properties that have getters into a map

Sharon Ben Asher
  • 13,849
  • 5
  • 33
  • 47
0

Your reading is almost correct. But you must use the root object (User) not the property object.

User user = ...; // Initialized user object
           if (propertyDescriptor.getPropertyType().
             getName().equalsIgnoreCase
           ("com.sample.entity.
              user.SupportLanguage")) {
              Method m = propertyDescriptor.getReadMethod();
              SupportLanguage s = m.invoke(user);
              System.out.println("languageCode: " + s.getLanguageCode()); 
bhdrkn
  • 6,244
  • 5
  • 35
  • 42
0

instead of using the java bean API you can also use pure reflection like the following example. the point is to set the private field accessible what may cause a accessibility-exception if the vm runs on a secure environment that has restrictions on that. but for this cases you may can make your properties protected.

public class GetPropertyTest {

@Test
public void testGetFLang() throws Exception {
    User user = new User();

    Field declaredField = user.getClass().getDeclaredField( "flang" );
    declaredField.setAccessible( true );

    // get the value
    SupportLanguage flang = (SupportLanguage) declaredField.get( user );

    assertEquals( 
        "SupportLanguage [languageCode=lang1, flang=true, mlang=true]", 
        flang.toString() 
    );

    // set new value
    declaredField.set( user, new SupportLanguage( "lang3", false, false ) );
    assertEquals(
        "User [firstName=null, lastName=null, "
        + "flang=SupportLanguage [languageCode=lang3, flang=false, mlang=false], "
        + "mlang=SupportLanguage [languageCode=lang2, flang=true, mlang=true]]",
        user.toString()
    );
}

@Test
public void testSetValuesFromMap() throws Exception {
    Map<String, Object> valueMap = new HashMap<String, Object>();
    valueMap.put( "firstName", "Jon" );
    valueMap.put( "lastName", "Doo" );
    valueMap.put( "flang", new SupportLanguage( "langFormMap1", true, true ) );
    valueMap.put( "mlang", new SupportLanguage( "langFormMap2", true, true ) );

    User user = new User();

    for ( Map.Entry<String, Object> entry : valueMap.entrySet() ) {
        String fieldName = entry.getKey();
        Object fieldValue = entry.getValue();
        Field declaredField = user.getClass().getDeclaredField( fieldName );
        declaredField.setAccessible( true );
        declaredField.set( user, fieldValue );
    }

    assertEquals(
        "User ["
        + "firstName=Jon, "
        + "lastName=Doo, "
        + "flang=SupportLanguage [languageCode=langFormMap1, flang=true, mlang=true], "
        + "mlang=SupportLanguage [languageCode=langFormMap2, flang=true, mlang=true]]",
        user.toString()
    );
}

public class User {
    private String firstName;
    private String lastName;
    private SupportLanguage flang = new SupportLanguage( "lang1", true, true );
    private SupportLanguage mlang = new SupportLanguage( "lang2", true, true );
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append( "User [firstName=" );
        builder.append( firstName );
        builder.append( ", lastName=" );
        builder.append( lastName );
        builder.append( ", flang=" );
        builder.append( flang );
        builder.append( ", mlang=" );
        builder.append( mlang );
        builder.append( "]" );
        return builder.toString();
    }

}

public class SupportLanguage {

    private String languageCode;
    private Boolean flang;
    private Boolean mlang;


    public SupportLanguage( String languageCode, Boolean flang, Boolean mlang ) {
        super();
        this.languageCode = languageCode;
        this.flang = flang;
        this.mlang = mlang;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append( "SupportLanguage [languageCode=" );
        builder.append( languageCode );
        builder.append( ", flang=" );
        builder.append( flang );
        builder.append( ", mlang=" );
        builder.append( mlang );
        builder.append( "]" );
        return builder.toString();
    }
}

}

Andreas
  • 303
  • 1
  • 9