狂奔 lion

自强不息

JSON通用服务端处理

最近在学习JavaScript,发现不论是ext还是prototype都很推崇json这种通信协议的格式,但是这两个框架都是比较偏前端的,和dwr不同,dwr是一个一站式的ajax框架,不仅提供了客户端的工具方法,也包括服务端的配置和通信的处理。
而ext和prototype等仅仅设置好了json的接口并对ajax通信做了封装,相对而言是一种比较“纯粹”的AJAX实现,当然ext还包括了大量的图形组件,这又是题外话了。
为了解决ext们的通信问题,如果单纯的定义Servlet,实现起来比较原始,既复杂又不好管理。于是网上有好多人采用了dwr来管理通信,还有人用structs作为对接口Servlet的映射配置管理,这样一来不论是客户端还是服务端,都有很多功能被切割掉了,显得不够“干净”。于是我写了下面的两个响应的Servlet处理类来解决这个问题。
代码如下:

 JSONServlet:

import java.io.*;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.*;

/**
 * 通用JSON服务端
 * 
 * 
@author 杨一
 
*/


public class JSONServlet extends javax.servlet.http.HttpServlet implements
        javax.servlet.Servlet 
{
    
    
public JSONServlet() {
        
super();
        
    }


    
protected void doPost(HttpServletRequest request,
            HttpServletResponse response) 
throws ServletException, IOException {
        JSONObject jsonObject 
= null;
        String responseText 
= null;
        
try {
            
//JSON对象,由参数json定义
            jsonObject = new JSONObject(request.getParameter("json"));
            
            
//访问的类和方法,例如Object ExampleClass.exampleMethod()
            String action = (String)request.getParameter("action");
            
int dotPos = action.lastIndexOf(".");
            
            String beanName 
= action.substring(0, dotPos);
            String methodName 
= action.substring(dotPos + 1);
            
            
//在当前线程环境中找当前作用类的实例
            Object bean = findInstance(beanName);
            
//作用类的原型的引用
            Class clazz;
            
            
//如果当前线程环境中有当前作用类的实例,获取其引用,否则实例化并返回引用,同时在线程中保存值
            if(bean == null){
                clazz 
= Class.forName(beanName);
                bean 
= clazz.newInstance();
                storeInstance(beanName, bean);
            }
 else{
                clazz 
= bean.getClass();
            }


            
//设置JSON值
            AbstractJsonAction aja = (AbstractJsonAction)bean;
            aja.initJson(jsonObject);
            
            
//获得要执行的方法
            Method m = clazz.getMethod(methodName);
            
            
//设置bean的其他参数
            Enumeration e = request.getParameterNames();
            Method setM;
            
while(e.hasMoreElements()){
                String str 
= (String)e.nextElement();
                
if(str.equals("json"|| str.equals("action")){
                    
continue;
                }

                StringBuffer sb 
= new StringBuffer();
                sb.append(
"set");
                sb.append(upperFirstChar(str));
                String tempMName 
= sb.toString();
                setM 
= clazz.getMethod(tempMName, new Class[]{String.class});
                setM.invoke(bean, (String)request.getParameter(str));
            }

            
            
//执行方法
            Object retObj = m.invoke(bean);
            
            
//此处的Object要进行重写toString方法,使其返回一个json串给客户端
            responseText = retObj.toString();
        }
 catch (Exception e) {
            e.printStackTrace();
        }
 
        response.setCharacterEncoding(
"UTF-8");
        response.setContentType(
"application/x-json");
        response.getWriter().print(responseText);
    }

    
    
private String upperFirstChar(String fieldName) {
        
char ch = fieldName.charAt(0);
        ch 
= Character.toUpperCase(ch);
        StringBuffer sb 
= new StringBuffer();
        sb.append(ch);
        sb.append(fieldName.substring(
1));
        fieldName 
= sb.toString();
        
return fieldName;
    }

    
    
private Object findInstance(String beanName){
        HashMap hm 
= (HashMap)tl.get();
        
return hm.get(beanName);
    }

    
    
private void storeInstance(String beanName, Object bean){
        HashMap hm 
= (HashMap)tl.get();
        hm.put(beanName, bean);
    }

    
    
private static ThreadLocal tl = new ThreadLocal(){
        
protected Object initialValue() {return new HashMap();};
    }
;
}

 

 

AbstractJsonAction.java:

import org.json.JSONObject;

/**
 * 抽象JSON Action类,负责处理各种业务,可以有自己的参数,数据结构采用JSON定义,业务方法名自己定义
 * 可以通过继承定义具体业务
 * 
 * 
@author 杨一
 
*/

public abstract class AbstractJsonAction {
 
public AbstractJsonAction(){}
 
 
public void initJson(JSONObject json){
  
this.json = json;
 }

 
 
protected JSONObject json; 
}


仅仅是表述一种想法,欢迎大家批评,呵呵:)

 @2008 杨一. 版权所有. 保留所有权利

posted on 2008-11-24 18:14 杨一 阅读(2222) 评论(1)  编辑  收藏

评论

# re: JSON通用服务端处理[未登录] 2008-11-24 18:59 Sirius

http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java

shindig中的json to object 双向转换器
我一直在用,可以参考一下,可能要修改一下才能用

ps:这个日期转换有点问题  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

导航

公告

本人在blogjava上发表的文章及随笔除特别声明外均为原创或翻译,作品受知识产权法保护并被授权遵从 知识分享协议:署名-非商业性使用-相同方式共享 欢迎转载,请在转载时注明作者姓名(杨一)及出处(www.blogjava.net/yangyi)
/////////////////////////////////////////
我的访问者

常用链接

留言簿(5)

随笔分类(55)

随笔档案(55)

相册

Java

其他技术

生活

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

自强不息


用心 - 珍惜时间,勇于创造