package com.jqmobile.core.http;
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.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import com.jqmobile.core.utils.json.JSONArray;
import com.jqmobile.core.utils.json.JSONConvertor2;
import com.jqmobile.core.utils.json.JSONException;
import com.jqmobile.core.utils.json.JSONObject;
/**
* HTTP通讯工具
* <p>此接口不满足久其移动通用客户端简化通讯协议,于2014-3-17停止维护。原所有使用者请于2014-12-30前调整完毕
* <p>2014-3-17停止维护,后续请使用com.jqmobile.core.http2.HttpUtils
* @author MODI
*
* @project com.jiuqi.mobile.core
* @date 2013年11月20日
*/
@Deprecated
public abstract class HttpUtils implements HttpInvoke {
public static final String HTTP_CONNTENT_TYPE = "text/html";
public static final String CHARSET = "UTF-8";
public static final String RESPONSE_DATA = "response_data";
public static final String REQUEST_ERRORED = "request_errored";
// error
public static final String RESPONSE_ERROR_MSG = "response_error_msg";
public static final String RESPONSE_ERROR_EXCEPTION_CLASS = "exception_class";
public static final String REQUEST_DATA = "request_data";
public static final String REQUEST_TAG_INTF_NAME = "intf";
public static final String REQUEST_TAG_METHOD_NAME = "method";
public static final String REQUEST_TAG_ARGS = "args";
public static final String REQUEST_SESSION = "session";
public static final String RESPONSE_SESSION = "^-session~!@#";
public static final String CLASS_TAG = "class";
private static int TIMEOUT = 10000;
// =======================================
public static void setTIMEOUT(int tIMEOUT) {
TIMEOUT = tIMEOUT;
}
public static int getTIMEOUT() {
return TIMEOUT;
}
public static HttpUtils getHttpUtils(String url, String uri) {
return new HttpClientImpl(url, uri);
}
public static HttpUtils getHttpUtils(String url, String uri,
String sessionId) {
HttpClientImpl impl = new HttpClientImpl(url, uri);
impl.sessionID = sessionId;
return impl;
}
public static String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
// =======================================
String sessionID;
static class HttpClientImpl extends HttpUtils {
private final String url, uri;
public HttpClientImpl(String url, String uri) {
super();
this.url = url;
this.uri = uri;
}
@Override
public Object invoke(String intfName, String methodName, Object... args)
throws Throwable {
JSONArray params = JSONConvertor2.serializableArray(args);
String serviceURL = url + uri;
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;
// if(null == sessionID && ret.has(HttpUtils.RESPONSE_SESSION)){
// sessionID = ret.getString(HttpUtils.RESPONSE_SESSION);
// ret.remove(HttpUtils.RESPONSE_SESSION);
// }
return JSONConvertor2.unSerializable(ret);
// 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;
}
// return null;
}
// 执行
private Object doPost(HttpURLConnection conn, String intfName,
String methodName, JSONArray params) throws Throwable {
PrintWriter out = new PrintWriter(new OutputStreamWriter(
conn.getOutputStream(), CHARSET));
String requestString = getRequestString(intfName, methodName,
params);
out.print(requestString);
out.flush();
out.close();
StringBuilder sResult = new StringBuilder();
conn.setConnectTimeout(TIMEOUT);
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream httpInput = null;
BufferedReader httpReader = null;
// 读取数据
httpInput = conn.getInputStream();
httpReader = new BufferedReader(new InputStreamReader(
httpInput, CHARSET));
String line = null;
while ((line = httpReader.readLine()) != null) {
if (sResult.length() > 0) {
sResult.append("\n");
}
sResult.append(line);
}
} else {
throw new HttpFailException("请求服务器失败");
}
if(sResult.toString().isEmpty()){
return null;
}
JSONObject result = new JSONObject(sResult.toString());
boolean error = result.getBoolean(REQUEST_ERRORED);
if (error) {
String errorMsg = "";
if (result.has(RESPONSE_ERROR_MSG)) {
errorMsg = result.getString(RESPONSE_ERROR_MSG);
}
if (result.has(RESPONSE_ERROR_EXCEPTION_CLASS)) {
try {
String eClass = result
.getString(RESPONSE_ERROR_EXCEPTION_CLASS);
if(eClass.endsWith("SessionExceedTimeException")){
this.sessionID = null;
throw new SessionExceedTimeException(errorMsg);
}
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 HttpRequestErrorException("服务器未知异常");
} else
throw new HttpRequestErrorException(errorMsg);
} else {
if(null == sessionID && result.has(HttpUtils.RESPONSE_SESSION)){
Object o = result.get(HttpUtils.RESPONSE_SESSION);
if(o instanceof JSONArray){
sessionID = ((JSONArray) o).getString(0);
}else if(o instanceof String){
sessionID = (String) o;
}
result.remove(HttpUtils.RESPONSE_SESSION);
}
if (!result.has(RESPONSE_DATA)) {
return null;
}
try {
JSONObject resultData = result.getJSONObject(RESPONSE_DATA);
return resultData;
} catch (JSONException e) {
Object obj = result.get(RESPONSE_DATA);
return obj;
}
}
}
// 得到请求的字符串
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(REQUEST_TAG_INTF_NAME, intfName);
ret.put(REQUEST_TAG_METHOD_NAME, methodName);
ret.put(REQUEST_TAG_ARGS, params);
ret.put(REQUEST_SESSION, sessionID);
return ret;
}
}
// 连接
/**
* 通过URL建立连接
* @param url
* @return
* @throws IOException
*/
public HttpURLConnection connect(String url) throws IOException {
URL _url = null;
try {
_url = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
HttpURLConnection conn = null;
//
conn = (HttpURLConnection) _url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
conn.setRequestProperty("Content-type", HTTP_CONNTENT_TYPE);
conn.setRequestProperty("Charset", CHARSET);
conn.setRequestProperty(REQUEST_SESSION, sessionID);
conn.setConnectTimeout(TIMEOUT);
conn.connect();
//
return conn;
}
}