今天我真的很兴奋!在我的SSH项目中用jQuery的异步传输成功了,经过一天多的奋战,大工告成!

我的项目需求是在javascript中向我的controller(即:action)中传输form表单数据,传输到action的任意需要的方法中,处理完结果在返回给jQuery,显示出来。

在其中,我遇到了好多问题(初次使用),但是呢,都慢慢的解决了!下面看一下我的项目:

1、首先在jsp页面中我写了javascript,如下:

 <script type="text/javascript" src="./js/jquery-1.10.2.js"></script>
<script type="text/javascript">
function mySearch(){
var queryStr = "";
var mydata = $("#myform").serialize();
var url = "cwgl_searchByConditions";
$.post(url,mydata,searchListCallBackFun,'json');
};
function searchListCallBackFun(data){
alert("进入回调函数");
alert(data.gshts);
$.each(data.gshts,function(index,gsht){
$("#gsht").append(
"<tr><td>" + gsht.gsmc + "</td><td>" + gsht.dabh + "</td><td>"
+ gsht.gshtbh + "</td><td>" + gsht.kh.khxm + "</td><td>"
+ gsht.kh.qc + "</td><td>" + gsht.khjhhkje + "</tr>"
);
});
};

在这里我是用的是jQuery的serialize()对我的表单进行序列化,形成形如{}的数据传输给action,之后struts2能够很好的识别这种数据类型并转化为对应的对象,这个不需要我们考虑,接下来是对action处理结果的返回,返回数据时我也遇到了很多问题,如:Class org.apache.struts2.json.JSONWriter can not access a member of class org.hibernate.persister.entity.AbstractEntityPersister$3 with modifiers "public";

这个问题是由于在我的action中有这样的数据:private CwglService cwglService;这个接口是在Spring的管理下的,json无法取得,但是,我们也不需要这个接口,我所需要的只是返回的数据!因此在我的struts.xml配置里有了这样的配置:<param name="excludeProperties">cwglService</param>排除接口。

另外的一个问题是:org.apache.struts2.json.JSONException: java.lang.reflect.InvocationTargetException是Hibernate的懒加载引起的。一定是你传递的数据中有引用类型的数据采用了懒加载机制,这个问题待会在下面有我看到的,觉得比较好,粘在了下面;

在我的struts.xml配置如下:

 <package name="default" extends="struts-default,json-default">
<action name="cwgl_*" class="com.action.CwglAction" method="{1}">
<result name="ajysgl_lb" type="json">
<param name="excludeProperties">cwglService</param>
<param name="ignoreHierarchy">false</param>
<param name="excludeNullProperties">true</param>
</result>
</action>
</package>

之后就可以自如的使用jQuery与action的交互了!

处理问题时,见到比较好的解释copy如下:

在ssh和ajax结合实现异步传输时,经常会出现的一个问题是,json格式的数据从后台传递到页面后无法解析,下面的data即是回调函数中参数,在页面断点后会看到data接收到的是下面一堆数据,其实是异常信息。

------------------------------------------------------------------------------------------

data
"<html>
<head>
    <title>Struts Problem Report</title>
    <style>
     pre {
      margin: 0;
         padding: 0;
     }    
    </style>
</head>
<body>
    <h2>Struts Problem Report</h2>
    <p>
    Struts has detected an unhandled exception:
    </p>
<div id="exception-info">
<table>
    <tr>
        <td><strong>Messages</strong>:</td>
        <td>
            <ol>
                        <li>Positioned Update not supported.</li>
                        <li>java.lang.reflect.InvocationTargetException</li>
                        <li>org.apache.struts2.json.JSONException: java.lang.reflect.InvocationTargetException</li>
                        <li>org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException:java.lang.reflect.InvocationTargetException</li>
                        <li>org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: java.lang.reflect.InvocationTargetException</li>
            </ol>
        </td>
    </tr>
    <tr>
        <td><strong>File</strong>:</td>
        <td>com/mysql/jdbc/SQLError.java</td>
    </tr>
    <tr>
        <td><strong>Line number</strong>:</td>
        <td>1,055</td>
    </tr>    
</table>
</div>
<div id="stacktraces">
<hr />
<h3>Stacktraces</h3>
<div class="stacktrace" style="padding-left: 0em">
    <strong>org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: java.lang.reflect.InvocationTargetException</strong>
    <div>
    <pre>
    org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:243)
    org.apache.struts2.json.JSONWriter.process(JSONWriter.java:165)
    org.apache.struts2.json.JSONWriter.value(JSONWriter.java:131)
    org.apache.struts2.json.JSONWriter.write(JSONWriter.java:99)
    org.apache.struts2.json.JSONUtil.serialize(JSONUtil.java:112)
    org.apache.struts2.json.JSONResult.execute(JSONResult.java:198)    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:362)    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:266)    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:165)    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)        org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:235)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:488)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Unknown Source)
    </pre>
    </div>
</div>

------------------------------------------------------------------------------------------

那么,为什么会出现这个异常呢?

究其原因,竟然是Hibernate的懒加载引起的。一定是你传递的数据中有引用类型的数据采用了懒加载机制。

比如:我要从Action中向前台传送一个Collection<Menuitem>,通过get方法

public Collection<Menuitem> getMenuitemList() {
  return this.menuitemList;
 }

而其中Menuitem类型的数据结构是:

public class Menuitem {
 private Long mid;
 private Long pid;//父节点
 private String name;//树的节点的名称
 private Boolean isParent;//是否为父节点
 private String icon;//图标的路径
 private Boolean checked;//复选框是否被选中
 /**
  * 菜单权限与用户是多对多的关系
  */
 private Set<User> users;

//getter(),setter()方法

}

在映射文件Menuitem.hbm.xml中users属性的配置如下:

<set name="users" table="user_menuitem" inverse="true">
         <key column="mid"></key>
         <many-to-many column="uid" class="cn.myoa.domain.User"></many-to-many>
</set>

未设置lazy="false",则默认采用懒加载模式。

当中间表user_menuitem中没有数据时,ok,不会牵涉到use表,也就不存在懒加载问题,运行一切正常。

但是当user_menuitem表中有数据,且数据与所传送的Menuitem对象有关时,就会有问题了

因为懒加载,这样在Action中获取的Menuitem对象中的users属性中的set集合中会存在user对象的引用,但是user的信息其实并未加载,

只有当用到时,容器才再次发出sql请求进行加载,但是在json插件对menuitemList进行处理以转换成json格式时,Hibernate Session早已关闭,这样user信息便加载不成功,而它又无法对set集合中空的引用进行处理,所以便抛出了JSONException。

有人可能会有疑问,我在web.xml中配置了OpenSessionInViewFilter过滤器,为什么Session还会关闭呢!?

这个疑问问的好!!我也不知何故,在网上也没找到相关的解释,不知是不是ajax的XMLHttpRequest的问题,

总之,在struts2与ajax结合的过程中,OpenSessionInView模式不起作用了!请知道的朋友不吝赐教!

好!既然知道了问题的原因,那么解决方法就很明了了!

方法一:设置lazy="false",即对user不采用懒加载。如

<set name="users" table="user_menuitem" inverse="true"lazy="false">
         <key column="mid"></key>
         <many-to-many column="uid" class="cn.myoa.domain.User"></many-to-many>
         </set>

不过这时要注意在User对象中有没有其他对象的引用,用过有,也要设置为非懒加载模式。

方法二:忽略set<User> users 属性,(推荐使用)

如果在前台页面不需要使用该属性的话,就不要把他传到前台去,设置方法是在其getter方法上加一注解: @JSON(serialize=false)

@JSON(serialize=false)
          public Set<User> getUsers() {
                  return users;
          }

这样json插件在转换数据时就会忽略该属性。

现在问题应该已经解决了!!

下面关于struts2和ajax的结合还有几点建议:

1、在页面用不到的数据最好不要传到前台(这也是之所以推荐第二种方法的原因,传的数据越大,效率越低不是吗!)

2、不是向前台传数据的方法最好不要以get开头,json插件会把所有get开头的方法当做属性,转为json格式数据

3、如果方法必须以get开头,然而又不是为了转为json格式,那么可以在该方法上加注解:@JSON(serialize=false)

4、需要传到前台的数据,一定要在dao中加载完毕,不能使用懒加载模式。

SSH里面使用jQuery的ajax的更多相关文章

  1. jquery中ajax的使用

    Java软件开发中,后台中我们可以通过各种框架,像SSH等进行对代码的封装,方便我们对Java代码的编写,例如,Struts,SpringMVC对从前台到action的流程进行封装控制,使我们只需要进 ...

  2. 使用JSONP,jQuery的ajax跨域获取json数据

    网上找了很多资料,写的不错,推荐下: 1.深入浅出JSONP--解决ajax跨域问题 (http://www.cnblogs.com/chopper/archive/2012/03/24/240394 ...

  3. jQuery之ajax实现篇

    jQuery的ajax方法非常好用,这么好的东西,你想拥有一个属于自己的ajax么?接下来,我们来自己做一个简单的ajax吧. 实现功能 由于jq中的ajax方法是用了内置的deferred模块,是P ...

  4. 【原创经验分享】JQuery(Ajax)调用WCF服务

    最近在学习这个WCF,由于刚开始学 不久,发现网上的一些WCF教程都比较简单,感觉功能跟WebService没什么特别大的区别,但是看网上的介绍,就说WCF比WebService牛逼多少多少,反正我刚 ...

  5. jQuery版AJAX简易封装

    开发过程中,AJAX的应用应该说非常频繁,当然,jQuery的AJAX函数已经非常好用,但是小编还是稍微整理下,方便不同需求下,可以简化输入参数,下面是实例代码: $(function(){ /** ...

  6. JS原生ajax与Jquery插件ajax深入学习

    序言: 近来随着项目的上线实施,稍微有点空闲,闲暇之时偶然发现之前写的关于javascript原生xmlHttpRequest ajax方法以及后来jquery插件ajax方法,于是就行了一些总结,因 ...

  7. 重写jquery的ajax方法

    //首先备份下jquery的ajax方法 var _ajax=$.ajax; //重写jquery的ajax方法 $.ajax=function(opt){ //备份opt中error和success ...

  8. Jquery通过Ajax方式来提交Form表单

    今天刚好看到Jquery的ajax提交数据到服务器的方法,原文是: 保存数据到服务器,成功时显示信息. jQuery 代码: $.ajax({ type: "POST", url: ...

  9. 对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache

    虽然jquery的较新的api已经很好用了, 但是在实际工作还是有做二次封装的必要,好处有:1,二次封装后的API更加简洁,更符合个人的使用习惯:2,可以对ajax操作做一些统一处理,比如追加随机数或 ...

随机推荐

  1. MVC分页控件

    1.下载MvcPager.dll文件并引用到MVC项目中 2.在控制器中引用命名空间using Webdiyer.WebControls.Mvc; 3.获取数据集合,数据的总记录数(数据集合有多少条数 ...

  2. Flume使用说明

    关于Flume,官方定义如下: Apache Flume is a distributed, reliable, and available system for efficiently collec ...

  3. ABP文档 - Quartz 集成

    文档目录 本节内容: 简介 安装 创建工作 调度工作 更多 简介 Quartz 是一个功能完整的开源工作调度系统,可用于最小的应用到一个大型的企业系统.Abp.Quartz 包简单地把Quartz集成 ...

  4. Input file 文本框美化

    HTML原生的input file 上传按钮有多(无)不(力)漂(吐)亮(槽)我就不多说了.大家几乎在项目中都会有遇到图片.等文件需要上传的地方,好看的文件上传按钮会使人身心愉悦(我瞎说的).好了不多 ...

  5. 《C++ Primer》读书笔记—第二章 变量和基本类型

    声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程. 1.8比特的char类型计算机表示的实际范围是-12 ...

  6. Unity3d中如何混用三种脚本语言?

    首先要明白,这三种说的混用是指文件级别的混用,就是说一个文件是由一种语言写的.而不是说你这一个文件可以混用这三种语言,注意这是不允许的. 第二要明白,在unity3d中为什么可以使用三种语言混合开发? ...

  7. Android 退出多Activity的application的方式

    在开发过程中,我们常常需要一个退出功能,来退出该应用的所有Activity.下面,我们列举一些退出应用的几种方式.以下用的源码点击查看源码地址 欢迎star,欢迎fork 利用ActivityCont ...

  8. ubuntu16.04下安装配置深度学习环境(一、cuda7.5的安装)

    1.下载所需要的软件 cuda7.5下载(点击下载链接),cudnn4.0下载 2.安装NVIDIA驱动. 一般有两种方法:1)一种方法是利用"软件和更新"来安装,依次选择 系统设 ...

  9. ZOJ 1492 Maximum Clique 搜索最大团

    ZOJ1492 题意:给一个无向图 求最大团的大小.节点数小于50 数据有限,考虑记忆化搜索,方程很好给出. 令 Si={vi,vi+1.....vn} mc[i]表示Si最大团的大小,倒着推算. 必 ...

  10. Java基本数据类型及其封装器的一些千丝万缕的纠葛

    一些概念     想必大家都知道Java的基础数据类型有:char.byte.short.int.long.float.double.boolean 这几种,与C/C++等语言不同的是,Java的基础 ...