关于一个错误,JSONException
JSONException 和$.post
关于一个错误:JSONException
1、错误的原因
1、
在action中存在一个属性
private Collection<Menuitem> privilegeList;
并且该属性有
public Collection<Menuitem> getPrivilegeList() {
return privilegeList;
}
struts2-json-plugin插件中就把上述的属性转化成json格式的对象返回到客户端 该转化是一个深度转化
public class Menuitem{
private Set<User> users;
}
不仅要转化menuitem,还要转化users,在转化users时,必须保证users的数据提取出来
2、当在dao层,发出一个hql语句"from Menuitem",这样可以把menuitem中的所有的数据加载出来,但是针对Set<User>是懒加载
集合中的user的数据并没有加载出来
综述原因会包JSONException的异常
2、解决方案
1、因为users的数据没有提取出来,所以不加载users
@JSON(serialize=false)
public Set<User> getUsers() {
return users;
}
2、利用迫切左外连接,在加载menuitem的时候,把user加载出来,但是必须把user中所有的引用属性设置为null,这样
menuitem和user就一起加载出来了
----
想获取
Action:
public String showPrivileges() throws Exception{
this.privilegeList = this.privilegeService.getMenuitemsByUid(this.uid);
for(Menuitem menuitem:this.privilegeList){
Set<User> users = menuitem.getUsers();
for(User user:users){
user.setDepartment(null);
user.setPosts(null);
user.setMenuitems(null);
}
}
Thread.sleep(1000);
return SUCCESS;
}
Dao:
@Repository("privilegeDao")
public class PrivilegeDaoImpl extends CommonDaoImpl<Menuitem> implements PrivilegeDao<Menuitem>{ @Override
public Set<Menuitem> getMenuitemsByIds(String ids) {
// 这里要使用连接将其加载出来,但是如果前台作为这个的属性还是会报JSONException,所以还是需要将这个属性设置为null;
return new HashSet<Menuitem>(this.hibernateTemplate.find("from Menuitem m left outer join fetch m.users u where m.mid in("+ids+")"));
} @Override
public Collection<Menuitem> getMenuitemsByUid(Long uid) {
/**
* 1、加载所有的权限节点
* 2、把用户能够访问到的节点也加载出来
* 3、把所有的权限节点中用户能够访问到的节点的checked设置为true
*/
//所有的菜单树
Collection<Menuitem> allMenuitems = this.hibernateTemplate.find("from Menuitem");
//用户能够访问到的菜单
Collection<Menuitem> userMenuitems = this.hibernateTemplate.find("from Menuitem m inner join fetch m.users u where u.uid=?",uid);
for(Menuitem menuitem:allMenuitems){
for(Menuitem menuitem2:userMenuitems){
//判断所有的菜单树中是否有用户能够访问到的菜单
if(menuitem2.getMid().longValue()==menuitem.getMid().longValue()){//正在遍历的菜单项是用户能够访问到的菜单
menuitem.setChecked(true);
}
}
}
return allMenuitems;
}
} 上面的方式就可以将user提取出来,就是将user里面的属性设置为null;
利用迫切左外连接,在加载menuitem的时候,把user加载出来,但是必须把user中所有的引用属性设置为null,这样menuitem和user就一起加载出来了;
因为引用对象之间的加载都是懒加载;================================================
4、$.post
1、回调函数是在服务器成功相应的时候执行的,是异步的过程
2、$.post只能读取服务器成功响应的信息
3、重构$.post添加错误处理功能
1、建立struts2统一的错误处理机制
<package name="ajax-error" namespace="/" extends="json-default">
<global-results>
<result name="errHandler" type="chain">
<param name="actionName">errorProcessor</param>
</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception"
result="errHandler" />
</global-exception-mappings> <action name="errorProcessor" class="com.itheima03.oa.exception.AjaxErrorProcess">
<result type="json"></result>
</action>
</package>
2、在错误处理的类中
public class AjaxErrorProcess extends ActionSupport{
private String message = "";
public String getMessage() {
return message;
} private Exception exception;
public Exception getException() {
return exception;
} public void setException(Exception exception) {
this.exception = exception;
} public String execute() {
/**
* 修改状态码
* 客户端就能感应到服务器端产生异常
*/
ServletActionContext.getResponse().setStatus(404);
this.message = exception.getMessage();
return SUCCESS;
}
}
说明:
message如果有空,没有异常信息,如果不为空,则有异常信息
3、$.post方法的重构
(function($){
$.oapost = function(postJSON){
$.post(postJSON.url, postJSON.data, function(data){
if(data.message==""){
postJSON.callback(data);
}else{//处理错误信息
alert(data.message);
}
});
}
})($);
这样写的好处是:在一处处理了错误信息,如果想改,则修改这一个地方即可