关于 struts2-json-plugin 报错

文章详细介绍了如何通过在Struts2配置文件中设置root属性和使用@JSON(serialize=false)注解来解决JSON序列化过程中出现的非法访问异常问题。通过在实体类中对特定属性进行排除,避免了序列化冲突。
摘要由CSDN通过智能技术生成

今天项目遇到了一个问题, 本地没有问题, 但是一放到服务器上 ,ajax 请求就一直报错:

Caused by: java.lang.IllegalAccessException: Class org.apache.struts2.json.JSONWriter can not access a member of class org.hibernate.cfg.annotations.PropertyBinder$NoValueGeneration with modifiers "public" 

网上查了一下, 说是返回的 json 数据中有问题, 解决方法

一. 在 struts.xml 中配置 root 属性, 

<package name="super_admin" extends="json-default" namespace="/superadmin">
         <action name="allAuthorities" class="edu.bjfu.action.AuthoritiesAction">
             <result type="json"><param name="root">authorities</param></result>
         </action>
     </package>

二. 对于不需要 json 序列化的属性加上 @JSON(serialize=false),  表示不序列化, 这个有可能是 action 中的属性, 也有可能是返回到页面上的数据中(即实体)的属性,


但是我不确定是哪个实体中的属性不能序列化, 只能采用一个笨方法, 找到 JSONWriter  的源码, 在这些地方加上输出信息

protected void bean(Object object) throws JSONException {
        this.add("{");

        BeanInfo info;
        System.out.println("start=====================>"+object.getClass());
        try {
            Class clazz = object.getClass();

            info = ((object == this.root) && this.ignoreHierarchy)
                    ? getBeanInfoIgnoreHierarchy(clazz)
                    : getBeanInfo(clazz);
            System.out.println("-------------获取 props 前--------");
            PropertyDescriptor[] props = info.getPropertyDescriptors();
            System.out.println("-------------获取 props 后--------");
            boolean hasData = false;
            for (PropertyDescriptor prop : props) {
                String name = prop.getName();
                System.out.println("name=============>"+name);
                Method accessor = prop.getReadMethod();
                Method baseAccessor = findBaseAccessor(clazz, accessor);

                if (baseAccessor != null) {
                    if (baseAccessor.isAnnotationPresent(JSON.class)) {
                        JSONAnnotationFinder jsonFinder = new JSONAnnotationFinder(baseAccessor).invoke();
                        if (!jsonFinder.shouldSerialize()) continue;
                        if (jsonFinder.getName() != null) {
                            name = jsonFinder.getName();
                        }
                    }
                    // ignore "class" and others
                    if (this.shouldExcludeProperty(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);
                    if (baseAccessor.isAnnotationPresent(JSONFieldBridge.class)) {
                        value = getBridgedValue(baseAccessor, value);
                    }

                    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) {
        	System.out.println("catch exception=====================>"+object.getClass());
            throw new JSONException(e);
        }

        this.add("}");
    }

根据抛出异常的最后一个实体从下往上查找, 一步一步尝试

我碰到的问题用第一种方法没有解决, 用的是第二种方式.  即我返回的实体中有一个关联对象 User, 我在他的 get 方法上加上 @JSON(serialize=false) 就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值