⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsonrpcbridge.java

📁 json-rpc是和DWR类似的ajax-rpc实现。我比较细化
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * JSON-RPC-Java - a JSON-RPC to Java Bridge with dynamic invocation * * $Id: JSONRPCBridge.java,v 1.37.2.5 2006/03/27 05:39:21 mclark Exp $ * * Copyright Metaparadigm Pte. Ltd. 2004. * Michael Clark <michael@metaparadigm.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *    http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */package com.metaparadigm.jsonrpc;import java.util.Map;import java.util.HashSet;import java.util.HashMap;import java.util.StringTokenizer;import java.util.ArrayList;import java.util.Iterator;import java.util.NoSuchElementException;import java.util.logging.Logger;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.InvocationTargetException;import java.io.Serializable;import org.json.JSONObject;import org.json.JSONArray;/** * This class implements a bridge that unmarshalls JSON objects in JSON-RPC * request format, invokes a method on the exported object, and then marshalls * the resulting Java objects to JSON objects in JSON-RPC result format. * <p /> * An instance of the JSONRPCBridge object is automatically placed in the * HttpSession object registered under the attribute "JSONRPCBridge" by * the JSONRPCServlet. * <p /> * The bridge is implemented as session specific to improve the security * of applications by allowing exporting of object methods only to * specific HttpSessions. * <p /> * To use the bridge to allow calling of Java methods you can easily * access the HttpSession specific bridge in JSP using the usebean tag. eg. * <p /> * <code>&lt;jsp:useBean id="JSONRPCBridge" scope="session" *   class="com.metaparadigm.jsonrpc.JSONRPCBridge" /&gt;</code> * <p /> * Then export the object you wish to call methods on. eg. * <p /> * <code>JSONRPCBridge.registerObject("test", testObject);</code> * <p /> * This will make available all methods of the object as * <code>test.&lt;methodnames&gt;</code> to JSON-RPC clients. This method * should generally be performed after an authentication check to only * export specific objects to clients that are authorised to use them. * <p /> * There exists a global bridge singleton object that will allow exporting * objects to all HTTP clients. This can be used for registering factory * classes although care must be taken with authentication as these objects * will be accessible to all clients. */public class JSONRPCBridge implements Serializable{    private final static Logger log =	Logger.getLogger(JSONRPCBridge.class.getName());    private boolean debug = false;    public void setDebug(boolean debug) {	this.debug = debug;	ser.setDebug(debug);    }    protected boolean isDebug() { return debug; }    private static JSONRPCBridge globalBridge = new JSONRPCBridge();    /**     * This method retreieves the global bridge singleton.     *     * It should be used with care as objects should generally be     * registered within session specific bridges for security reasons.     *     * @return returns the global bridge object.     */    public static JSONRPCBridge getGlobalBridge() { return globalBridge; }    // key clazz, val ClassData    private static HashMap classCache = new HashMap();    // key argClazz, val HashSet<LocalArgResolverData>    private static HashMap localArgResolverMap = new HashMap();    // JSONSerializer instance for this bridge    private JSONSerializer ser = new JSONSerializer();    // key CallbackData    private HashSet callbackSet = new HashSet();    // key "session exported class name", val Class    private HashMap classMap = new HashMap();    // key "session exported instance name", val ObjectInstance    private HashMap objectMap = new HashMap();    // key Integer hashcode, object held as reference    protected HashMap referenceMap = new HashMap();    // ReferenceSerializer if enabled    protected Serializer referenceSer = null;    // key clazz, classes that should be returned as References    protected HashSet referenceSet = new HashSet();    // key clazz, classes that should be returned as CallableReferences    protected HashSet callableReferenceSet = new HashSet();    private static HttpServletRequestArgResolver requestResolver =	new HttpServletRequestArgResolver();    private static HttpSessionArgResolver sessionResolver =	new HttpSessionArgResolver();    private static JSONRPCBridgeServletArgResolver bridgeResolver =	new JSONRPCBridgeServletArgResolver();    static    {	registerLocalArgResolver(javax.servlet.http.HttpServletRequest.class,				 javax.servlet.http.HttpServletRequest.class,				 requestResolver);	registerLocalArgResolver(javax.servlet.http.HttpSession.class,				 javax.servlet.http.HttpServletRequest.class,				 sessionResolver);	registerLocalArgResolver(JSONRPCBridge.class,				 javax.servlet.http.HttpServletRequest.class,				 bridgeResolver);    }    public JSONRPCBridge()    {        this(true);    }    public JSONRPCBridge(boolean useDefaultSerializers)    {        if (useDefaultSerializers) {            try {                ser.registerDefaultSerializers();            } catch (Exception e) {                e.printStackTrace();            }        }    }    protected static class ClassData    {	private Class clazz;	// key methodKey, val (Method || Method[])	private HashMap methodMap;	// key methodKey, val (Method || Method[])	private HashMap staticMethodMap;    }    protected static class CallbackData implements Serializable    {	private InvocationCallback cb;	private Class contextInterface;	public CallbackData(InvocationCallback cb, Class contextInterface)	{	    this.cb = cb;	    this.contextInterface = contextInterface;	}	public boolean understands(Object context)	{	    return contextInterface.isAssignableFrom(context.getClass());	}	public int hashCode()	{	    return cb.hashCode() * contextInterface.hashCode();	}	public boolean equals(Object o)	{	    CallbackData cmp = (CallbackData)o;	    return (cb.equals(cmp.cb) &&		    contextInterface.equals(cmp.contextInterface));	}    }    protected static class LocalArgResolverData    {	private LocalArgResolver argResolver;	private Class argClazz;	private Class contextInterface;	public LocalArgResolverData(LocalArgResolver argResolver,				    Class argClazz,				    Class contextInterface)	{	    this.argResolver = argResolver;	    this.argClazz = argClazz;	    this.contextInterface = contextInterface;	}	public boolean understands(Object context)	{	    return contextInterface.isAssignableFrom(context.getClass());	}	public int hashCode()	{	    return argResolver.hashCode() * argClazz.hashCode() *		contextInterface.hashCode();	}	public boolean equals(Object o)	{	    LocalArgResolverData cmp = (LocalArgResolverData)o;	    return (argResolver.equals(cmp.argResolver) &&		    argClazz.equals(cmp.argClazz) &&		    contextInterface.equals(cmp.contextInterface));	}    }    protected static class ObjectInstance implements Serializable    {	private Object o;	public ObjectInstance(Object o, Class clazz)	{	    if (! clazz.isInstance(o))	    {	        throw new ClassCastException("Attempt to register jsonrpc object with invalid class.");	    }	    this.o = o;	    this.clazz = clazz;	}	private Class clazz;	public ObjectInstance(Object o)	{	    this.o = o;	    clazz = o.getClass();	}	public ClassData classData()	{	    return getClassData(clazz);	}    }    protected static class MethodKey    {	private String methodName;	private int numArgs;	public MethodKey(String methodName, int numArgs)	{	    this.methodName = methodName;	    this.numArgs = numArgs;	}	public int hashCode()	{	    return methodName.hashCode() * numArgs;	}	public boolean equals(Object o)	{	    if(!(o instanceof MethodKey)) return false;	    return (methodName.equals(((MethodKey)o).methodName) &&		    numArgs == ((MethodKey)o).numArgs);	}    }    protected static class MethodCandidate    {	private Method method;	private ObjectMatch match[];	public MethodCandidate(Method method)	{	    this.method = method;	    match = new ObjectMatch[method.getParameterTypes().length];	}	public ObjectMatch getMatch()	{	    int mismatch = -1;	    for(int i=0; i < match.length; i++) {		mismatch = Math.max(mismatch, match[i].mismatch);	    }	    if(mismatch == -1) return ObjectMatch.OKAY;	    else return new ObjectMatch(mismatch);	}    }    private static ClassData analyzeClass(Class clazz)    {	log.info("analyzing " + clazz.getName());	Method methods[] = clazz.getMethods();	ClassData cd = new ClassData();	cd.clazz = clazz;	// Create temporary method map	HashMap staticMethodMap = new HashMap();	HashMap methodMap = new HashMap();	for(int i=0; i < methods.length; i++) {	    Method method = methods[i];	    if(method.getDeclaringClass() == Object.class) continue;	    int mod = methods[i].getModifiers();	    if(!Modifier.isPublic(mod)) continue;	    Class param[] = method.getParameterTypes();	    // don't count locally resolved args	    int argCount=0;	    synchronized(localArgResolverMap) {		for(int n=0; n<param.length; n++) {		    HashSet resolvers = (HashSet)			localArgResolverMap.get(param[n]);		    if(resolvers != null) continue;		    argCount++;		}	    }	    MethodKey mk = new MethodKey(method.getName(), argCount);	    ArrayList marr = (ArrayList)methodMap.get(mk);	    if(marr == null) {		marr = new ArrayList();		methodMap.put(mk, marr);	    }	    marr.add(method);	    if(Modifier.isStatic(mod)) {		marr = (ArrayList)staticMethodMap.get(mk);		if(marr == null) {		    marr = new ArrayList();		    staticMethodMap.put(mk, marr);		}		marr.add(method);	    }	}	cd.methodMap = new HashMap();	cd.staticMethodMap = new HashMap();	// Convert ArrayLists to arrays	Iterator i = methodMap.entrySet().iterator();	while(i.hasNext()) {	    Map.Entry entry = (Map.Entry)i.next();	    MethodKey mk = (MethodKey)entry.getKey();	    ArrayList marr = (ArrayList)entry.getValue();	    if(marr.size() == 1) {		cd.methodMap.put(mk, marr.get(0));	    } else {		cd.methodMap.put(mk, marr.toArray(new Method[0]));	    }	}	i = staticMethodMap.entrySet().iterator();	while(i.hasNext()) {	    Map.Entry entry = (Map.Entry)i.next();	    MethodKey mk = (MethodKey)entry.getKey();	    ArrayList marr = (ArrayList)entry.getValue();	    if(marr.size() == 1) {		cd.staticMethodMap.put(mk, marr.get(0));	    } else {		cd.staticMethodMap.put(mk, marr.toArray(new Method[0]));	    }	}	return cd;    }    private static ClassData getClassData(Class clazz)    {	ClassData cd;	synchronized (classCache) {	    cd = (ClassData)classCache.get(clazz);	    if(cd == null) {		cd = analyzeClass(clazz);		classCache.put(clazz, cd);	    }	}	return cd;    }    public void registerSerializer(Serializer s)	throws Exception    {	ser.registerSerializer(s);    }    public void enableReferences()	throws Exception    {	if(referenceSer == null) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -