`
Fly_m
  • 浏览: 259640 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

struts2与json插件(2)

阅读更多

 

在前一篇中<struts2与json插件(1)> ,讲到了解决在struts2中出现的一点点乱码问题,就想看看json中的数据处理方式.由struts2的处理流程来看,主要处理result的代码如下在defaultActionInvocation中:

private void executeResult() throws Exception {
        result = createResult();

        String timerKey = "executeResult: "+getResultCode();
        try {
            UtilTimerStack.push(timerKey);
            if (result != null) {
                result.execute(this);
            } else if (resultCode != null && !Action.NONE.equals(resultCode)) {
                throw new ConfigurationException("No result defined for action " + getAction().getClass().getName() 
                        + " and result " + getResultCode(), proxy.getConfig());
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("No result returned for action "+getAction().getClass().getName()+" at "+proxy.getConfig().getLocation());
                }
            }
        } finally {
            UtilTimerStack.pop(timerKey);
        }
    }

 
如上所示,result就是返回的result,而resultCode就是我们通用的String返回类型了.而json插件中,采用默认值Action.Success来得到json类型,而在result中处理,即调用上面的result.invoke(this).json中的主要处理代码如下(省略中间一些代码):

    public void execute(ActionInvocation invocation) throws Exception {
        ActionContext actionContext = invocation.getInvocationContext();
        HttpServletRequest request = (HttpServletRequest) actionContext
            .get(StrutsStatics.HTTP_REQUEST);
        HttpServletResponse response = (HttpServletResponse) actionContext
            .get(StrutsStatics.HTTP_RESPONSE);

        try {
            String json;
            Object rootObject;
            if (this.enableSMD) {
                //generate SMD
                rootObject = this.writeSMD(invocation);
            } else {
                // generate JSON
                if (this.root != null) {
                    ValueStack stack = invocation.getStack();
                    rootObject = stack.findValue(this.root);
                } else {
                    rootObject = invocation.getAction();
                }
            }
            json = JSONUtil
                .serialize(rootObject, this.excludeProperties, ignoreHierarchy, enumAsBean);

            boolean writeGzip = enableGZIP && JSONUtil.isGzipInRequest(request);
           
            JSONUtil.writeJSONToResponse(response, this.defaultEncoding,
                isWrapWithComments(), json, false, writeGzip);

        } catch (IOException exception) {
            log.error(exception);
            throw exception;
        }
    }

 

可以看出,json插件的功能(在处理json上),就是将invocation中的action对象转化成json对象,再输出到页面上.
    在上面的应用上来看,用json插件必须注册json的resultType,而且,返回类型一定是json,也就是说,你必须给每一个json调用定义一个json的返回类型,而实际上这个类型就是转向jsonResult上,和一般的调用不一样,它不返回任何视图.即json这个返回类型感觉上完全是多余的,除了标明是json返回之外没有其他作用.而且对于解析来说,它是解析一个action对象,所就是说,如果你的action是富对象,里面有很多的属性,而实际你需要的不多时,那这个解析就完全失去了作用了.
     话说这么多,改进方法,从根本上来说,就是改进这种解析机制.是不解析当前的action对象,而是像spring一样,解析只需要解析的对象一样.如返回a,就只需要解析a.查看上面的executeResult()方法,其中对result和resultCode进行了处理.其中有这么一句

if (result != null) {
                result.execute(this);
            } else if (resultCode != null && !Action.NONE.equals(resultCode)) {
                throw new ConfigurationException("No result defined for action " + getAction().getClass().getName() 
                        + " and result " + getResultCode(), proxy.getConfig());
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("No result returned for action "+getAction().getClass().getName()+" at "+proxy.getConfig().getLocation());
                }
            }

 

第一句,也就是一般我们进行处理的地方,调用result进行最后的处理.而第二句,则是对resultCode进行判断,而第三句什么都不做.所以,对于其他的处理,可以从resultCode下手.方法有两种,一是返回无类型,即void类型,二是返回Action.NONE.当是这两种类型的时候,struts2就不会对result进行主动处理了.详细可参见struts2对Action.NONE的说明,如下:


/**
     * The action execution was successful but do not
     * show a view. This is useful for actions that are
     * handling the view in another fashion like redirect.
     */
    public static final String NONE = "none";

 

 即我们只需要在action方法中,处理ajax调用,而返回void或者"none"就行了.参考方法调用就如下:


public void showCategoryListAjax2() throws Exception {
		this.category = this.service.getCategory(this.id);
		/** 如果该类别为空 **/
		if(this.category == null) {
			AjaxResponse.sendAjaxText(null, ServletActionContext.getResponse());
			return;
		}

		this.categoryList = this.service.getCategoryListBySuperCategory(this.category);

		AjaxResponse.sendAjaxText(this.categoryList, ServletActionContext.getResponse());
	}

 

 上面的返回类别是一种取巧的方法,更好的方法是返回Action.NONE.这样在struts.xml配置就像这样:

<action name="taa" class="articleAction" method="topArticleAjax"/>

 是不是更好,惟一要做的就是在action方法处理json转换.不过这不是主要问题,在参考json的转换模式上,我对json转换进行了改进.在Fly_m的注解上如下:

public @Interface Fly_m{
      String name() default ""; 
      String format() default ""; 
      boolean exclude() default false; 
}

 支持如json一样的名称和format以及exclude(如果为真则不进行转换).另外,支持排除指定类(如果转换对象类型和排除类一致而不进行转换)和指定名称的对象(如果对象名称和排除对象名称一致,则被忽略,只限于对象和map.这对于hibernate这种相互调用的持久层对象最好了).如对象a.b.c的形式.默认的json转换是完全转换,在json插件上,如果在b上设定json(exclude),则无论如何b都不会被转换,这种方法太过固定,不支持临时配置.而在改进中,只需要加一个"a.b"形式的excludeProperties参数就可以了.如果想转换时,把参数去掉就行了.相应的转换方法如下:

public static String convertToJson(Object obj, String... excludeProperties) {
		return convertToJson(obj, null, null, excludeProperties);
	}

  

public static String convertToJson(Object obj, Format format, Class[] excludeClasses, String... excludeProperties) {
		JsonHandle jsonHandle = new JsonHandle();
		jsonHandle.excludeProperties = excludeProperties;
		jsonHandle.excludeClasses = excludeClasses;
		if(format != null)
			jsonHandle.defaultFormat = format;
		return jsonHandle.convertToJson(null, 0, obj);
	}

  而在jsonHandle中是这样处理的.

public String convertToJson(String s, int depth, Object obj) {
			if(obj == null || obj.getClass().getName().indexOf("$$EnhancerByCGLIB$$") != -1 || contains(excludeClasses, obj.getClass())) {
				sb.append("null");
			} else if(isSimpleType(obj.getClass())) {
				if(obj instanceof Character) {
					sb.append("'").append(obj).append("'");
				} else {
					sb.append(obj);
				}
			} else
			if(String.class.isAssignableFrom(obj.getClass()) || StringBuffer.class.isAssignableFrom(obj.getClass())
					|| StringBuilder.class.isAssignableFrom(obj.getClass())) {
				sb.append('"');
				CharacterIterator it = new StringCharacterIterator(obj.toString());

				for(char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
					if(c == '"') {
						sb.append("\\\"");
					} else if(c == '\\') {
						sb.append("\\\\");
					} else if(c == '/') {
						sb.append("\\/");
					} else if(c == '\b') {
						sb.append("\\b");
					} else if(c == '\f') {
						sb.append("\\f");
					} else if(c == '\n') {
						sb.append("\\n");
					} else if(c == '\r') {
						sb.append("\\r");
					} else if(c == '\t') {
						sb.append("\\t");
					} else if(Character.isISOControl(c)) {
						sb.append(unicode(c));
					} else {
						sb.append(c);
					}
				}

				sb.append('"');
			} else if(obj instanceof Collection) {
				boolean hibernateFlag;
				try {
					((Collection) obj).size();
					hibernateFlag = true;
				} catch(Exception ex) {
					hibernateFlag = false;
				}

				if(hibernateFlag) {
					sb.append("[");

					for(Iterator iterator = ((Collection) obj).iterator(); iterator.hasNext();) {
						convertToJson(s, depth, iterator.next());

						if(iterator.hasNext()) {
							sb.append(",\n");
						}
					}

					sb.append("]");
				} else {
					sb.append("null");
				}

			} else if(obj.getClass().isArray()) {
				sb.append("[");

				int max = java.lang.reflect.Array.getLength(obj);

				for(int i = 0; i < max; i++) {
					if(i > 0) {
						sb.append(",");
					}
					convertToJson(s, depth, java.lang.reflect.Array.get(obj, i));
				}

				sb.append("]");
			} else if(java.util.Map.class.isAssignableFrom(obj.getClass())) {
				if(sb.length() > 0 && sb.lastIndexOf(",") != -1) {
					sb.insert(sb.lastIndexOf(",") + 1, "\n");
				}
				sb.append("{");

				for(Map.Entry e : ((Map<?, ?>) obj).entrySet()) {
					if(!(e.getKey() instanceof String))
						continue;
					if(contains(excludeProperties, e.getKey().toString())) {
						continue;
					}
					if(sb.length() > 0 && sb.charAt(sb.length() - 1) == ',' && sb.charAt(sb.length() - 2) == '}') {
						sb.insert(sb.length(), "\n");
					}
					sb.append("\"").append(e.getKey()).append("\"").append(":");

					if(depth <= DEFAULT_DEPTH) {
						convertToJson(add(s, e.getKey().toString()), depth + 1, e.getValue());
					} else {
						sb.append("undefined");
					}

					sb.append(",");
				}

				if(sb.length() > 3) {
					sb.deleteCharAt(sb.length() - 1);
				}

				sb.append("}");
			} else {
				Map map = null;
				try {
					map = getPropertiesByReflect(this, obj);
				} catch(Exception ex) {
					ex.printStackTrace();
				}

				convertToJson(s, depth, map);
			}
			return sb.toString();
		}
	}

 

 相关的转换方法都参照了其他的处理方式,具体解析方法请参照附件中的JsonUtils类.

 这篇文章只是说明了一种对于json的一种新的处理方式,并不是对于json插件的不满,当然我还是喜欢自己的处理方式.加上前面对乱码的处理,算是对struts2的一种补充吧.

  • JsonUtil.rar (2.1 KB)
  • 描述: JsonUtils.java 源代码.
  • 下载次数: 341
分享到:
评论
2 楼 lylelb 2010-04-14  
牛!!!!
1 楼 talangniao 2008-12-12  
好酷!!!

相关推荐

    struts2的json插件

    4. **与AJAX集成**:JSON插件使得Struts2与jQuery、Dojo等库的AJAX请求无缝集成,能够快速响应前端的动态请求。 在提供的压缩包中,有两个不同版本的JSON插件:`jsonplugin-0.34.jar` 和 `jsonplugin-0.32.jar`。...

    struts2与json整合

    要实现Struts2与JSON的整合,首先需要在项目中引入Struts2 JSON插件。根据给定的部分内容,可以看到使用的是`struts2-json-plugin-2.1.8.1.jar`这个JAR包。该插件包含处理JSON相关的类库,使得Struts2能够识别并处理...

    使用Struts2的JSON插件来实现JSON数据传递

    Struts2 JSON插件的安装与配置是使用其功能的第一步。首先,你需要将struts2-json-plugin相关的JAR文件添加到项目的类路径中。然后,在Struts2的配置文件struts.xml中启用JSON插件,通常通过以下配置实现: ```xml ...

    struts2+json

    在Struts2中集成JSON支持,首先需要添加相应的依赖,比如struts2-json-plugin,这个插件提供了JSON结果类型。当Action执行完毕后,可以返回一个JSON结果类型,Struts2会自动将Action的属性转换为JSON格式并返回给...

    struts2-json-plugin

    struts2-json-plugin,Struts JSON插件

    struts2-json

    Struts2是一个非常著名的Java Web框架,用于构建企业级...总的来说,Struts2与JSON的结合简化了Web应用的开发流程,提高了数据交换的效率。但是,同时也需要关注其安全性,确保在享受便利的同时,不会引入潜在的风险。

    struts2-json-plugin源码

    在Struts2中,通过整合JSON插件,可以方便地将Action的返回结果转换为JSON格式,供前端JavaScript处理。 `struts2-json-plugin`是Struts2的一个插件,它使得Struts2能够处理JSON请求和响应,无需额外的配置或库。这...

    json-lib-2.1.jar和struts2-json-plugin-2.1.8.1.jar

    `struts2-json-plugin-2.1.8.1.jar` 则是Struts 2框架的一个插件,主要用于增强Struts 2对JSON的支持。Struts 2是一款非常流行的MVC(Model-View-Controller)框架,用于构建企业级的Java Web应用程序。这个插件允许...

    Struts2.5操作JSON相关jar包

    首先,`json包和struts2——json插件`这个文件很可能包含了Struts2的JSON插件,它是Struts2与JSON进行数据交换的核心组件。该插件允许我们在Action类中直接返回JSON对象,无需额外的序列化处理。通过配置插件,...

    struts 2.0 与 2.1 需要的json插件

    总的来说,Struts 2的JSON插件是实现JSON支持的关键组件,它使得Struts 2能够无缝地与JSON数据交互,从而提高了Web应用的交互性和效率。正确配置和使用JSON插件,可以帮助开发者构建更高效的AJAX应用或RESTful API。

    Struts2与JSON

    将Struts2与JSON整合,可以实现高效、动态的Web交互。 首先,我们要理解Struts2整合JSON的基本流程。在Struts2中,我们可以通过Action类返回一个JSON结果类型,这样Struts2会自动将Action的属性转化为JSON格式并...

    struts2的json插件实例

    Struts2是一个非常流行的Java Web框架,用于构建可维护、可扩展且结构良好的应用程序。...通过深入理解和实践,你将能更好地掌握Struts2与JSON的结合,为你的Java Web应用提供强大的数据交换能力。

    struts2-json-plugin-2.3.8.jar

    在实际开发中,为了使用这个插件,你需要将`struts2-json-plugin-2.3.8.jar`文件放入项目的类路径(classpath)下,然后在Struts2的配置文件(通常为struts.xml)中启用JSON插件。在Action类中,定义返回JSON数据的...

    struts2返回JSON数据的两种方式

    在本文中,我们将探讨两种在Struts2框架中返回JSON数据的方法。...二是利用Struts2的内置JSON插件,通过返回特定的属性和结果类型自动处理JSON。每种方法都有其适用场景,可以根据项目需求选择合适的方式。

    struts2的json插件配置详解(附demo)

    为了方便ajax调用传输数据,在struts2中加入的json插件用来做对象的序列化和反序列化,json插件的下载地址 http://code.google.com/p/jsonplugin/ 1. 下载json插件包,将jar包拷贝到WEB-INF/lib目录 注:struts2...

    struts2所需的包和Struts2_json所需包

    2. **Struts2 JSON插件**:Struts2提供了一个JSON插件(`struts2-json-plugin.jar`),它允许我们将Action的返回值直接转换为JSON格式,便于前后端数据交换。这个插件简化了原本需要手动序列化对象到JSON字符串的...

    struts2+json的使用

    2. 配置Struts2的JSON插件:在struts.xml配置文件中,添加JSON插件的配置,以启用JSON支持。 ```xml &lt;constant name="struts.enable.SMD" value="true"/&gt; &lt;constant name="struts.action.extension" value=",json"/...

    struts2的json插件配置详解(附示例strutsJson)

    这篇博客将深入讲解Struts2的JSON插件配置,并通过实例“strutsJson”来演示具体用法。 首先,让我们了解JSON插件的基本配置。在Struts2框架中,我们需要在`struts.xml`配置文件中引入JSON插件的相关配置。这通常...

Global site tag (gtag.js) - Google Analytics