手机端后台向前台传输数据的二进制压缩方法

后端取出数据后发给前端,原本我们使用json格式传输,每次传输将近1k左右,但是为了给用户省流量,我们采取先把json去掉每一个key,转换为二进制,然后gzip压缩,这样操作下来节省了70%的数据量,效果很好。

具体方法:
原有返回格式是这样
<StoresList>
<return>
      {
      "status": {
      "request_status": "0",
      "error_code": "BTMes0100002",
      "error_msg": "success"
      },
      "bizobj": [
      {
      "STORE_ID": 1,
      "STORE_NAME": "肯德基",
      "STORE_PHONE": "4008-823823",
      "STORE_ADDRESS": "文二路肯德基店",
      "STORE_LAT": "30.33331",
      "STORE_LONG": "120.22221",
      "PHOTO_TYPE": 2,
      "RESOLUTION_TYPE": 2,
      "PHOTO_URL": "http://www.kendeji.com/a.jpg"
      }, {
      "STORE_ID": 2,
      "STORE_NAME": "麦当劳",
      "STORE_PHONE": "15233336666",
      "STORE_ADDRESS": "文一路麦当劳店",
      "STORE_LAT": "30.33332",
      "STORE_LONG": "120.22222",
      "PHOTO_TYPE": 2,
      "RESOLUTION_TYPE": 2,
      "PHOTO_URL": "http://www.maidanglao.com/a.jpg"
      }  ],
      "page_info": {
      "cur_page": "1",
      "page_size": "12",
      "total_items": "3"
      }
      }
    </return>
  </StoresList>


我们约定每一个属性的长度,在一个xml文件中写成这样
<storeList id="status">							
	<request_status>4</request_status>
	<error_code>4</error_code>
	<error_msg>40</error_msg>	
</storeList>	
<storeList id="page_info">
	<cur_page>4</cur_page>
	<page_size>4</page_size>
	<total_items>4</total_items>	
</storeList>	
<storeList id="bizobj">		
		<STORE_ID>4</STORE_ID>
		<STORE_NAME>50</STORE_NAME>
		<STORE_PHONE>16</STORE_PHONE>
		<STORE_ADDRESS>50</STORE_ADDRESS>			
		<STORE_LAT>12</STORE_LAT>
		<STORE_LONG>12</STORE_LONG>		
		<PHOTO_TYPE>4</PHOTO_TYPE>
		<RESOLUTION_TYPE>4</RESOLUTION_TYPE>		
		<PHOTO_URL>50</PHOTO_URL>		
		<CLASS_ID>4</CLASS_ID>			
		<STORE_URL>50</STORE_URL>	
		<distance>6</distance>	
</storeList>

然后依次遍历每个storelist下的节点的ElementName以及ElementValue ,即可通过elementName得到json中的值,通过elementValue来给json中的值转换为byte[],并且前补零。
最后把要拼装的jsonobject或者jsonarray的byte数组拼装成一个byte【】,然后对其gzip即可
public class BinaryUtil {
	/**
	 * jsonobj转换为byte数组
	 * @param jsonObj
	 * @param charset
	 * @param xmlParameter
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws DocumentException
	 */
	public static byte[] convertJsonObj2ByteArray(JSONObject jsonObj, String charset,
			XmlParameter xmlParameter) throws UnsupportedEncodingException,
			DocumentException {
		List<Jsonvalue> list = new ArrayList<Jsonvalue>();
		List<XmlBean> xmllist = combineBizobj(xmlParameter);
		for (XmlBean bean : xmllist) {
			String name = jsonObj.getString(bean.getAttributeName());
			Integer value = bean.getAttributeValue();
			list.add(change2Jsonvalue(name, value, charset));
		}
		return combineList(list, charset);
	}

	/**
	 * jsonarray转换为byte数组
	 * @param jsonArray
	 * @param charset
	 * @param xmlParameter
	 * @return
	 * @throws DocumentException
	 * @throws UnsupportedEncodingException
	 */
	public static byte[] convertJsonArray2ByteArray(JSONArray jsonArray,
			String charset, XmlParameter xmlParameter)
			throws DocumentException, UnsupportedEncodingException {
		if (jsonArray == null) {
			return null;
		}
		int arraySize = jsonArray.size();
		List<Jsonvalue> list = new ArrayList<Jsonvalue>();
		List<XmlBean> xmllist = combineBizobj(xmlParameter);
		for (int i = 0; i < arraySize; i++) {
			for (XmlBean bean : xmllist) {
				String name = jsonArray.getJSONObject(i).getString(
						bean.getAttributeName());
				Integer value = bean.getAttributeValue();
				list.add(change2Jsonvalue(name, value, charset));
			}
		}
		return combineList(list, charset);
	}

	/**
	 * 合并多个byte数组,合并后的长度为多个子数组的和
	 * @param charset
	 * @param firstByteArray
	 * @param secondByteArray
	 * @param objects
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static byte[] combineByteArray(String charset,byte[] firstByteArray,
			byte[] secondByteArray, Object... objects) throws UnsupportedEncodingException {
		if (firstByteArray == null) {
			return secondByteArray;
		} else if (secondByteArray == null) {
			return firstByteArray;
		} else {
			StringBuffer sb=new StringBuffer();
			sb.append(new String(firstByteArray));
			sb.append(new String(secondByteArray));
			
			if (objects != null) {
				int j = objects.length;
				for(int i=0;i<j;i++){
					sb.append(new String((byte[])objects[i]));
				}
			}
			return sb.toString().getBytes(charset);
		}
	}

	/**
	 * 获得一个接口对应的所有的id
	 * @param xmlParameter
	 * @return
	 * @throws DocumentException
	 */
	public static List<String> getIds(XmlParameter xmlParameter)
			throws DocumentException {
		List<String> list = new ArrayList<String>();
		List<Element> elist = getElementList(xmlParameter);
		for (Element e : elist) {
			list.add(e.attributeValue("id"));
		}
		return list;
	}
	
	/**
	 * gzip压缩数据
	 * @param data
	 * @return
	 * @throws IOException
	 */
	public static byte[] gzipData(byte[] data) throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		GZIPOutputStream gzos = new GZIPOutputStream(bos);
		gzos.write(data);
		gzos.close();
		return bos.toByteArray();
	}

	/**
	 * 获得接口名称对应的配置元素列表
	 * @param method
	 * @return
	 * @throws DocumentException
	 */
	@SuppressWarnings("unchecked")
	private static List<Element> getElementList(XmlParameter xmlParameter)
			throws DocumentException {
		SAXReader saxReader = new SAXReader();
		Document document = saxReader.read(xmlParameter.getXmlPath());
		Element root = document.getRootElement();
		List<Element> elist = root.selectNodes(xmlParameter.getElementName());
		return elist;
	}

	

	private static byte[] combineList(List<Jsonvalue> list, String charset)
			throws UnsupportedEncodingException {
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < list.size(); i++) {
			result.append(new String(list.get(i).getB()));
		}
		String f = result.toString();
		return f.getBytes(charset);
	}

	/**
	 * 前补零
	 * @throws UnsupportedEncodingException 
	 */
	private static byte[] fillZero(String charset,byte[] s, int bytesSize) throws UnsupportedEncodingException {
		byte[] zreo = new byte[1];
		zreo[0] = 0;
		while (s.length < bytesSize) {
			s = combineByteArray(charset,zreo, s);
		}
		return s;
	}

	private static Jsonvalue change2Jsonvalue(String value, Integer length,
			String charset) throws UnsupportedEncodingException {
		Jsonvalue jv = new Jsonvalue(fillZero(charset,value.getBytes(charset), length),
				length);
		return jv;
	}

	/**
	 * 获得一个element对应的所有节点
	 * 
	 * @param xmlParameter
	 * @return
	 * @throws DocumentException
	 */
	@SuppressWarnings("unchecked")
	private static List<XmlBean> combineBizobj(XmlParameter xmlParameter)
			throws DocumentException {
		List<XmlBean> list = new ArrayList<XmlBean>();
		SAXReader saxReader = new SAXReader();
		Document document = saxReader.read(xmlParameter.getXmlPath());
		Element root = document.getRootElement();
		List<Element> elist = root.selectNodes(xmlParameter.getElementName());
		for (Element e : elist) {
			if (e.attribute("id").getValue()
					.equalsIgnoreCase(xmlParameter.getElementId())) {
				List<Element> list1 = e.elements();
				for (Element ee : list1) {
					XmlBean xmlBean = new XmlBean(ee.getName(),
							Integer.parseInt(ee.getData().toString()));
					list.add(xmlBean);
				}
			}
		}
		return list;
	}
}


压缩包见附件包含本身的jar以及依赖的jar

你可能感兴趣的:(手机端后台向前台传输数据的二进制压缩方法)