• SSH里面使用jQuery的ajax


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

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

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

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

     1 <script type="text/javascript" src="./js/jquery-1.10.2.js"></script>
     2 <script type="text/javascript">
     3 function mySearch(){
     4     var queryStr = "";
     5     var mydata = $("#myform").serialize();
     6     var url = "cwgl_searchByConditions";
     7     $.post(url,mydata,searchListCallBackFun,'json');
     8 };
     9 function searchListCallBackFun(data){
    10     alert("进入回调函数");
    11     alert(data.gshts);
    12     $.each(data.gshts,function(index,gsht){
    13         $("#gsht").append(
    14                 "<tr><td>" + gsht.gsmc + "</td><td>" + gsht.dabh + "</td><td>" 
    15                 + gsht.gshtbh + "</td><td>" + gsht.kh.khxm + "</td><td>"
    16                 + gsht.kh.qc + "</td><td>" + gsht.khjhhkje + "</tr>"
    17         );
    18     });
    19 };
    View Code

    在这里我是用的是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配置如下:

    1 <package name="default" extends="struts-default,json-default">
    2     <action name="cwgl_*" class="com.action.CwglAction" method="{1}">
    3         <result name="ajysgl_lb" type="json">
    4             <param name="excludeProperties">cwglService</param>
    5                <param name="ignoreHierarchy">false</param>
    6                <param name="excludeNullProperties">true</param>
    7         </result>
    8     </action>
    9 </package>
    View Code

    之后就可以自如的使用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中加载完毕,不能使用懒加载模式。

    我很小我很弱,我在慢慢成长!
  • 相关阅读:
    偏最小二乘法回归(Partial Least Squares Regression)
    今天就来聊聊产品运营
    VS2005终于不“变态”了!
    Android 里的对话框Dialog 实现机制基础
    C#多线程操作界面控件的解决方案
    转C++ ,C#数据类型对照
    关于Linq to sql 应用时出现的一个‘row not found or changed’ 异常
    Android之Context Memu
    HttpModule的认识
    Docker:官网文档 Get Started 笔记
  • 原文地址:https://www.cnblogs.com/lvzhanhui/p/xiaoqiaolv_ajax_jquery.html
Copyright © 2020-2023  润新知