json-rpc-java最让人郁闷的地方就是把bridge注册到session,当然可以把所有的方法都注册到GlobalBridge,不过这样会有一个问题,就是客户端创建JSONRpcClient的时候listMethod会返回所有的注册方法,一个不觉得,如果东西过多的话也够恐怖的.而且对于应用的前端也与JSONRpcClient死死绑在一起.
有一种办法就是暴露出少量的dispath方法,然后通过反射传入的方法名字传入Map参数来做,但是这样感觉也怪怪的,所以还是用自己的想法来进行改造:客户端不需要new JSONRpcClient,而是通过url的方式来访问暴露的业务组件,如XXXService.xxx.所有的暴露组件注册到GlobalBridge.修改其实就是把它的Servlet改掉就可以了:
public class RpcServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; private final static int buf_size = 4096; public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ClassCastException { String action = request.getRequestURI().substring( request.getServletPath().length() + request.getContextPath().length() + 1); JSONRPCBridge json_bridge = JSONRPCBridge.getGlobalBridge(); response.setContentType("text/plain;charset=utf-8"); OutputStream out = response.getOutputStream(); String charset = request.getCharacterEncoding(); if (charset == null) charset = "UTF-8"; BufferedReader in = new BufferedReader(new InputStreamReader(request .getInputStream(), charset)); CharArrayWriter data = new CharArrayWriter(); char buf[] = new char[buf_size]; int ret; while ((ret = in.read(buf, 0, buf_size)) != -1) data.write(buf, 0, ret); String json = "{\"method\": \""+action+"\", \"params\": "+data.toString()+"}"; // Process the request JSONObject json_req = null; JSONRPCResult json_res = null; try { json_req = new JSONObject(json); json_res = json_bridge.call(new Object[] { request }, json_req); } catch (ParseException e) { e.printStackTrace(); json_res = new JSONRPCResult(JSONRPCResult.CODE_ERR_PARSE, null, JSONRPCResult.MSG_ERR_PARSE); } byte[] bout = json_res.toString().getBytes("UTF-8"); response.setIntHeader("Content-Length", bout.length); out.write(bout); out.flush(); out.close(); } }
对比以前的来改非常容易,然后就是构建一个在客户端可用的访问器.
由于应用是结合Ext的,所以用到了它的基本类库(偷懒了-_-)以及jsonrpc js类库中的几个帮助方法,实现同步与异步调用:
JsonRpc = { rootUrl : "" }; JsonRpc.request = function(url, params, callback) { if (callback) { Ext.Ajax.request({ url : JsonRpc.rootUrl + url, params : toJSON(params), method : "POST", callback : function(op, success, response) { if (success) { var o = eval("(" + response.responseText + ")"); callback(o.result, o.error); } else { callback(undefined, { msg : "failed" }); } } }); } else { var conn = Ext.lib.Ajax.getConnectionObject().conn; conn.open("POST", JsonRpc.rootUrl + url, false); conn.send(toJSON(params)); var o = eval("(" + conn.responseText + ")"); if (o.error) { throw o.error; } else { return o.result; } } };
同步与异步使用分别是:
//同步 JsonRpc.request("XXXService.xx", [params]); //异步 var callback = function(result, ex) { }; JsonRpc.request("XXXService.xx", [params], callback);