歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

關於struts2 json插件的正則表達式寫法的一點兒總結

最近碰到一個問題,需要將一個集體序列化成json對象,如:List<Person> list=new ArrayList<Person>();

Person對象中有一個屬性是Dept類型的,序列化的時候不想將此屬性也序列化,也就是要排除該屬性,可以在Result中加一個屬性,excludeProperties,關鍵在於值寫什麼,這是個正則表達式,我還加了一個root參數,值是"list",也就是說讓struts2從這個對象開始進行序列化的操作,如果不配的話會默認使用action.

在序列化的過程中,struts2會逐漸進入這個方法

  1. public String write(Object object, Collection<Pattern> excludeProperties,  
  2.                       Collection<Pattern> includeProperties, boolean excludeNullProperties) throws JSONException {  
  3.       this.excludeNullProperties = excludeNullProperties;  
  4.       this.buf.setLength(0);  
  5.       this.root = object;  
  6.       this.exprStack = "";  
  7.       this.buildExpr = ((excludeProperties != null) && !excludeProperties.isEmpty())  
  8.               || ((includeProperties != null) && !includeProperties.isEmpty());  
  9.       this.excludeProperties = excludeProperties;  
  10.       this.includeProperties = includeProperties;  
  11.       this.value(object, null);  
  12.   
  13.       return this.buf.toString();  
  14.   }  

其中的root就是我配的list對象了.最重要的一步是調用value方法,咱們看看這個方法,

  1. this.process(object, method);  

這個方法中又調用了process方法來處理這個對象,

  1. private void process(Object object, Method method) throws JSONException {  
  2.         this.stack.push(object);  
  3.   
  4.         if (object instanceof Class) {  
  5.             this.string(object);  
  6.         } else if (object instanceof Boolean) {  
  7.             this.bool((Boolean) object);  
  8.         } else if (object instanceof Number) {  
  9.             this.add(object);  
  10.         } else if (object instanceof String) {  
  11.             this.string(object);  
  12.         } else if (object instanceof Character) {  
  13.             this.string(object);  
  14.         } else if (object instanceof Map) {  
  15.             this.map((Map) object, method);  
  16.         } else if (object.getClass().isArray()) {  
  17.             this.array(object, method);  
  18.         } else if (object instanceof Iterable) {  
  19.             this.array(((Iterable) object).iterator(), method);  
  20.         } else if (object instanceof Date) {  
  21.             this.date((Date) object, method);  
  22.         } else if (object instanceof Calendar) {  
  23.             this.date(((Calendar) object).getTime(), method);  
  24.         } else if (object instanceof Locale) {  
  25.             this.string(object);  
  26.         } else if (object instanceof Enum) {  
  27.             this.enumeration((Enum) object);  
  28.         } else {  
  29.             this.bean(object);  
  30.         }  
  31.   
  32.         this.stack.pop();  
  33.     }  
這個裡面其實就是根據對象的類型來調用相應的方法來處理,可以看出struts2 json插件支持的數據類型.由於咱們是list類型的,會調用 array這個方法.
  1. private void array(Iterator it, Method method) throws JSONException {  
  2.        this.add("[");  
  3.   
  4.        boolean hasData = false;  
  5.        for (int i = 0; it.hasNext(); i++) {  
  6.            String expr = null;  
  7.            if (this.buildExpr) {  
  8.                expr = this.expandExpr(i);  
  9.                if (this.shouldExcludeProperty(expr)) {  
  10.                    it.next();  
  11.                    continue;  
  12.                }  
  13.                expr = this.setExprStack(expr);  
  14.            }  
  15.            if (hasData) {  
  16.                this.add(',');  
  17.            }  
  18.            hasData = true;  
  19.            this.value(it.next(), method);  
  20.            if (this.buildExpr) {  
  21.                this.setExprStack(expr);  
  22.            }  
  23.        }  
  24.   
  25.        this.add("]");  
  26.    }  

add方法就是在最後的結果添加字符串,expandExpr方法就是用來產生正則是表達式的,對每一個屬性,都會產生一個正則是表達式,可以看出表達式裡面現在是[0],

然後又調用value方法處理第一個person對象.

person對象是Object類型的,在process方法中會調用bean方法,

  1. PropertyDescriptor[] props = info.getPropertyDescriptors();  
  2.   
  3.          boolean hasData = false;  
  4.          for (PropertyDescriptor prop : props) {  
  5.              String name = prop.getName();  
  6.              Method accessor = prop.getReadMethod();  
  7.              Method baseAccessor = findBaseAccessor(clazz, accessor);  
  8.   
  9.              if (baseAccessor != null) {  
  10.                  if (baseAccessor.isAnnotationPresent(JSON.class)) {  
  11.                      JSONAnnotationFinder jsonFinder = new JSONAnnotationFinder(baseAccessor).invoke();  
  12.   
  13.                      if (!jsonFinder.shouldSerialize()) continue;  
  14.                      if (jsonFinder.getName() != null) {  
  15.                          name = jsonFinder.getName();  
  16.                      }  
  17.                  }  
  18.                  // ignore "class" and others   
  19.                  if (this.shouldExcludeProperty(prop)) {  
  20.                      continue;  
  21.                  }  
  22.                  String expr = null;  
  23.                  if (this.buildExpr) {  
  24.                      expr = this.expandExpr(name);  
  25.                      if (this.shouldExcludeProperty(expr)) {  
  26.                          continue;  
  27.                      }  
  28.                      expr = this.setExprStack(expr);  
  29.                  }  
  30.   
  31.                  Object value = accessor.invoke(object);  
  32.                  if (baseAccessor.isAnnotationPresent(JSONFieldBridge.class)) {  
  33.                      value = getBridgedValue(baseAccessor, value);  
  34.                  }  
  35.   
  36.                  boolean propertyPrinted = this.add(name, value, accessor, hasData);  
  37.                  hasData = hasData || propertyPrinted;  
  38.                  if (this.buildExpr) {  
  39.                      this.setExprStack(expr);  
  40.                  }  
  41.              }  
  42.          }  

在bean方法中會得到這個對象的所有屬性,然後遍歷屬性,如果屬性名稱為id,則通過expandExpr方法會生成[0].id這個表達式,然後在shouldExcludeProperty方法中跟你傳的正則表達式進行比較,如果匹配上就會忽略掉該屬性,這個方法裡面有兩個比較,一個是忽略(excludeProperties)的比較,一個是包含(includeProperties)的比較,會先進行忽略的比較,因此,如果匹配上了,就直接返回true,就不會進行包含的比較,這就跟短路的情況差不多,如果沒有匹配,則進行下一個屬性的比較.

我們更關心的是這個表達式的規則是怎樣的,因此其他細節性的東西我們不必要去關注.

有不清楚的情況的話可以再跟蹤源代碼看。

Copyright © Linux教程網 All Rights Reserved