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.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.JSONConvertor; import com.jiuqi.lbsinterface.json.JSONException; import com.jiuqi.lbsinterface.json.JSONObject; import com.jiuqi.lbsinterface.ws.WSConsts; import com.jiuqi.lbsinterface.ws.server.Wrapper; /** * webservice 代理执行核心,负责网络等相关任务 * @author liuhongbin */ public class WSInvocationHandler 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 WSInvocationHandler(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; Class<?> returnType = method.getReturnType(); if(returnType.isArray()){ Wrapper w = JSONConvertor.unSerializable(Wrapper.class, ret); return w.getRet(); } Object retObj = JSONConvertor.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) { } } 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) { JSONArray ret = new JSONArray()/*(JSONObject) JSONConvertor.serializable(params)*/; if (params == null || params.length <= 0) { return ret; } for (int i = 0; i < params.length; i++) { Object param = params[i]; // JSONObject json = (JSONObject) JSONConvertor.serializable(param); Object json = JSONConvertor.serializable(param); ret.put(json); } return ret; } // 得到请求的字符串 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; } }