package com.jiuqi.lbsinterface.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 com.jiuqi.lbsinterface.exception.ConnectServiceFailException; import com.jiuqi.lbsinterface.exception.NiGoException; import com.jiuqi.lbsinterface.exception.WSFailException; import com.jiuqi.lbsinterface.exception.WSRequestErrorException; import com.jiuqi.lbsinterface.json.JSONArray; import com.jiuqi.lbsinterface.json.JSONConvertor2; import com.jiuqi.lbsinterface.json.JSONException; import com.jiuqi.lbsinterface.json.JSONObject; import com.jiuqi.lbsinterface.ws.WSConsts; public class ClientInvocationHandler implements InvocationHandler{ /** * 连接超时 */ private static final int TIMEOUT = 10*1000; //10秒 private String serverURL = null; private String serviceURI = null; private Class<?> intf = null; private String sessionID; /** * 构造函数 * @param serverURL 服务地址 * @param serviceURI 业务服务对相应的相对地址 * @param sessionID */ public ClientInvocationHandler(String serverURL, String serviceURI, String sessionID, Class<?> intf) { this.serverURL = serverURL; this.serviceURI = serviceURI; this.sessionID = sessionID; this.intf = intf; } @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(conn, intfName, methodName, params); if(obj instanceof JSONObject){ JSONObject ret = (JSONObject) obj; Type returnType = method.getGenericReturnType(); return JSONConvertor2.unAutoSerializable(ret, returnType); //// if(returnType.isArray()){ //// Wrapper w = JSONConvertor2.unSerializable(Wrapper.class, ret); //// return w.getRet(); //// } // Object retObj = JSONConvertor2.unSerializable(returnType, ret); // return retObj; }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(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(); 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("请求服务器失败"); } 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) { } } if(null == errorMsg || "".equals(errorMsg.trim())){ throw new WSRequestErrorException("服务器未知异常"); }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; } } } // 将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); // String requestString = WSConsts.REQUEST_DATA + "=" + requestJSON.toString(); // return requestString; 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); ret.put(WSConsts.REQUEST_SESSION, sessionID); return ret; } }