/* * Copyright (C) 2010 mAPPn.Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mappn.gfan.common; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; import org.json.JSONException; import org.json.JSONObject; import android.content.pm.PackageInfo; import android.text.TextUtils; import com.mappn.gfan.Session; import com.mappn.gfan.common.codec.digest.DigestUtils; import com.mappn.gfan.common.util.SecurityUtil; import com.mappn.gfan.common.util.Utils; import com.mappn.gfan.common.vo.UpgradeInfo; /** * 这个类是获取API请求内容的工厂方法 * * @author andrew * @date 2011-4-21 * */ public class ApiRequestFactory { private static ArrayList<Integer> S_XML_REQUESTS = new ArrayList<Integer>(); private static ArrayList<Integer> S_JSON_REQUESTS = new ArrayList<Integer>(); private static ArrayList<Integer> S_ENCRYPT_REQUESTS = new ArrayList<Integer>(); private static ArrayList<Integer> S_ENCODE_FORM_REQUESTS = new ArrayList<Integer>(); static { S_XML_REQUESTS.add(MarketAPI.ACTION_GET_HOME_RECOMMEND); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_CATEGORY); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_SEARCH_KEYWORDS); S_XML_REQUESTS.add(MarketAPI.ACTION_SEARCH); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_TOP_RECOMMEND); S_XML_REQUESTS.add(MarketAPI.ACTION_CHECK_NEW_SPLASH); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_RANK_BY_CATEGORY); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_GROW_FAST); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_DETAIL); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_PRODUCT_DETAIL); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_COMMENTS); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_MYRATING); S_XML_REQUESTS.add(MarketAPI.ACTION_ADD_COMMENT); S_XML_REQUESTS.add(MarketAPI.ACTION_ADD_RATING); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_ALL_CATEGORY); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_PRODUCTS); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_TOPIC); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_RECOMMEND_PRODUCTS); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_REQUIRED); S_XML_REQUESTS.add(MarketAPI.ACTION_GET_DOWNLOAD_URL); S_XML_REQUESTS.add(MarketAPI.ACTION_CHECK_UPGRADE); S_XML_REQUESTS.add(MarketAPI.ACTION_CHECK_NEW_VERSION); S_XML_REQUESTS.add(MarketAPI.ACTION_PURCHASE_PRODUCT); S_XML_REQUESTS.add(MarketAPI.ACTION_SYNC_CARDINFO); S_XML_REQUESTS.add(MarketAPI.ACTION_QUERY_CHARGE_BY_ORDERID); S_XML_REQUESTS.add(MarketAPI.ACTION_SYNC_BUYLOG); S_XML_REQUESTS.add(MarketAPI.ACTION_SYNC_APPS); // JSON S_JSON_REQUESTS.add(MarketAPI.ACTION_BIND_ACCOUNT); S_JSON_REQUESTS.add(MarketAPI.ACTION_GET_ALIPAY_ORDER_INFO); S_JSON_REQUESTS.add(MarketAPI.ACTION_QUERY_ALIPAY_RESULT); // encrypt S_ENCRYPT_REQUESTS.add(MarketAPI.ACTION_REGISTER); S_ENCRYPT_REQUESTS.add(MarketAPI.ACTION_LOGIN); S_ENCRYPT_REQUESTS.add(MarketAPI.ACTION_GET_PAY_LOG); S_ENCRYPT_REQUESTS.add(MarketAPI.ACTION_CHARGE); S_ENCRYPT_REQUESTS.add(MarketAPI.ACTION_GET_BALANCE); // pay S_ENCODE_FORM_REQUESTS.add(MarketAPI.ACTION_GET_ALIPAY_ORDER_INFO); S_ENCODE_FORM_REQUESTS.add(MarketAPI.ACTION_QUERY_ALIPAY_RESULT); S_ENCODE_FORM_REQUESTS.add(MarketAPI.ACTION_BBS_SEARCH); } // justify the G-Header private static ArrayList<Integer> UCENTER_API = new ArrayList<Integer>(); static { UCENTER_API.add(MarketAPI.ACTION_REGISTER); UCENTER_API.add(MarketAPI.ACTION_LOGIN); UCENTER_API.add(MarketAPI.ACTION_GET_BALANCE); UCENTER_API.add(MarketAPI.ACTION_QUERY_CHARGE); UCENTER_API.add(MarketAPI.ACTION_PURCHASE_PRODUCT); UCENTER_API.add(MarketAPI.ACTION_GET_CONSUMESUM); UCENTER_API.add(MarketAPI.ACTION_GET_CONSUME_DETAIL); UCENTER_API.add(MarketAPI.ACTION_GET_PAY_LOG); UCENTER_API.add(MarketAPI.ACTION_CHARGE); UCENTER_API.add(MarketAPI.ACTION_SYNC_CARDINFO); UCENTER_API.add(MarketAPI.ACTION_QUERY_CHARGE_BY_ORDERID); } // 不需要进行缓存的API public static ArrayList<Integer> API_NO_CACHE_MAP = new ArrayList<Integer>(); static { API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_HOME_RECOMMEND); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_TOP_RECOMMEND); API_NO_CACHE_MAP.add(MarketAPI.ACTION_CHECK_NEW_SPLASH); API_NO_CACHE_MAP.add(MarketAPI.ACTION_REGISTER); API_NO_CACHE_MAP.add(MarketAPI.ACTION_LOGIN); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_BALANCE); API_NO_CACHE_MAP.add(MarketAPI.ACTION_QUERY_CHARGE); API_NO_CACHE_MAP.add(MarketAPI.ACTION_PURCHASE_PRODUCT); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_CONSUMESUM); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_CONSUME_DETAIL); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_PAY_LOG); API_NO_CACHE_MAP.add(MarketAPI.ACTION_CHARGE); API_NO_CACHE_MAP.add(MarketAPI.ACTION_SYNC_CARDINFO); API_NO_CACHE_MAP.add(MarketAPI.ACTION_QUERY_CHARGE_BY_ORDERID); API_NO_CACHE_MAP.add(MarketAPI.ACTION_BIND_ACCOUNT); API_NO_CACHE_MAP.add(MarketAPI.ACTION_UNBIND); API_NO_CACHE_MAP.add(MarketAPI.ACTION_ADD_COMMENT); API_NO_CACHE_MAP.add(MarketAPI.ACTION_ADD_RATING); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_COMMENTS); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_MYRATING); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_REQUIRED); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_ALIPAY_ORDER_INFO); API_NO_CACHE_MAP.add(MarketAPI.ACTION_QUERY_ALIPAY_RESULT); API_NO_CACHE_MAP.add(MarketAPI.ACTION_GET_DOWNLOAD_URL); } /** * 获取Market API HttpReqeust */ public static HttpUriRequest getRequest(String url, int action, HttpEntity entity, Session session) throws IOException { if (MarketAPI.ACTION_UNBIND == action) { HttpGet request = new HttpGet(url + session.getUid()); return request; } else if (UCENTER_API.contains(action)) { HttpPost request = new HttpPost(url); // update the User-Agent request.setHeader("User-Agent", session.getUCenterApiUserAgent()); request.setEntity(entity); return request; } else if (S_XML_REQUESTS.contains(action)) { HttpPost request = new HttpPost(url); // update the g-header request.setHeader("G-Header", session.getJavaApiUserAgent()); request.addHeader("Accept-Encoding", "gzip"); request.setEntity(AndroidHttpClient.getCompressedEntity(entity.getContent())); return request; } else { // for BBS search API HttpPost request = new HttpPost(url); request.setEntity(entity); return request; } } /** * 获取Market API HTTP 请求内容 * * @param action 请求的API Code * @param params 请求参数 * @return 处理完成的请求内容 * @throws UnsupportedEncodingException 假如不支持UTF8编码方式会抛出此异常 */ public static HttpEntity getRequestEntity(int action, Object params) throws UnsupportedEncodingException { if (S_XML_REQUESTS.contains(action)) { // 普通的XML请求内容 return getXmlRequest(params); } else if (S_ENCODE_FORM_REQUESTS.contains(action)) { // URL encode form 请求内容 return getFormRequest(action, params); } else if (S_JSON_REQUESTS.contains(action)) { // 普通的JSON请求内容 return getJsonRequest(action, params); } else if (S_ENCRYPT_REQUESTS.contains(action)) { // 加密的请求内容 return getEncryptRequest(action, params); } else { // 不需要请求内容 return null; } } /** * 获取标准的XML请求内容,采用utf8编码方式 * @return XML请求内容 * @throws UnsupportedEncodingException 假如不支持UTF8编码方式会抛出此异常 */ private static StringEntity getXmlRequest(Object params) throws UnsupportedEncodingException { String body = generateXmlRequestBody(params); Utils.D("generate XML request body is : " + body); return new StringEntity(body, HTTP.UTF_8); } /** * 获取标准的JSON请求内容,采用utf8编码方式 * @return JSON请求内容 * @throws UnsupportedEncodingException 假如不支持UTF8编码方式会抛出此异常 */ private static StringEntity getJsonRequest(int action, Object params) throws UnsupportedEncodingException { String body = generateJsonRequestBody(params); Utils.D("generate JSON request body is : " + body); return new StringEntity(body, HTTP.UTF_8); } /** * 获取加密后的请求内容 * @return ByteArrayEntity请求内容 */ private static ByteArrayEntity getEncryptRequest(int action, Object params) { String body = generateXmlRequestBody(params); Utils.D("generate request body before encryption is : " + body); // 加密处理 if (action == MarketAPI.ACTION_CHARGE) { final byte[] encyptedBody = SecurityUtil.encryptHttpChargeBody(body); return new ByteArrayEntity(encyptedBody); } else { final byte[] encyptedBody = SecurityUtil.encryptHttpBody(body); return new ByteArrayEntity(encyptedBody); } } /** * 获取标准的表单请求内容,采用utf8编码方式 * @return UrlEncodedFormEntity请求内容 * @throws UnsupportedEncodingException 假如不支持UTF8编码方式会抛出此异常 */ @SuppressWarnings("unchecked") private static UrlEncodedFormEntity getFormRequest(int action, Object params) throws UnsupportedEncodingException { if (action == MarketAPI.ACTION_GET_ALIPAY_ORDER_INFO || action == MarketAPI.ACTION_QUERY_ALIPAY_RESULT) { String body = generateJsonRequestBody(params); Utils.D("generate JSON request body is : " + body); final byte[] encyptedBody = SecurityUtil.encryptHttpChargePalipayBody(body); String dataenc = new String(encyptedBody, HTTP.UTF_8); String cno = "03"; String actionMethod = null; if (MarketAPI.ACTION_GET_ALIPAY_ORDER_INFO == action) { // 获取支付宝订单信息 actionMethod = "addAlipayOrder"; } else { // 查询支付宝充值结果 actionMethod = "queryAlipayOrderIsSuccess"; } final ArrayList<NameValuePair> postParams = new ArrayList<NameValuePair>(4); postParams.add(new BasicNameValuePair("action", actionMethod)); postParams.add(new BasicNameValuePair("data", dataenc)); postParams.add(new BasicNameValuePair("cno", cno)); postParams.add(new BasicNameValuePair("sign", DigestUtils.md5Hex("action=" + actionMethod + "&data=" + dataenc + "&cno=" + cno + SecurityUtil.KEY_HTTP_CHARGE_ALIPAY))); return new UrlEncodedFormEntity(postParams, HTTP.UTF_8); } else if (params instanceof ArrayList) { return new UrlEncodedFormEntity((ArrayList<NameValuePair>) params, HTTP.UTF_8); } return null; } /** * Generate the API XML request body */ @SuppressWarnings("unchecked") private static String generateXmlRequestBody(Object params) { if (params == null) { return "<request version=\"2\"></request>"; } HashMap<String, Object> requestParams; if (params instanceof HashMap) { requestParams = (HashMap<String, Object>) params; } else { return "<request version=\"2\"></request>"; } final StringBuilder buf = new StringBuilder(); // TODO: add local_version parameter if exist // 2010/12/29 update version to 2 to get comments from bbs buf.append("<request version=\"2\""); if (requestParams.containsKey("local_version")) { buf.append(" local_version=\"" + requestParams.get("local_version") + "\" "); requestParams.remove("local_version"); } buf.append(">"); // add parameter node final Iterator<String> keySet = requestParams.keySet().iterator(); while (keySet.hasNext()) { final String key = keySet.next(); if ("upgradeList".equals(key)) { buf.append("<products>"); List<PackageInfo> productsList = (List<PackageInfo>) requestParams.get(key); for (PackageInfo info : productsList) { buf.append("<product package_name=\"").append(info.packageName); buf.append("\" version_code=\"").append(info.versionCode).append("\"/>"); } buf.append("</products>"); continue; } else if ("appList".equals(key)) { buf.append("<apps>"); List<UpgradeInfo> productsList = (List<UpgradeInfo>) requestParams.get(key); for (UpgradeInfo info : productsList) { buf.append("<app package_name=\"").append(info.pkgName); buf.append("\" version_code=\"").append(info.versionCode); buf.append("\" version_name=\"").append(info.versionName); buf.append("\" app_name=\"").append(wrapText(info.name)); // buf.append("\" md5=\"").append(info.md5); buf.append("\"/>"); } buf.append("</apps>"); continue; } buf.append("<").append(key).append(">"); buf.append(requestParams.get(key)); buf.append("</").append(key).append(">"); } // add the enclosing quote buf.append("</request>"); return buf.toString(); } /** * Generate the API JSON request body */ @SuppressWarnings("unchecked") private static String generateJsonRequestBody(Object params) { if (params == null) { return ""; } HashMap<String, Object> requestParams; if (params instanceof HashMap) { requestParams = (HashMap<String, Object>) params; } else { return ""; } // add parameter node final Iterator<String> keySet = requestParams.keySet().iterator(); JSONObject jsonObject = new JSONObject(); try { while (keySet.hasNext()) { final String key = keySet.next(); jsonObject.put(key, requestParams.get(key)); } } catch (JSONException e) { e.printStackTrace(); return ""; } return jsonObject.toString(); } private static final String[] REPLACE = { "&", "&", "\"", """, "'", "'", "<", "<", ">", ">" }; private static String wrapText(String input) { if (!TextUtils.isEmpty(input)) { for (int i = 0, length = REPLACE.length; i < length; i += 2) { input = input.replace(REPLACE[i], REPLACE[i + 1]); } return input; } else { return ""; } } }