今天项目遇到了一个问题, 本地没有问题, 但是一放到服务器上 ,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) 就可以了