2013-03-12 3 views
4

BeanutilsBean.describe() 메서드를 사용하여 감사 내역의 데이터를 가져옵니다. 그것은 잘 작동합니다 - 그건 문제가 아닙니다!Apache Commons BeanUtilsBean - describe()에서 속성 제외

그러나 감사 할 필요가없는 특정 속성이 있습니다. 이들은 목록에 문자열로 기록됩니다. 예를 들어, 속성이 DomainObject.myValue 인 경우 목록에 "myValue"이 포함되어 DomainObject.getMyValue()에 대한 호출 결과가 감사 추적에 포함되지 않습니다.

현재 코드는 모든 속성을 BeanutilsBean.describe()에서 가져 와서 반복하여 원하지 않는 속성을 삭제합니다.

내가 할 수있게하려면 제외 할 속성 이름 목록을 사용하여 BeanUtilsBean 인스턴스를 구성하여 해당 메소드를 호출하지 않도록하십시오. 그래서 내 예에서는 DomainObject.getMyValue()가 전혀 호출되지 않습니다.

API 또는 코드를 살펴볼 수없는 경우 해결할 수 없습니다.

답변

1

아니요, 필터링은 가장 간단한 방법입니다. 이 방법의 출처는 어떠한 종류의 구성 가능한 필터링도 제공하지 않습니다.

  • 전화 describe() 다음 (당신이 지금 무슨 일을하는지) 결과를 필터링 : BeanUtilsBean를 사용하는 동안 내가 볼 수있는 유일한 두 가지 옵션이 정말있다. public static Map<String, String> describeBean(Object bean, String... excludedProperties)
  • describe()의 구현을 복사하지만 초기 반복 중에 필터링을 수행하는 사용자 고유의 유틸리티 메소드 (위와 같은 서명)를 롤링 할 수 있습니다. 이것은 Map을 추가로 통과 할 필요가 없기 때문에 더 효과적입니다.
4

이것은 이것을 해결하는 데 사용 된 코드입니다.

제외 된 속성 getters를 호출하지 않는 BeanUtilsBean.describe()의 약간 수정 된 복사본입니다. ach's answer에서 "자신 만의 롤"옵션을 사용할 수 있습니다 (첫 번째 옵션은 2 년 동안 실제 코드에서 사용되었지만 절대로 나와 앉지 않았습니다!).

import java.beans.PropertyDescriptor; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Set; 

import org.apache.commons.beanutils.BeanUtilsBean; 
import org.apache.commons.beanutils.DynaBean; 
import org.apache.commons.beanutils.DynaProperty; 
import org.apache.commons.beanutils.MethodUtils; 

public class BeanUtilsBeanExtensions { 

    private static final BeanUtilsBean BEAN_UTILS_BEAN = BeanUtilsBean 
        .getInstance(); 

    public BeanUtilsBeanExtensions() { 
    } 

    /** 
    * Extends BeanUtilsBean.describe() so that it can be given a list of 
    * attributes to exclude. This avoids calling methods which might derive 
    * data which don't happen to be populated when the describe() call is made 
    * (and therefore could throw exceptions) as well as being more efficient 
    * than describing everything then discarding attributes which aren't 
    * required. 
    * 
    * @param bean 
    *   See BeanUtilsBean.describe() 
    * @param excludedAttributeNames 
    *   the attribute names which should not be described. 
    * @return See BeanUtilsBean.describe() 
    */ 
    public Map<String, String> describe(Object bean, 
        Set<String> excludedAttributeNames) 
        throws IllegalAccessException, 
        InvocationTargetException, NoSuchMethodException { 

     // This method is mostly just a copy/paste from BeanUtilsBean.describe() 
     // The only changes are: 
     // - Removal of reference to the (private) logger 
     // - Addition of Reference to a BeanUtilsBean instance 
     // - Addition of calls to excludedAttributeNames.contains(name) 
     // - Use of generics on the Collections 
     // - Calling of a copy of PropertyUtilsBean.getReadMethod() 

     if (bean == null) { 
      return (new java.util.HashMap<String, String>()); 
     } 

     Map<String, String> description = new HashMap<String, String>(); 
     if (bean instanceof DynaBean) { 
      DynaProperty[] descriptors = ((DynaBean) bean).getDynaClass() 
          .getDynaProperties(); 
      for (int i = 0; i < descriptors.length; i++) { 
       String name = descriptors[i].getName(); 
       if (!excludedAttributeNames.contains(name)) { 
        description.put(name, 
            BEAN_UTILS_BEAN.getProperty(bean, name)); 
       } 
      } 
     } 
     else { 
      PropertyDescriptor[] descriptors = BEAN_UTILS_BEAN 
          .getPropertyUtils().getPropertyDescriptors(bean); 
      Class<? extends Object> clazz = bean.getClass(); 
      for (int i = 0; i < descriptors.length; i++) { 
       String name = descriptors[i].getName(); 
       if (!excludedAttributeNames.contains(name) 
           && getReadMethod(clazz, descriptors[i]) != null) { 
        description.put(name, 
            BEAN_UTILS_BEAN.getProperty(bean, name)); 
       } 
      } 
     } 
     return description; 
    } 

    /* 
    * Copy of PropertyUtilsBean.getReadMethod() since that is package-private. 
    */ 
    private Method getReadMethod(Class<? extends Object> clazz, 
        PropertyDescriptor descriptor) { 
     return MethodUtils.getAccessibleMethod(clazz, 
         descriptor.getReadMethod()); 
    } 

}