/**

 * 
 */
package com.umessage.splat.web.servlet;
 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
 
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import com.umessage.splat.core.utils.DesUtils;
import com.umessage.splat.core.utils.FileUtils;
import com.umessage.splat.core.utils.HttpUtils;
import com.umessage.splat.core.utils.PublicReader;
import com.umessage.splat.core.utils.SpringUtil;
import com.umessage.splat.core.utils.Xstream;
import com.umessage.splat.web.aspect.target.Splat;
 
/**
 * 客户端请求入口
 * 
 * @author xugang
 * 
 */
public class ClientEntranceServlet extends HttpServlet {
private static final Logger log = LoggerFactory.getLogger(ClientEntranceServlet.class);
private static final long serialVersionUID = -224091407405073218L;
 
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doPost(request, response);
}
 
@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// String businessPath = "http://localhost:9090/";
String businessPath = "http://localhost:8080/splat-web/";
OutputStream outStream = response.getOutputStream();
Map actions = generateReqParameters(reader(request));
Set> actSet = actions.entrySet();
 
for (Map.Entry ent : actSet) {
long start = System.currentTimeMillis();
String key = ent.getKey();
String[] keys = key.split("&");
String action = keys[0];
String requuid = keys[1];
Object params = ent.getValue();
 
log.debug("当前业务请求是{},请求参数包括:{}, 请求地址:{}", new String[] { action, params.toString(), businessPath + action });
 
outStream.write(requuid.getBytes());// 写入UUID
byte[] data = HttpUtils.fetchEntity(businessPath + action, (Map) params);
byte[] pack = null;
if (FileUtils.isZIP(data)) {
pack = data;
} else {
pack = PublicReader.compressToByte(data);
}
 
outStream.write(Xstream.changebytelength(pack.length).getBytes());// 写入长度
outStream.write(pack);// 写入数据
 
long end = System.currentTimeMillis();
log.debug(">>>>>>请求接口[{}]耗时[{}]ms", businessPath + action, end - start);
 
// 收集日志信息供外部使用
callSplat(action, 200, request.getRemoteAddr(), request.getRequestURI(), request.getMethod(), end - start, (Map) params);
}
outStream.flush();
// response.setCharacterEncoding("UTF-8");
 
}
 
/**
* 获取业务请求地址
* @param request
* @return
*/
@SuppressWarnings("unused")
private String getUrl(HttpServletRequest request) {
String url = request.getRequestURL().toString();
String uri = request.getRequestURI();
String ctx = request.getContextPath();
String businessPath = url.split(uri)[0] + ctx + "/";
return businessPath;
}
 
/**
* 解压、解密请求参数
* 前两位是TAG,接着8位密钥,然后是压缩后的消息体。 对消息题解压后,进行DES解密
* @param request
* @return
*/
private String reader(HttpServletRequest request) {
try {
 
InputStream input = request.getInputStream();
byte[] pack = IOUtils.toByteArray(input);// 用户发送的原始数据
 
byte[] key = new byte[8]; // 密钥
byte[] body = new byte[pack.length - 10]; // 有效的数据体
 
System.out.println("recv data length {{{" + pack.length + "}}}");
System.arraycopy(pack, 2, key, 0, key.length);// 取出密钥
System.arraycopy(pack, 10, body, 0, body.length);// 取出消息体
 
byte[] unpack = PublicReader.uncompressToStringback(body);// 解压后的数据
String jsonstr = DesUtils.parseSignback(unpack, new String(key, "UTF-8"));
log.info("客户端请求明文:{}", jsonstr);
return jsonstr;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
 
/**
* 生成HTTP GET请求参数
* @param str
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Map generateReqParameters(String str) {
// 业务请求及参数
Map actions = new HashMap();
try
{
JSONObject jsonObject = JSONObject.fromObject(str);
Map pubParams = new HashMap();
pubParams.put("pub.CP_CH", StringUtils.isNotBlank(jsonObject.optString("CP_CH")) ? jsonObject.optString("CP_CH").trim() : "");
pubParams.put("pub.CP_CITYID", StringUtils.isNotBlank(jsonObject.optString("CP_CITYID")) ? jsonObject.optString("CP_CITYID").trim() : "");
pubParams.put("pub.CP_IMEI", StringUtils.isNotBlank(jsonObject.optString("CP_IMEI")) ? jsonObject.optString("CP_IMEI").trim() : "");
pubParams.put("pub.CP_MODEL", StringUtils.isNotBlank(jsonObject.optString("CP_MODEL")) ? jsonObject.optString("CP_MODEL").trim() : "");
pubParams.put("pub.CP_PLTFM", StringUtils.isNotBlank(jsonObject.optString("CP_PLTFM")) ? jsonObject.optString("CP_PLTFM").trim() : "");
pubParams.put("pub.CP_PRT", StringUtils.isNotBlank(jsonObject.optString("CP_PRT")) ? jsonObject.optString("CP_PRT").trim() : "");
pubParams.put("pub.CP_RATIO", StringUtils.isNotBlank(jsonObject.optString("CP_RATIO")) ? jsonObject.optString("CP_RATIO").trim() : "");
pubParams.put("pub.CP_TOUCH", StringUtils.isNotBlank(jsonObject.optString("CP_TOUCH")) ? jsonObject.optString("CP_TOUCH").trim() : "");
pubParams.put("pub.CP_UID", StringUtils.isNotBlank(jsonObject.optString("CP_UID")) ? jsonObject.optString("CP_UID").trim() : "");
pubParams.put("pub.CP_VER", StringUtils.isNotBlank(jsonObject.optString("CP_VER")) ? jsonObject.optString("CP_VER").trim() : "");
pubParams.put("pub.CP_PHONENUM", StringUtils.isNotBlank(jsonObject.optString("CP_PHONENUM")) ? jsonObject.optString("CP_PHONENUM").trim() : "");
pubParams.put("pub.CP_TPL", StringUtils.isNotBlank(jsonObject.optString("CP_TPL")) ? jsonObject.optString("CP_TPL").trim() : "");
pubParams.put("pub.CP_RESVER", StringUtils.isNotBlank(jsonObject.optString("CP_RESVER")) ? jsonObject.optString("CP_RESVER").trim() : "");
pubParams.put("pub.CP_PUBRESPATH", StringUtils.isNotBlank(jsonObject.optString("CP_PUBRESPATH")) ? jsonObject.optString("CP_PUBRESPATH").trim() : "");
pubParams.put("pub.CP_LON", StringUtils.isNotBlank(jsonObject.optString("CP_LON")) ? jsonObject.optString("CP_LON").trim() : "");
pubParams.put("pub.CP_LAT", StringUtils.isNotBlank(jsonObject.optString("CP_LAT")) ? jsonObject.optString("CP_LAT").trim() : "");
 
JSONArray jsonArray = jsonObject.getJSONArray("actions");
for (int i = 0; i < jsonArray.size(); i++) {
Map priParams = new HashMap();
String body = jsonArray.getString(i);
JSONObject jsonBody = JSONObject.fromObject(body);
String action = jsonBody.optString("action");
String requuid = jsonBody.optString("requuid");
 
String paras = jsonBody.optString("paras");
Map jsonParas = parserToMap(paras);
Set> paraSet = jsonParas.entrySet();
for (Map.Entry entry : paraSet) {
String key = entry.getKey();
String value = entry.getValue();
// 处理分页数据
if ("ps".equals(key)) {
priParams.put("page.size", StringUtils.isNotBlank(value) ? value : "10");
continue;
}
if ("pn".equals(key)) {
priParams.put("page.page", StringUtils.isNotBlank(value) ? String.valueOf(Integer.valueOf(value) + 1) : "1");
continue;
}
priParams.put(key, value);
}
priParams.putAll(pubParams);
actions.put(action + "&" + requuid, priParams);
}
}
catch(Exception ex)
{
  ex.printStackTrace();
}
return actions;
}
 
/**
* 将JSON格式字符串转换成Map对象
* @param s
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private static Map parserToMap(String s) {
Map map = new HashMap();
JSONObject json = JSONObject.fromObject(s);
Iterator keys = json.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
String value = json.get(key).toString();
if (value.startsWith("{") && value.endsWith("}")) {
map.put(key, parserToMap(value));
} else {
map.put(key, value);
}
 
}
return map;
}
 
/**
* 传递请求参数到系统日志信息目标对象
* @param action
*            业务接口名称
* @param state
*            HTTP响应状态码
* @param ip
*            请求方的IP地址
* @param uri
*            请求的资源描述
* @param method
*            请求的方法(GET / POST)
* @param time
*            从请求开始到处理完成的时间
* @param parameters
*            请求的原始参数
*/
private void callSplat(String action, int state, String ip, String uri, String method, long time, Map parameters) {
Splat splat = (Splat) SpringUtil.getBean("splatImpl");
splat.setAction(action);
splat.setState(state);
splat.setIp(ip);
splat.setUri(uri);
splat.setMethod(method);
splat.setTime(time);
splat.setParameters(parameters);
splat.call();
}
 
public static void main(String[] args) {
String str = "{\"actions\":[{\"paras\":{\"aaa\":\"s8888\",\"lat\":\"39.96922\",\"lon\":\"116.43587\",\"zoom\":\"1\"},\"action\":\"searchbycoupon\",\"requuid\":\"44F9145E-6672-434B-BEA8-415881ED8CB4\"},{\"paras\":{\"lat\":\"39.9r6922\",\"lon\":\"116.43f587\",\"zoom\":\"1\"},\"action\":\"getInverseGeo222\",\"requuid\":\"44F9145E-6672-434B-BEA8-415881ED8CB4\"}],\"CP_PRT\":\"lifeserach\",\"CP_PUBRESPATH\":\"/user/resoruce\",\"CP_UID\":\"34324523452523\",\"CP_PLTFM\":\"iphone\",\"CP_TOUCH\":\"1\",\"CP_CITYID\":\"1000\",\"CP_IMEI\":\"114234123\",\"CP_LON\":\"222\",\"CP_CH\":\"xxx\",\"CP_MODEL\":\"iphone\",\"CP_RATIO\":\"800*233\",\"CP_TPL\":\"iphone\",\"CP_VER\":\"2.6\",\"CP_RESVER\":\"1.0\",\"CP_PHONENUM\":\"12332223432\",\"CP_LAT\":\"111\"}";
Map actions = generateReqParameters(str);
Set> entSet = actions.entrySet();
for (Map.Entry entry : entSet) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
 
}
 
}