package com.cib.ajax.rpc;
import java.io.BufferedReader;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.jabsorb.JSONRPCResult;
import org.jabsorb.JSONRPCServlet;
import org.json.JSONArray;
import org.json.JSONObject;
import com.cib.ajax.rpc.util.JSON2JavaBean;
import com.cib.ajax.rpc.util.JSON2JavaMethodUtil;
import com.cib.ajax.rpc.util.JavaBean2JSON;
public class CommonJSONRPCServiceServlet extends JSONRPCServlet {
private static final long serialVersionUID = 1L;
transient Class<?> serviceInterface = null;
transient Object serviceInstance = null;
private JSON2JavaMethodUtil methodUtil = new JSON2JavaMethodUtil();
/**
* @see JSONRPCServlet#JSONRPCServlet()
*/
public CommonJSONRPCServiceServlet() {
super();
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
String interfaceClazz = config.getInitParameter("interface");
this.serviceInterface = Class.forName(interfaceClazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
String implementationClazz = config
.getInitParameter("implementation");
this.serviceInstance = Class.forName(implementationClazz)
.newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void service(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// Either a GET or a POST that's not an XHR call, such as after login
// via j_security_check that tries to forward to last requested URL.
if (request.getMethod().equals("GET")) {
doGet(request, response);
} else {
try {
handleServiceRequest(request, response);
} catch (Exception e) {
e.printStackTrace();
} finally {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute("JSONRPCBridge");
}
}
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
try {
handleServiceRequest(request, response);
} finally {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute("JSONRPCBridge");
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
doGet(request, response);
}
private void handleServiceRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException {
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));
// Read the request
CharArrayWriter data = new CharArrayWriter();
char[] buf = new char[4096];
int ret;
while ((ret = in.read(buf, 0, 4096)) != -1) {
data.write(buf, 0, ret);
}
JSONObject jsonReq = null;
//String method = null;
try {
System.out.println(data.toString());
String reqData = URLDecoder.decode(data.toString(), "UTF-8");
jsonReq = new JSONObject(reqData);
//method = jsonReq.getString("method");
} catch (Exception e) {
e.printStackTrace();
}
byte[] bout = null;
bout = handleJSONRPCMethodInvocation(request, response, jsonReq);
// Send response to client
out.write(bout);
out.flush();
out.close();
}
protected byte[] handleJSONRPCMethodInvocation(HttpServletRequest request,
HttpServletResponse response, JSONObject jsonReq)
throws IOException, UnsupportedEncodingException {
String method = null;
Object[] args = null;
Object id = null;
Method jsonOperation = null;
try {
// Extract the method
method = jsonReq.getString("method");
jsonOperation = methodUtil.findOperation(method,this.serviceInterface);
// Extract the arguments
args = methodUtil.transferToJavaParameters(jsonReq, this.serviceInterface);
} catch (Exception e) {
JSONRPCResult errorResult = new JSONRPCResult(
JSONRPCResult.CODE_REMOTE_EXCEPTION, id, e.getCause());
return errorResult.toString().getBytes("UTF-8");
}
// invoke the request
Object result = null;
Object[] parameters = null;
if (null != args && hasSessionParam(jsonOperation)) {
parameters = new Object[args.length + 1];
parameters[0] = request.getSession(false);
for (int i = 0; i < args.length; i++) {
parameters[i + 1] = args[i];
}
} else {
parameters = args;
}
try {
JSONObject jsonResponse = new JSONObject();
// result = wire.invoke(jsonOperation, args);
result = jsonOperation.invoke(this.serviceInstance, parameters);
JavaBean2JSON transform = new JavaBean2JSON();
try {
// FIXME: this only checks for String and not primitive types
if (!(result instanceof java.lang.String)) {
jsonResponse.put("result", transform.toJSON(result));
} else {
jsonResponse.put("result", result);
}
jsonResponse.putOpt("id", id);
// get response to send to client
return jsonResponse.toString().getBytes("UTF-8");
} catch (Exception e) {
JSONRPCResult errorResult = new JSONRPCResult(
JSONRPCResult.CODE_REMOTE_EXCEPTION, id, e.getCause());
return errorResult.toString().getBytes("UTF-8");
}
} catch (InvocationTargetException e) {
JSONRPCResult errorResult = new JSONRPCResult(
JSONRPCResult.CODE_REMOTE_EXCEPTION, id, e.getCause());
return errorResult.toString().getBytes("UTF-8");
} catch (RuntimeException e) {
JSONRPCResult errorResult = new JSONRPCResult(
JSONRPCResult.CODE_REMOTE_EXCEPTION, id, e.getCause());
return errorResult.toString().getBytes("UTF-8");
} catch (IllegalAccessException e) {
JSONRPCResult errorResult = new JSONRPCResult(
JSONRPCResult.CODE_REMOTE_EXCEPTION, id, e.getCause());
return errorResult.toString().getBytes("UTF-8");
} catch (Exception e) {
JSONRPCResult errorResult = new JSONRPCResult(
JSONRPCResult.CODE_REMOTE_EXCEPTION, id, e.getCause());
return errorResult.toString().getBytes("UTF-8");
}
}
/**
* 只有第一个参数可以是session类型的 当第一个参数是session类型的,则将session也作为参数传入Service方法
*
* @param method
* @return
*/
private boolean hasSessionParam(Method method) {
// Note that only the first parameter can be HTTPSession
Class<?>[] params = method.getParameterTypes();
if (null != params
&& params.length > 0
&& params[0].getCanonicalName().compareToIgnoreCase(
"javax.servlet.http.HttpSession") == 0) {
return true;
}
return false;
}
}