论坛首页 Web前端技术论坛

基于Ajax和JSON从javascript中调用后台java方法的JsonGateway

浏览 8343 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-22  
    JsonGateway是一个java远程服务调用的ajax的接口,它使用Json数据格式在页面上的javascript和后台的java服务之间进行数据交换。目前它可以调用spring的service,当然也可以调用普通的java类方法。jsonGateway可以自动生成所配置的java类的javascript包装类,这将使你能够轻松进行ajax远程调用。jsonGateway使用了JQuery来进行远程调用,同时在服务端使用了jsontools进行json数据格式的转换。

你可以在Sorceforge上下载 http://sourceforge.net/project/showfiles.php?group_id=188794

使用方法:

如果后台我们使用了Spring,那么调用Spring中配置的Service Bean的方法的方式为


  配置JsonGateway的Servlet:  在web.xml中, 增加
    <servlet>
        <description>json gateway</description>
        <display-name>json gateway servlet</display-name>
        <servlet-name>json-gateway</servlet-name>
        <servlet-class>org.svilo.spring.json.JsonGatewayServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>json-gateway</servlet-name>
        <url-pattern>/json/*</url-pattern>
    </servlet-mapping>

在html、jsp页面中,引入如下的javascript:
  <script type="text/javascript" src="/js/jquery.js"></script>
  <script type="text/javascript" src="/js/json.js"></script>
  <script type="text/javascript" src="/js/moo.js"></script>
  <script type="text/javascript" src="/js/jsonGateway.js"></script>

同时也需要引入自动生成的服务代理Javascript:

   如果你有一个Spring的服务bean叫做'CustomerMgrService',那么在你的html中,增加如下几行代码:

   <script type="text/javascript"src="/json/CustomerMgrService.js"></script>   //the CustomerMgrService.js is generated by the JsonGateway

具体在javascript中的使用方法如下:

function testService(){

     var callerResponder = new CallerResponder(); //这是ajax的响应回调的封装类
     callerResponder.success = function(jsonObj) {  //当调用后台方法成功时的回调函数
         var customer = jsonObj;      
         alert(customer.brandName);
       
         alert(this.context.name);     //this will display 'wuyu'  //我们在调用某个后台服务方法前,设置到CallerResponder上下文中的一些变量,在成功回调函数中,可以通过上下文取出来使用
         alert(this.context.age);     //this will display '30'
         var str = jQuery.toJSON(customer); 
         var msg = "ajax success: " + str;     
         alert(msg);     
        }

     callerResponder.error = function(request,settings,e) {  //failure callback function, you may not implement it

//调用后台方法出错的回调函数
         if (request.status == 500) {
            var jsonError = jQuery.parseJSON(request.responseText);
         }
        if (this.debug ) {
            alert("ajax error: " + request.responseText);
            alert(e);
        }
     }

    callerResponder.context.name = "wuyu";  //set the data which you will access in callback function 向callerResponder的上下文中设置一些需要在回调函数中访问的数据

    callerResponder.context.age = "30";


     var customerMgrService = new CustomerMgrService(); //新创建一个远程服务包装的javascript对象
     var tagMgrService = new TagMgrService();
     var strCustomerId = jQuery("#customerId").val();
     //调用后台服务方法
     customerMgrService.findByCustomerId(strCustomerId,callerResponder);  // 后台的spring配置中名字叫 CustomerMgrService的Bean有一个'public Customer findByCustomerId(String customerId)'方法,所以我们在这里可以调用它,它在后台方法中只有customerId这个参数,在这里,我们在调用时方法参数的最后面增加了一个callerResponder的参数。
}



下载包中的代码缺省只能是调用Spring中配置的服务bean的方法,但是在没有使用spring的程序中,我们也要使用的话,可以修改JsonGatewayServlet.java

public class JsonGatewayServlet extends HttpServlet {

    private static Properties services;

    public void init() throws ServletException {
         super.init();
         services = new Properties();
         InputStream in =JsonGatewayServlet.class.getClassLoader().getResourceAsStream("services.properties");
         try{
             services.load(in);
         }catch( Exception e){
             e.printStackTrace();
         }
   }
增加一个名字叫做services.properties的服务配置文件,该文件中写上服务名称和对应java类的映射关系,比如:
BranchByArea=com.keygate.adbidplatform.common.service.BranchByArea



最后再修改一下JsonGatewayServlet的getService方法,直接从我们的配置文件中读取服务的配置即可。

private Object getService(HttpServletRequest request,String serviceName) throws Exception {
//  WebApplicationContext webappCtx = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
//  Object service = webappCtx.getBean(serviceName);
        Object service = Class.forName((String)services.get(serviceName)).newInstance();
        if (service == null)
  {
   Exception e = new Exception("can not find the service: " + serviceName);
   throw e;
  }
  return service;
}



呵呵,自己编写的这个JsonGateway虽然不是很强大,但是想要从javascript中调用java后台方法已经足够了,同时参数的传递也很对象化。配合jquery使用,感觉不错。
   发表时间:2007-06-22  
用json有几个大缺点:
1 是不能直接处理对象图,如果有循环引用,jQuery.toJSON就会挂掉
2 object只是map而已,不直接含有类信息,不容易和java中的类层次对应上
这两个都是致命缺点
建议看看Objot库,很好地解决了这问题。还有PHPRPC,Buffalo,都避免了json的问题。前面有帖子讨论

如果用基础的库来做这种客户端对服务器的调用,那这个库的核心就要足够强大。如果只是直接基于json而没有做额外处理,那么就等于把职责推给程序员,当项目需要传递对象图、类信息时,还是痛苦
0 请登录后投票
   发表时间:2007-06-22  
本来json比较适用传数据,如果要传对象图,可以做稍许转换。例如考虑xml怎么保存它。其实就类似sql的外键那样。
类信息跟语言关联太深,如果是简单类型,那稍作转换也可。
0 请登录后投票
   发表时间:2007-06-22  
考虑用 xml 保存它,是谁来考虑?应用开发程序员还是类库开发程序员?如birdjavaeye所说,如果把这个责任推给应用开发程序员的话,做项目是就太痛苦了。所以,还是把这些封装到类库中去,使用时,以 RPC 方式调用最方便。
0 请登录后投票
   发表时间:2007-06-23  
对2楼疑问的回复:
1、是不能直接处理对象图,如果有循环引用,jQuery.toJSON就会挂掉
这个是因为jQuery.toJSON的这个方法有缺陷,我放上去的代码是已经修正过这个问题的。

2、object只是map而已,不直接含有类信息,不容易和java中的类层次对应上
这个当然是用了些技巧,所以也不存在你说的问题。

我写的这个jsongateway不需要程序员来把什么类的信息写在javascript 的object中,想想dwr都怎么用的,jsongateway同样是这样简单。只需要按照说明正常使用即可。程序员只需要愉快的调用自动生成的后台服务的javascript包装类,即可达到调用后台服务方法的目的。这点和flex2差不多。
0 请登录后投票
   发表时间:2007-06-23  
andot 写道
考虑用 xml 保存它,是谁来考虑?应用开发程序员还是类库开发程序员?如birdjavaeye所说,如果把这个责任推给应用开发程序员的话,做项目是就太痛苦了。所以,还是把这些封装到类库中去,使用时,以 RPC 方式调用最方便。


我的意思是考虑如果用xml怎么保存,也就是用一个属性(IDREF)来指向对象。并不是说一定要用xml。我是说借鉴xml表达,或者sql表达的方法——即通过一个primitive的id属性来关联。

不过话说回来,如果中间是使用xml而不是json的话,也是一种方式。比如我就比较喜欢在中间使用xml。在什么情况下适用xml?我认为如果你需要一个独立的协议描述的话,可以考虑用xml。xml的好处有几个:
1. 表达能力丰富,可以描述复杂的业务数据
2. xml数据源适合更广泛的场合,互操作性较好,例如cs结构的程序、企业系统之间的交互、手机应用等;相对而言,json和其他格式不是说不能这样使用,但是确实主要局限于web网站。
3. 处理方法标准化化,有很多在各种平台上都可用的工具(sax,dom,xslt等等)。


如果仅仅是程序内部的信息传递,当然我们不希望应用开发程序员为此操心。反过来,某些场合,是需要对通讯协议做仔细设计的,那可以说不仅是应用开发程序员的责任,而且是业务人员的责任。
0 请登录后投票
   发表时间:2007-06-25  
西风吹雨 写道

我写的这个jsongateway不需要程序员来把什么类的信息写在javascript 的object中,想想dwr都怎么用的,jsongateway同样是这样简单。只需要按照说明正常使用即可。程序员只需要愉快的调用自动生成的后台服务的javascript包装类,即可达到调用后台服务方法的目的。这点和flex2差不多。

dwr在这个方面和json一样,以它为起点做对比,还是有点不足。
以简单的方式调用后台服务确实是必要的,只不过库能多做点,程序员就能轻松点
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics