Keep a reminder of the process of trial and error to get all the fields in the bean.
I want to get all the fields in the bean with Iterator. ** "Field1, Field2, Field3, Field4" ** can be acquired for the following beans.
Fields.java
public class Fields {
//field
private String Field1;
private String Field2;
private String Field3;
private String Field4;
//constructor
Fields(String Field1, String Field2, String Field3, String Field4) {
this.Field1 = Field1;
this.Field2 = Field2;
this.Field3 = Field3;
this.Field4 = Field4;
}
// settet,getter omitted
// .
// .
// .
}
** PropertyUtils ** and ** BeanUtils ** are classes that handle ** JavaBeans **. [^ 1]
Among them, using the describe (Object bean)
method that converts each value in the bean to Map and returns it,
** Convert Bean to Map → Get key value of converted Map (field name) **
I decided to get all the fields in the bean.
[^ 1]: Click here for a reference site on how to use BeanUtils. Java BeanUtils memo (Hishidama's commons-BeanUtils Memo)
Fields.java(Use PropertyUtils)
// PropertyUtils#Get all fields using describe
public Iterator<?> getNames()
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
try{
//Convert Bean to Map → Get key value of converted Map (field name)
return PropertyUtils.describe(this).keySet().iterator();
}catch(IllegalAccessException e){
throw e;
}catch(InvocationTargetException e){
throw e;
}catch(NoSuchMethodException e){
throw e;
}
}
Fields.java(Use BeanUtils)
// BeanUtilsUtils#Get all fields using describe
public Iterator<?> getNames1()
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
try{
//Convert Bean to Map → Get key value of converted Map (field name)
return BeanUtils.describe(this).keySet().iterator();
}catch(IllegalAccessException e){
throw e;
}catch(InvocationTargetException e){
throw e;
}catch(NoSuchMethodException e){
throw e;
}
}
FieldGet.java
package test;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
public class FieldGet {
public static void main (String args[]){
Fields field = new Fields("Field 1","Field 2","Field 3","Field 4");
Iterator<?> propertyUtils;
Iterator<?> beanUtils;
try {
// PropertyUtils#Get all fields using describe
propertyUtils = field.getNames();
// BeanUtilsUtils#Get all fields using describe
beanUtils = field.getNames1();
System.out.println("--Use PropertyUtils--");
while(propertyUtils.hasNext()){
System.out.println(propertyUtils.next());
}
System.out.println("--Using BeanUtils--");
while(beanUtils.hasNext()){
System.out.println(beanUtils.next());
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
Execution result
--Use PropertyUtils--
Field1
Field3
class
Field2
Field4
--Using BeanUtils--
Field1
Field3
class
Field2
Field4
I was able to get the field name of the bean, There seems to be room for improvement, such as getting a "class" that is not a field name, or not in ascending order.
Also, while running it several times ...
ʻInvocationTargetException occurred at
PropertyUtils / BeanUtils.describe (this) `, and the field could not be retrieved.
I don't know the exact cause, so I decided to consider getting the field name in another way.
Execution result(part)
Caused by: java.lang.reflect.InvocationTargetException
... 1024 more
Caused by: java.lang.StackOverflowError
Bean fields can also be obtained ** with the reflection API **. [^ 2]
With getDeclaredFields ()
, ** all access modifier (public, protected, default, private) fields can be retrieved as an array of Field class **.
[^ 2]: Get field with Java reflection API
Fields.java(Use reflection)
// Class#Get all fields using getDeclaredFields
public Iterator<?> getNames2(){
//Get fields for all access modifiers
Field[] tmpField = this.getClass().getDeclaredFields();
//Generate a list to return with Iterator
List<String> Field = new ArrayList<String>();
for(int i = 0; i < tmpField.length; i++) {
// getName()Get the field with
Field.add(tmpField[i].getName());
}
return Field.iterator();
}
FieldGet.java
package test;
import java.util.Iterator;
public class FieldGet {
public static void main (String args[]){
Fields field = new Fields("Field 1","Field 2","Field 3","Field 4");
terator<?> reflection;
// Class#Get all fields using getDeclaredFields
reflection = field.getNames2();
System.out.println("--Use reflection--");
while(propertyUtils.hasNext()){
System.out.println(propertyUtils.next());
}
}
}
Execution result
--Use reflection--
Field1
Field2
Field3
Field4
Now, as expected, we were able to get all the fields.
You can also get all fields in Struts DynaActionForm. ** ✳︎ The idea is the same as "What I tried 1" **
Step 1: Create a class that inherits DynaValidatorForm or DynaActionForm
Step 2: Implement the method with the same idea ** as "What I tried 1" ** (Convert form to Map → Get key value of converted Map (field name)) **
Struts DynaActionForm has a getMap ()
method that converts the property defined in DynaActionForm to Map type and returns it **, so if you use that method, it is the same as "What I saw 1" It is possible to get all fields with the idea of.
Is it something like ** equivalent to the describe (Object bean) method of the PropertyUtils / BeanUtils class **?
I'm not sure about the detailed internal processing ...
StrutsDynaValidatorForm.java
package test;
import java.util.Iterator;
import org.apache.struts.validator.DynaValidatorForm;
public class StrutsDynaValidatorForm extends DynaValidatorForm {
public Iterator getNames() {
return this.getMap().keySet().iterator();
}
}
Recommended Posts