package com.jiuqi.mobile.nigo.comeclose.ws.client; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; import javax.xml.crypto.dsig.keyinfo.RetrievalMethod; import org.apache.log4j.xml.Log4jEntityResolver; import com.jiuqi.mobile.nigo.comeclose.exception.ConnectServiceFailException; import com.jiuqi.mobile.nigo.comeclose.exception.NiGoException; import com.jiuqi.mobile.nigo.comeclose.exception.WSFailException; import com.jiuqi.mobile.nigo.comeclose.exception.WSRequestErrorException; import com.jiuqi.mobile.nigo.comeclose.json.JSONArray; import com.jiuqi.mobile.nigo.comeclose.json.JSONConvertor2; import com.jiuqi.mobile.nigo.comeclose.json.JSONException; import com.jiuqi.mobile.nigo.comeclose.json.JSONObject; import com.jiuqi.mobile.nigo.comeclose.utils.DateUtils; import com.jiuqi.mobile.nigo.comeclose.utils.StringUtils; import com.jiuqi.mobile.nigo.comeclose.ws.WSConsts; public class LBSClientInvocationHandler implements InvocationHandler { /** * 连接超时 */ private static int TIMEOUT = 10 * 1000; // 10秒 static final private String serverURL = null; private String serviceURI = null; private Class<?> intf = null; private int time; public Class<?> getIntf() { return intf; } public void setIntf(Class<?> intf) { this.intf = intf; } /** * 构造函数 * * @param serverURL * 服务地址 * @param serviceURI * 业务服务对相应的相对地址 * @param sessionID */ public LBSClientInvocationHandler(String serverURL, String serviceURI, Class<?> intf) { this(serverURL, serviceURI, intf, 10 * 1000); } public LBSClientInvocationHandler(String serverURL, String serviceURI, Class<?> intf, int timeout) { this.serverURL = serverURL; this.serviceURI = serviceURI; this.intf = intf; this.TIMEOUT = timeout; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String intfName = intf.getName(); String methodName = method.getName(); JSONArray params = params2JSON(args); String serviceURL = getServiceURL(); HttpURLConnection conn = connect(serviceURL); // JSONObject ret = doPost(conn, intfName, methodName, params); Object obj = doPost(proxy,method,args,conn, intfName, methodName, params); if (obj instanceof JSONObject) { JSONObject ret = (JSONObject) obj; Type returnType = method.getGenericReturnType(); // android 2.2 try { if (null != returnType && null != returnType.toString() && !(returnType.toString().contains("."))) { return JSONConvertor2.unSerializable(ret); } } catch (Throwable e) { } return JSONConvertor2.unAutoSerializable(ret, returnType); } else { return obj; } } private String getServiceURL() { String url = serverURL + serviceURI; return url; } // 连接 private HttpURLConnection connect(String url) throws NiGoException { URL _url = null; try { _url = new URL(url); } catch (MalformedURLException e) { e.printStackTrace(); } HttpURLConnection conn = null; try { conn = (HttpURLConnection) _url.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); conn.setUseCaches(false); conn.setRequestProperty("Content-type", WSConsts.HTTP_CONNTENT_TYPE); conn.setRequestProperty("Charset", WSConsts.CHARSET); conn.setConnectTimeout(TIMEOUT); conn.connect(); } catch (IOException e) { throw new ConnectServiceFailException(url); } return conn; } // 执行 private Object doPost(Object proxy,Method method, Object[] args,HttpURLConnection conn, String intfName, String methodName, JSONArray params) throws Throwable { PrintWriter out = new PrintWriter(new OutputStreamWriter( conn.getOutputStream(), WSConsts.CHARSET)); String requestString = getRequestString(intfName, methodName, params); out.print(requestString); out.flush(); out.close(); StringBuilder sResult = new StringBuilder(); conn.setConnectTimeout(5000); int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { InputStream httpInput = null; BufferedReader httpReader = null; // 读取数据 httpInput = conn.getInputStream(); httpReader = new BufferedReader(new InputStreamReader(httpInput, WSConsts.CHARSET)); String line = null; while ((line = httpReader.readLine()) != null) { if (sResult.length() > 0) { sResult.append("\n"); } sResult.append(line); } } else { throw new WSFailException("请求服务器失败:" + responseCode + ";url:" + conn.getURL().toString()); } JSONObject result = new JSONObject(sResult.toString()); boolean error = result.getBoolean(WSConsts.REQUEST_ERRORED); if (error) { String errorMsg = ""; if (result.has(WSConsts.RESPONSE_ERROR_MSG)) { errorMsg = result.getString(WSConsts.RESPONSE_ERROR_MSG); } if (result.has(WSConsts.RESPONSE_ERROR_EXCEPTION_CLASS)) { try { String eClass = result .getString(WSConsts.RESPONSE_ERROR_EXCEPTION_CLASS); Class<?> ex = Class.forName(eClass, true, Thread .currentThread().getContextClassLoader()); Constructor<? extends Throwable> con; if ("".equals(errorMsg)) { con = (Constructor<? extends Throwable>) ex .getDeclaredConstructor(); if (null != con) { throw con.newInstance(); } } else { con = (Constructor<? extends Throwable>) ex .getDeclaredConstructor(String.class); if (null != con) { throw con.newInstance(errorMsg); } } if (null == con) { con = (Constructor<? extends Throwable>) ex .getDeclaredConstructor(String.class, Throwable.class); if (null != con) { throw con.newInstance(errorMsg, (Throwable) null); } } } catch (Exception e) { e.printStackTrace(); } } if (null == errorMsg || "".equals(errorMsg.trim())) { throw new WSRequestErrorException("服务器未知异常"); } else{ /** * Session超时时抛出异常errorMsg = 您的登录信息已过期,请重新登录! * 定位组件没有session */ // if(null!=errorMsg&&errorMsg.contains("登录信息已过期")){ // // }else{ // throw new WSRequestErrorException(errorMsg); // } } } else { if (!result.has(WSConsts.RESPONSE_DATA)) { return null; } try { JSONObject resultData = result .getJSONObject(WSConsts.RESPONSE_DATA); return resultData; } catch (JSONException e) { Object obj = result.get(WSConsts.RESPONSE_DATA); return obj; } } return error; } // 将params转换成json格式的字符串 private JSONArray params2JSON(Object[] params) { return JSONConvertor2.serializableArray(params); } // 得到请求的字符串 private String getRequestString(String intfName, String methodName, JSONArray params) throws JSONException { JSONObject requestJSON = getRequestData(intfName, methodName, params); return requestJSON.toString(); } // 将请求参数转换成JSON对象 private JSONObject getRequestData(String intfName, String methodName, JSONArray params) throws JSONException { JSONObject ret = new JSONObject(); ret.put(WSConsts.REQUEST_TAG_INTF_NAME, intfName); ret.put(WSConsts.REQUEST_TAG_METHOD_NAME, methodName); ret.put(WSConsts.REQUEST_TAG_ARGS, params); return ret; } }