Giriş
Şu satırı dahil ederiz.
Şu satırı dahil ederiz.
Ortak Noktalar
1. Her iki sınıf ta erişilmeye çalışılan sınıfın public olmasını ve no argument constructor'a sahip olmasını ister. Açıklaması şöyle. Eğer bu koşullar sağlanmazsa BeanUtils InvocationTargetException fırlatır.
1. BeanUtils ve PropertyUtils hemen hemen aynı şeyleri yapıyor gibi görünüyor, ancak aralarında önemli bir fark var.
BeanUtils verilen parametreyi setter metodundaki tipe çevirmeye çalışıyor. PropertyUtils bunu yapmıyor. BeanUtils için açıklama şöyle.
Aynı şeyi söyleyen bir başka açıklama şöyle.
void setFieldA(int value) olsun. Bu durumda BeanUtils setter metodu bulabilir ancak PropertyUtils bulamaz ve PropertyUtils IllegalArgumentException fırlatır.
Bu durum XML'den okuma yapınca setter çağırmak için BeanUtils'i kullanmayı daha kolay yapıyor.
Örnek - String parametreyi int setter'a çevirme
Elimizde şöyle bir kod olsun.
copyProperties metodu - destinaton + original
İmzası şöyle.
Şöyle yaparız.
Şöyle yaparız. Exception yakalamayı göstermedim.
Eğer bean'ler aynı değilse exception fırlatır. Elimizde iki alan ismine sahip iki bean olsun.
Sadece verilen alanları kopyalar.
Şu satırı dahil ederiz.
import org.apache.commons.beanutils.BeanUtils;
MavenŞu satırı dahil ederiz.
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
BeanUtils ve PropertyUtils birbirlerine benziyorlar.Ortak Noktalar
1. Her iki sınıf ta erişilmeye çalışılan sınıfın public olmasını ve no argument constructor'a sahip olmasını ister. Açıklaması şöyle. Eğer bu koşullar sağlanmazsa BeanUtils InvocationTargetException fırlatır.
2. Hem BeanUtils hem de PropertyUtils Introspection kullanarak getter/setter metodları kullanır. Açıklaması şöyle.The class must be public, and provide a public constructor that accepts no arguments. This allows tools and applications to dynamically create new instances of your bean, without necessarily knowing what Java class name will be used ahead of time,...
Elimizde şöyle bir kod olsun.The BeanUtils package relies on introspection rather than reflection. This means that it will find only JavaBean compliant properties.
There are some subtleties of this specification that can catch out the unwary:
- A property can have only one set and one get method. Overloading is not allowed.
- The java.beans.Introspector searches widely for a custom BeanInfo class. If your class has the same name as another with a custom BeanInfo (typically a java API class) then the Introspector may use that instead of creating via reflection based on your class. If this happens, the only solution is to create your own BeanInfo.
public class Bean {
protected Boolean happy;
public void setHappy(Boolean happy) {
this.happy = happy;
}
}
Şöyle yaparız.Bean bean = new Bean();
BeanUtils.setProperty(bean, "happy", true);
Farklar1. BeanUtils ve PropertyUtils hemen hemen aynı şeyleri yapıyor gibi görünüyor, ancak aralarında önemli bir fark var.
BeanUtils verilen parametreyi setter metodundaki tipe çevirmeye çalışıyor. PropertyUtils bunu yapmıyor. BeanUtils için açıklama şöyle.
Set the specified property value, performing type conversions as required to conform to the type of the destination property.
Örneği field tipi int olsun ancak elimizdeki atanacak parametre tipi String olsun ve setter metoduThere is however a big difference between these two classes which I came across while using these classes: BeanUtils does an automatic type conversion and PropertyUtils does not.For example: with BeanUtils you can set a double valued property by providing a String. BeanUtils will check the type of the property and convert the String into a double. With PropertyUtils you always have to provide a value object of the same type as the property, so in this example a double.
void setFieldA(int value) olsun. Bu durumda BeanUtils setter metodu bulabilir ancak PropertyUtils bulamaz ve PropertyUtils IllegalArgumentException fırlatır.
Bu durum XML'den okuma yapınca setter çağırmak için BeanUtils'i kullanmayı daha kolay yapıyor.
Örnek - String parametreyi int setter'a çevirme
Elimizde şöyle bir kod olsun.
public static class Obj {
private int number;
private String string;
public void setNumber(int number) {
this.number = number;
}
public void setString(String string) {
this.string = string;
}
public String toString() {
return "number=" + number + " string=" + string;
}
}
Şöyle yaparızString[] values = new String[] { "1", "two" };
String[] properties = new String[] { "number", "string" };
Obj obj = new Obj();
for (int i = 0; i < properties.length; i++) {
BeanUtils.setProperty(obj, properties[i], values[i]);
}
System.out.println("obj=" + obj);
Çıktı olarak şunu alırızobj=number=1 string=two
2. BeanUtils var olmayan bir field'ı set etmeye çalışınca exception fırlatmaz hata da vermez. PropertyFields ise NoSuchMethodException fırlatır.copyProperties metodu - destinaton + original
İmzası şöyle.
public static void copyProperties(Object dest, Object orig)
throws IllegalAccessException,
InvocationTargetException)
ÖrnekŞöyle yaparız.
BeanUtils.copyProperties(dest, source);
ÖrnekŞöyle yaparız. Exception yakalamayı göstermedim.
Ch409F fromBean = new Ch409F();
...
Ch409DifF toBean = new Ch409DifF();
...
BeanUtils.copyProperties(toBean, fromBean);
ÖrnekEğer bean'ler aynı değilse exception fırlatır. Elimizde iki alan ismine sahip iki bean olsun.
BeanDTO {
NestedBeanDTO nestedProperty;
}
Bean {
NestedBean nestedProperty;
}
Şöyle yaparız.BeanUtils.copyProperties(Bean, BeanDTO)
Exception olarak şunu alırız.argument type mismatch - had objects of type "NestedBeanDTO" but expected signature
"NestedBean"
copyProperties metodu - destination + original + propertiesSadece verilen alanları kopyalar.
Örnek
Şöyle yaparız
Student student = new Student();
student.setName("Tom");
student.setAge(18);
Student newStudent = new Student();
BeanUtils.copyProperties(student,newStudent);
System.out.println(newStudent);
getConvertUtils metodu
Elimizde şöyle bir kod olsun.
private static class CustomBeanConverter implements Converter {
@Override
public <T> T convert(Class<T> aClass, Object o) {
Object output = null;
try {
output = aClass.getDeclaredConstructor().newInstance();
BeanUtils.copyProperties(output, o);
} catch (IllegalAccessException | InvocationTargetException |
NoSuchMethodException | InstantiationException e) {
e.printStackTrace();
}
return (T)output;
}
}
Şöyle yaparız.BeanUtilsBean.getInstance().getConvertUtils().register(
new CustomBeanConverter(), NestedBean.class);
BeanUtils.copyProperties(Bean, BeanDTO)
getProperty metoduAçıklaması şöyle.
Eğer field'a erişemiyorsa şu exception fırlatılır.... Thus when we extract a property or event name from the middle of an existing Java name, we normally convert the first character to lower case*case 1. However to support the occasional use of all upper-case names, we check if the first two characters*case 2 of the name are both upper case and if so leave it alone. So for example,'FooBah" becomes 'fooBah'
'Z' becomes 'z'
'URL' becomes 'URL'We provide a method Introspector.decapitalize which implements this conversion rule
But wUnknown property 'User_Name' on class 'User'".
Örnek
Şöyle yaparız.
Object object = ...;
Object str = BeanUtils.getProperty(object,"count");
Örnek
Elimizde şöyle bir kod olsun. getProperty() metodunu "User_Name" olarak çağırırsak exception fırlatır. Çünkü getUser_Name() and setUser_Name() metodlarına bakarak property'nin "user_Name" olması beklenir.
Birden fazla alanı aynı anda set etmek için kullanılır.
Örnek
Elimizde şöyle bir kod olsun
İmzası şöyle.Elimizde şöyle bir kod olsun. getProperty() metodunu "User_Name" olarak çağırırsak exception fırlatır. Çünkü getUser_Name() and setUser_Name() metodlarına bakarak property'nin "user_Name" olması beklenir.
public class User {
private String User_Name;
public String getUser_Name() {
return this.User_Name;
}
public void setUser_Name(String user_Name) {
this.User_Name = user_Name;
}
}
Düzeltmek için şöyle yaparızpublic class User {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public static void main(String[] args)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
User bean = new User();
bean.setUserName("name");
System.out.println(BeanUtils.getProperty(bean, "userName"));
}
}
populate metoduBirden fazla alanı aynı anda set etmek için kullanılır.
Örnek
Elimizde şöyle bir kod olsun
class A {
rivate String name;
ublic void setName(String name){
this.name = name;
public String getName(){
return this.name;
}
}
Şöyle yaparız.A someBean = new A();
// access properties as Map
Map<String, Object> properties = BeanUtils.describe(someBean);
properties.set("name","Fred");
BeanUtils.populate(someBean, properties);
// access individual properties
String oldname = BeanUtils.getProperty(someBean,"name");
BeanUtils.setProperty(someBean,"name","Barny");
setProperty metodupublic static void setProperty(Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException
Parameters:
bean - Bean on which setting is to be performed
name - Property name (can be nested/indexed/mapped/combo)
value - Value to be set
ÖrnekŞöyle yaparız.
BeanUtils.setProperty(customer,"firstName","Paul Young");
ÖrnekŞöyle yaparız.
Object reflectedInstance = ...;
Object objectFromResponse = ...;
Field[] fields = reflectedInstance.getClass().getDeclaredFields();
for(Field field: fields) {
Object objectFromResponse = ...;
if(if(field.getName().equals("...")) {
BeanUtils.setProperty(reflectedInstance, field.getName(), objectFromResponse);
}
Hiç yorum yok:
Yorum Gönder