src/org/nutz/mvc/impl/JsonRPC.java
public static <T> T mapper(Class<T> klass, final String endpoint, final String namespace, final int timeout) {
        return (T)Proxy.newProxyInstance(klass.getClassLoader(), new Class<?>[]{klass}, new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                NutMap jreq = new NutMap();
                jreq.setv("jsonrpc", "2.0").setv("id", R.UU32()).setv("method", method.getName());
                if (!Strings.isBlank(namespace)) {
                    jreq.put("namespace", namespace);
                }
                jreq.setv("params", args);
                Request req = Request.create(endpoint, METHOD.POST);
                req.setData(Json.toJson(jreq));
                Response resp = Sender.create(req).setTimeout(timeout).send();
                if (resp.isOK()) {
                    if (method.getReturnType() == Void.class)
                        return null;
                    return Json.fromJson(method.getGenericReturnType(), resp.getReader());
                }
                throw new RuntimeException("resp code="+resp.getStatus());
            }
        });
    }
public static <T> T mapper(Class<T> klass, final String endpoint, final String namespace, final int timeout) {
        return (T)Proxy.newProxyInstance(klass.getClassLoader(), new Class<?>[]{klass}, new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                NutMap jreq = new NutMap();
                jreq.setv("jsonrpc", "2.0").setv("id", R.UU32()).setv("method", method.getName());
                if (!Strings.isBlank(namespace)) {
                    jreq.put("namespace", namespace);
                }
                jreq.setv("params", args);
                Request req = Request.create(endpoint, METHOD.POST);
                req.setData(Json.toJson(jreq));
                Response resp = Sender.create(req).setTimeout(timeout).send();
                if (resp.isOK()) {
                    if (method.getReturnType() == Void.class)
                        return null;
                    return Json.fromJson(method.getGenericReturnType(), resp.getReader());
                }
                throw new RuntimeException("resp code="+resp.getStatus());
            }
        });
    }
客户端. 用于生成一个代理接口的实例,透明访问json-rpc服务
@param klass 需要代理的接口
@param endpoint jsonrpc URL入口
@param namespace 命名空间,非json-rpc标准,扩展用,不需要就传null
@param timeout 超时设置,若永不超时,设置为-1
@return 代理实例