jsp向EXTJS返回json格式数据

来源:互联网 发布:linux确认删除文件指令 编辑:程序博客网 时间:2024/05/16 11:43

 今天在做一个工作,即jsp想mysql中查询数据后,以json格式返回到客户端(Extjs)中。

 下面是解决方法和遇到的问题及解决。

 

      jsp查询mysql昨天已说明,今天着重讨论返回json。

      首先,使用JavaBean,让它负责生成json格式(这里做的只是关系数据的二元关系,json格式可以确定),在jsp里调用并传入参数即可,类似其他的第三方库。该JavaBean的源代码如下:
 
package com.jj.database.util;
import java.util.ArrayList;
public class Json {
 public static void main(String[] args) {
//  System.out.println("gernerating json.");
    } 
   
    public String singleInfo="";
    protected boolean _success=true;
    protected String _error="";
    protected ArrayList arrData=new ArrayList();
    protected ArrayList dataItem=new ArrayList();
    public String getError() {
        return _error;
    }
    public void setError(String error) {
        if(!error.equals(""))this._success=false;
        this._error = error;
    }
    public boolean getSuccess() {
        return _success;
    }
    public void setSuccess(boolean success) {
        if(success) this._error="";
        this._success = success;
    }
   
    public Json()
    {
       
    }
   
    public void reSet()
    {
        arrData.clear();
        dataItem.clear();
    }
   
    public void addItem(String name,String _value)
    {
        dataItem.add(name);
        dataItem.add(_value);
    }
   
    //一个数组添加完毕,一个新的数组开始
    public void addItemOk()
    {
        arrData.add(dataItem);
        dataItem=new ArrayList();
    }
   
    public String ToString()
    {
        StringBuilder sb=new StringBuilder();
        sb.append("{");
        sb.append("/"datas/":");
        sb.append("[");
        int ad=arrData.size();
        for(int i=0;i<ad;i++)
        {
            ArrayList arr=(ArrayList)(arrData.get(i));
            sb.append("{");
            int t=arr.size();
            for(int j=0;j<t;j+=2)
            {
                if(j==t) break;
                sb.append("/'");
                sb.append(arr.get(j).toString());
                sb.append("/'");
                sb.append(":");
                sb.append("/'");
                sb.append(arr.get(j+1).toString());
                sb.append("/'");
                if(j<t-2) sb.append(",");
            }
            sb.append("}");
            if(i<ad-1) sb.append(",");
        }
        sb.append("]");
        sb.append("}");
        return sb.toString();
    }
    
 }

      遇到的问题是:将JavaBean源文件编译后,把class文件放在同一目录下。在jsp文件中使用<%@page import ="com.jj.database.util.Json"%>时,无法正确引入JavaBean,报错:
org.apache.jasper.JasperException: Exception in JSP:.......................
参考很久。大致的解决方法有:
      1)将<%javahome%>/lib/tools.jar拷贝到<%tomcat_home%>/common/lib下,然后重启tomcat。
      2)在系统环境变量CLASSPATH中加入tools.jar的路径。
      但1),2)在我机子上都没效果。
      3)我的解决方案:
      我的机子上的目录如下(<%tomcat_home%>下);
      webapps
           ROOT
                myjsp
                      index.jsp
                web-inf
                      classes
                            com
      我将jsp页面放在myjsp中,然后把编译后的com包(包含class文件)拷贝到上面的目录的class下。最后重启tomcat。
 
      然后在jsp中使用下面语句来引用这个JavaBean,<jsp:directive.page import="com.jj.database.util.Json"/>,当然也可以直接使用<%@page import ="com.jj.database.util.Json" %>,即可正确载入
      接下来jsp即可正常引用这个JavaBean,完成生成一个json格式字符串。下面是实例代码(rs是使用mysql查询的结果集):
    Json json=new Json();
    json.reSet();
    json.setSuccess(true);
        while(rs.next())
    {
        json.addItem("provinceid",(new Integer(rs.getInt(1))).toString());
  
        json.addItem("provincename",rs.getString(2));
        json.addItemOk();
    }
     out.print(json.ToString());
  
    下面又遇到了问题,即当客户端向jsp请求数据是,使用上述页面产生结果。而在客户端extjs无法解析。使用firebug调试可看出(或看页面源代码),使用上述的方法返回的数据格式如下:
json-data(/r/n    /r/n  </body>/r/n</html>/r/n)。
    
      弄了很长时间,终于发现原因了。原来是jsp页面的结构。如果你在jsp里添加了html页面的标签,那么在响应客户端请求时产生一个与jsp同构的html页面,它里面除了包含out.print输出的数据外,还有jsp本身的html结构,这给客户端解析带来麻烦。我的页面最后正好是:
<%
  //jsp code, to output json data
%>
   
  </body>
</html>
恰好是上面的json数据后面的28个字符。
解决的方法时去掉jsp中的html标签即可,这时即产生完整的json格式数据。
     然后使用js中的eval函数,将接收到的json字符串转化为json对象,格式如下(设该字符串是str),
     var jsondata = eval('('+str+')'),直接把str作为参数不行。这里jsondata就是一个json对象,你可以使用它或任意引用它里面的数据。以我这里的数据为例:
     str ={datas:[{'provinceid':'1','provincename':'beijing'},{'provinceid':'2','provincename':'shanghai'}]} 
     转化后可以引用jsondata.datas[0].provinceid等,也可以直接把jsondata作为jsonStore的data参数,然后按照它的结构设计一个jsonReader即可。
下面的截图即为今天的成果
 <无法显示>
下面仍有很长的路要走,继续努力。
参考
1 http://www.gold98.net/blog/article.asp?id=676
2 http://www.cnitblog.com/yemoo/archive/2009/07/12/34526.html