private void sendJsonError(String message, Object data) { ServletRequestInfo info = getServletRequestInfo(); Object id = info.currentJsonRequest.id; // If ID is empty then it is a notification and we send nothing back if (id == null) return; JsonRpcResponseModel result = new JsonRpcResponseModel(); result.id = id; result.jsonrpc = "2.0"; result.error = new JsonRpcErrorModel(); result.error.message = message; result.error.data = data; if (message.equals(JSON_RPC_PROTOCOL_ERROR_MESSAGE) || message.equals(JSON_RPC_ID_ERROR_MESSAGE)) { result.error.code = "-32600"; } else if (message.equals(JSON_RPC_METHOD_ERROR_MESSAGE)) { result.error.code = "-32601"; } else if (message.equals(JSON_RPC_PARSE_ERROR_MESSAGE)) { result.error.code = "-32700"; } else { result.error.code = "-32000"; } info.jsonResponses.add(result); }
/** * @param methodName The name of the function to invoke. * @param methodParams A Map, List, or Array of input parameters for the method. Values will be * cast to the appropriate types if necessary. */ private void invokeMethod(String methodName, Object methodParams) throws IOException { ServletRequestInfo info = getServletRequestInfo(); if (!methodMap.containsKey(methodName) || methodMap.get(methodName) == null) { sendError( new IllegalArgumentException(String.format("Method \"%s\" not supported.", methodName)), null); return; } if (methodParams == null) methodParams = new Object[0]; if (methodParams instanceof Map) methodParams = getParamsFromMap(methodName, (Map<?, ?>) methodParams); if (methodParams instanceof List<?>) methodParams = ((List<?>) methodParams).toArray(); if (info.streamParameterIndex != null) { int index = info.streamParameterIndex.intValue(); if (index >= 0) ((Object[]) methodParams)[index] = info.inputStream; } Object[] params = (Object[]) methodParams; // get method by name ExposedMethod exposedMethod = methodMap.get(methodName); if (exposedMethod == null) { sendError(new IllegalArgumentException("Unknown method: " + methodName), null); return; } // cast input values to appropriate types if necessary Class<?>[] expectedArgTypes = exposedMethod.method.getParameterTypes(); if (expectedArgTypes.length == params.length) { for (int index = 0; index < params.length; index++) { params[index] = cast(params[index], expectedArgTypes[index]); } } // prepare to output the result of the method call long startTime = System.currentTimeMillis(); // Invoke the method on the object with the arguments try { Object result = exposedMethod.method.invoke(exposedMethod.instance, params); if (info.currentJsonRequest == null) // AMF3 { if (exposedMethod.method.getReturnType() != void.class) { ServletOutputStream servletOutputStream = info.getOutputStream(); serializeCompressedAmf3(result, servletOutputStream); } } else // json { Object id = info.currentJsonRequest.id; /* If ID is empty then it is a notification, we send nothing back */ if (id != null) { JsonRpcResponseModel responseObj = new JsonRpcResponseModel(); responseObj.jsonrpc = "2.0"; responseObj.result = result; responseObj.id = id; info.jsonResponses.add(responseObj); } } } catch (InvocationTargetException e) { System.err.println(methodToString(methodName, params)); sendError(e, null); } catch (IllegalArgumentException e) { String moreInfo = "Expected: " + formatFunctionSignature(methodName, expectedArgTypes, exposedMethod.paramNames) + "\n" + "Received: " + formatFunctionSignature(methodName, params, null); sendError(e, moreInfo); } catch (Exception e) { System.err.println(methodToString(methodName, params)); sendError(e, null); } long endTime = System.currentTimeMillis(); // debug if (endTime - startTime >= debugThreshold) System.out.println( String.format("[%sms] %s", endTime - startTime, methodToString(methodName, params))); }