歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 關於struts2 json插件的正則表達式寫法的一點兒總結

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

日期:2017/3/1 10:14:08   编辑:Linux編程

最近碰到一個問題,需要將一個集體序列化成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. return this.buf.toString();
  13. }

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

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

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

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

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

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

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

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

Copyright © Linux教程網 All Rights Reserved