`
mj4d
  • 浏览: 302565 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

struts2-json-plugin2.2.1使用的几个问题

阅读更多

首先我们看看struts2中插件struts2-json-plugin2.2.1的使用:

1、xml配置:当然package还是得直接或间接继承自json-default

 

<action name="list" class="com.sample.s2web.action.user.UserAction" method="list" >
 <result name="success" type="json">
		<param name="ignoreHierarchy">true</param>
		<param name="excludeNullProperties">true</param>//排除空值属性
		<param name="excludeProperties">message</param>//排除属性
		<param name="includeProperties"></param>//包含属性,默认包含所有属性,如果此处填了属性那么就只会包含该
		<param name="root">pageModule</param>
<result>
</action>

 

2、UserAction.java中的list方法:

    public String list() {
        try {
            pageModule = new PageModule<User>();
            pageModule.setList(null);
            pageModule.setTotalCount(30);
            pageModule.setPage(1);
            pageModule.setMessage("Result");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

 

我们来分析下配置和相应的结果:

1、按照上面的配置,这里对root对象pageModule会忽略父类对象:

<param name="ignoreHierarchy">true</param>//default : true

这里主要是内省(Introspector),见JSONWriter中的方法:bean

            info = ((object == this.root) && this.ignoreHierarchy) ? Introspector.getBeanInfo(clazz, clazz
                    .getSuperclass()) : Introspector.getBeanInfo(clazz);

当然这里只会忽略root的父类,而该root的成员变量如果也有继承那就不会被忽略

考虑如下类图:

我们将Student作为root对象,看看采用上面配置生产的JSON:

        Student s = new Student();
        s.setBirthday(new Date());
        s.setUsername("robin");
        s.setAddress("chengdu");
        s.setSalary(12345);
        s.setTitle("SEE");
        
        SCourse c = new SCourse();
        c.setName("JAVA");
        c.setDesc("xxxx");
        c.setPrice(123);
        c.setPublish("Null");
        s.setCourse(c);
        
        return s;

    JSONUtil.serialize(format(), null, null, true, false, false)
//{"address":"chengdu","course":{"desc":"xxxx","name":"JAVA","price":123,"publish":"Null"},"courses":null,"salary":12345,"title":"SEE"}

 由此可见,在生产的JSON串中只忽略了root对象Student的父类,而没有忽略成员变量course的父类。这也是导致某些JSON转换中循环引用的问题。我们来看看JSONWriter.java中的源码:

//通过内省来对bean属性进行序列化
private void bean(Object object) throws JSONException {
        this.add("{");

        BeanInfo info;

        try {
            Class clazz = object.getClass();
            //关键在这里,是否需要忽略父类,这里有两个条件:当前bean是否是根对象和ignoreHierarchy的设置。在下次递归调用此方法时object就不再是root
            info = ((object == this.root) && this.ignoreHierarchy) ? Introspector.getBeanInfo(clazz, clazz
                    .getSuperclass()) : Introspector.getBeanInfo(clazz);

            PropertyDescriptor[] props = info.getPropertyDescriptors();

            boolean hasData = false;
            for (int i = 0; i < props.length; ++i) {
                PropertyDescriptor prop = props[i];
                String name = prop.getName();
                Method accessor = prop.getReadMethod();
                Method baseAccessor = null;
                if (clazz.getName().indexOf("$$EnhancerByCGLIB$$") > -1) {
                    try {
                        baseAccessor = Class.forName(
                                clazz.getName().substring(0, clazz.getName().indexOf("$$"))).getMethod(
                                accessor.getName(), accessor.getParameterTypes());
                    } catch (Exception ex) {
                        LOG.debug(ex.getMessage(), ex);
                    }
                } else if (clazz.getName().indexOf("$$_javassist") > -1) {
                	try {
                        baseAccessor = Class.forName(
                                clazz.getName().substring(0, clazz.getName().indexOf("_$$")))
                                .getMethod(accessor.getName(), accessor.getParameterTypes());
                    } catch (Exception ex) {
                        LOG.debug(ex.getMessage(), ex);
                    }
                } else
                    baseAccessor = accessor;

                if (baseAccessor != null) {

                    JSON json = baseAccessor.getAnnotation(JSON.class);
                    if (json != null) {
                        if (!json.serialize())
                            continue;
                        else if (json.name().length() > 0)
                            name = json.name();
                    }

                    // ignore "class" and others
                    if (this.shouldExcludeProperty(clazz, prop)) {
                        continue;
                    }
                    String expr = null;
                    if (this.buildExpr) {
                        expr = this.expandExpr(name);
                        if (this.shouldExcludeProperty(expr)) {
                            continue;
                        }
                        expr = this.setExprStack(expr);
                    }

                    Object value = accessor.invoke(object, new Object[0]);
                    boolean propertyPrinted = this.add(name, value, accessor, hasData);
                    hasData = hasData || propertyPrinted;
                    if (this.buildExpr) {
                        this.setExprStack(expr);
                    }
                }
            }

            // special-case handling for an Enumeration - include the name() as
            // a property */
            if (object instanceof Enum) {
                Object value = ((Enum) object).name();
                this.add("_name", value, object.getClass().getMethod("name"), hasData);
            }
        } catch (Exception e) {
            throw new JSONException(e);
        }

        this.add("}");
    }

在工作中也曾遇到一个问题,就是作为当然root对象的一个成员变量的父类,在一个public getXXX(可序列号的方法)会导致NPE,而一直抛出异常java.lang.reflect.InvocationTargetException导致困扰不短时间,就是没搞清楚这个时候的父类不会被忽略。还有一个问题就是同事在做用户权限时,基于RBAC的用户权限,在设计时子类和父类存在多对多的映射,导致在JSON转换时抛出异常,很明显这就是循环引用的问题。

 

 

 

2、接下来的excludeNullProperties指明了在root中(这里pageModule)如果有空值将被忽略,同时接下来的两个属性采用正则匹配排除root中的属性不进行json转化,而includeProperties则指明了包含的属性,默认会全部(当然如果excludeNullProperties=true对于为null或空值的属性不会进行JSON转化)。

如上面的一个配置,对于Action中的方法,那么最终的JSON为:

{"page":1,"totalCount":30}

 

 

3、上面是自己在使用时常用的几个参数,在JSONInterceptor类中还包含其他几个,这里介绍一二:

wrapWithComments:将JSON添加注释:/* {..json..}  */单并不推荐使用,在使用时需要eval(),可能会有XSS攻击

prefix: 生成前缀,如果设置为true,会在json加上前缀"{}&& "这有助于防止被劫持.

enableGZIP:压缩输出

前面说了JSON插件的基本配置,在JSONInterceptor中对root或json进行转换的是JSONUtil,主要是调用了

Object obj = JSONUtil.deserialize(request.getReader());


String json = JSONUtil.serialize(result, excludeProperties, includeProperties,
                        ignoreHierarchy, excludeNullProperties);

在JSONUtil中提供了JSON来对需要序列号的root进行设置:

   注释名                  说明                            默认值               
name                          配置JSONname                        ""
serialize 可序列化serialize true
deserialize 不进行序列号 true
format Date格式化 yyyy-MM-dd'T'HH:mm:ss

对上面的进行设置:

    @JSON(format="yyyy-MM-dd HH:mm:ss")
    public Date getCreateDay() {
        return createDay;
    }
[JSON]{"createDay":"2012-07-14 21:54:27","message":"Result","page":1,"totalCount":30}
 

 


分享到:
评论
1 楼 duqiangcise 2013-07-25  
,你是烧东吗?

相关推荐

    struts2-json-plugin-2.2.1.jar

    struts2自带的json转换 倒入jar文件 struts.xml中 &lt;package ......extends="json-default" &lt;result type="json"/&gt;

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

    结合这三个组件,开发者可以构建出响应式、动态的Web应用,后端使用Struts 2处理业务逻辑,通过JSON Plugin返回JSON数据,前端利用jQuery通过AJAX请求获取这些数据,然后动态更新页面,提高用户体验。这种前后端分离...

    (struts2-json-plugin-2.2.1)struts2 json-default配置中需要的jar包

    `struts2-json-plugin-2.2.1`这个版本的插件,意味着它是Struts2框架的2.2.1版本中的JSON支持。以下是这个插件正常工作所需的一些核心JAR文件: 1. **struts2-core.jar**:这是Struts2框架的基础,包含了所有核心的...

    struts-json.jar

    json-lib-2.2.1-jdk15.jar, ognl-2.7.3.jar, struts2-core-2.1.8.1.jar, struts2-json-plugin-2.2.1.jar, xwork-core-2.1.6.jar 避免版本不一致导致的问题,将我项目中所涉及的包上传分享以供下载~

    Struts2开发包struts2-blank-2.2.1

    此外,可能还有其他如`struts2-json-plugin.jar`、`struts2-dojo-plugin.jar`等插件,分别用于支持JSON响应和Dojo库的集成。 Struts2-blank-2.2.1版本是一个基础模板,它预设了基本的配置和目录结构,便于开发者...

    struts2-extended-jars

    struts-json-plugin-2.1.8.jar; xwork-core-2.1.6.jar; xwork-core-2.2.1.jar; commons-io-1.3.2.jar; freemarker-2.3.16.jar; ognl-2.7.3.jar; ognl-3.0.jar; commons-pool.jar; commons-fileupload-1.2.1.jar; ...

    struts2要使用json必须的两个包

    在Struts2中使用JSON,有两个关键的JAR包是必不可少的,这些正是`struts2-json-plugin-2.2.1.jar`和`json-lib-2.3-jdk15.jar`。 首先,`struts2-json-plugin-2.2.1.jar`是Struts2 JSON插件的实现库。这个插件为...

    struts2-2.2.1

    - **其他辅助库**:如ognl、xwork、struts2-convention、struts2-json-plugin等,用于提供特定的功能支持。 5. **安全方面**: Struts2-2.2.1版本可能已修复了一些安全漏洞,如著名的STRUTS2-2048漏洞,这要求...

    Struts2-2,2.1.1官方完整版jar包

    Struts2是一个非常著名的Java Web框架,它基于MVC(Model-View-Controller)设计模式,为开发者提供了构建可维护性、可扩展性极强的Web应用的强大工具。2.2.1.1是Struts2的一个较早版本,虽然在官网已经不太容易找到...

    Struts-2.2.1文档

    - `struts2-convention-plugin`:这个插件实现了约定优于配置的原则,可以自动映射Action和结果,减少了XML配置的工作量。 4. **表单验证**: - Struts 2 提供了基于XML和注解的表单验证机制,可以对用户输入进行...

    ssh json使用jar全

    在`struts2-json-plugin-2.2.1.jar`中,包含了Struts2对JSON的支持,允许我们在Action中返回JSON结果。 例如,要在Struts2 Action中返回JSON,你需要在Action类上添加`@Results`注解,指定一个JSON结果类型: ```...

    struts-2.2.1.1-all.rar

    Struts 2是Java Web开发中的一个开源框架,它基于MVC(Model-View-Controller)设计模式,为开发者提供了一种结构化和可扩展的方式来构建动态网站、Web应用程序和服务。Struts 2.2.1.1是该框架的一个特定版本,此...

    struts-2.2.1.1 jar文件

    - `struts2-json-plugin-x.x.x.jar`:JSON支持插件,使Struts2能够处理JSON请求和响应。 - `struts2-tiles-plugin-x.x.x.jar`:Tiles插件,集成Tiles框架,用于更复杂的页面布局。 - `struts2-spring-plugin-x.x.x....

    已配置好Struts2.2.1GA的WEB-INF

    Struts2.2.1GA的lib目录可能包括`struts2-core.jar`、`struts2-convention-plugin.jar`、`struts2-json-plugin.jar`等,这些库支持不同类型的请求和结果处理。 4. **classes**目录:通常存放编译后的Java类,包括...

    JSON、STRUCT2编程会用到的JAR包

    commons-fileupload-1.2.1.jar、commons-io-1.4.jar、commons-logging-1.0.4.jar、freemarker-2.3.8.jar、javassist-3.7.ga.jar、json-lib-2.2.1-jdk15.jar、ognl-2.6.11.jar、struts2-core-2.2.1.1.jar、struts2-...

    Struts2开发必备jar包

    6. **struts2-json-plugin.jar**:这个插件支持JSON(JavaScript Object Notation)数据格式的处理,使Struts2能够与AJAX和移动应用更好地交互。 7. **struts2-tiles-plugin.jar**:Tiles是一个视图集成框架,帮助...

    Struts2必不可少的5个jar包.rar

    Struts2是一个基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架,它...同时,Struts2还有许多其他可选的插件和库,如Struts2-dojo-plugin、Struts2-json-plugin等,它们为开发带来了更多的功能和便利。

    SSH整合类库分析spring3.0.4+hibernate3.5.5+struts2.2.1

    3. `struts2-json-plugin.jar`:支持JSON格式的数据交互,方便AJAX操作。 Hibernate的依赖包括: 1. `hibernate-core.jar`:Hibernate的主要实现,包含ORM的核心功能。 2. `hibernate-annotations.jar`:支持注解...

Global site tag (gtag.js) - Google Analytics