移动开发中的通信架构(四)

本文介绍了一个名为HttpClient的网络请求类,该类负责打开网络链接、获取数据,并将数据存储为字节数组供Response类解析。文章详细展示了HttpClient类的实现代码,并提供了Response类的相关代码以展示数据解析过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

这篇文章讲解真正的网络请求类HttpClient,它负责打开网络链接,获取数据,把数据存放于一个字节数组,让Response解析。

以下是代码:

package app.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

import app.program.GameConst;

/**
 * 功能:
 * 
 * 打开网络链接,获取数据,把数据存放于一个字节数组,让Response解析
 */
public class HttpClient {
	// 注: HttpsConnection继承自HttpConnection
	private HttpConnection conn = null;

	private InputStream inputStream = null;

	private OutputStream outputStream = null;

	private Request request = null;

	int msgId;


	public HttpClient(int _msgId) {
		msgId = _msgId;
	}

	public Response getResponse(Request request) throws Exception {
		if (request == null) {
			return null;
		}

		try {
			this.request = request;

			Response resp = new Response();

			// 打开链接
			makeConnection();
			// 设置参数
			setProperty();
			// 写入内容
			setContent();
			// 打开输入流
			makeInputStream();
			// 得到响应码
			resp.responseCode = conn.getResponseCode();
			if (resp.responseCode != HttpConnection.HTTP_OK) {
				return null;
			}

			String strContentLength = conn.getHeaderField("content-length");

			if (strContentLength != null) {
				resp.contentLength = Integer.parseInt(strContentLength);
			}

			resp.analysisData(readResponse(), true);

			return resp;

		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			this.request = null;
			cleanup();
		}
	}

	private void makeConnection() throws Exception {
		conn = (HttpConnection) Connector.open("http://", Connector.READ_WRITE, true);
	}

	private void makeInputStream() throws Exception {
		inputStream = conn.openInputStream();
	}

	private void makeOutputStream() throws Exception {
		outputStream = conn.openOutputStream();
	}

	/**
	 * 参数设置
	 * 
	 * @throws Exception
	 */
	private void setProperty() throws Exception {
		conn.setRequestMethod(HttpConnection.POST);
	}

	public void setContent() throws Exception {
		if (request.getContent() != null) {
			conn.setRequestProperty("Content-Length", String.valueOf(request.getContent().length));
			makeOutputStream();
			outputStream.write(request.getContent());
		}
	}

	/**
	 * 从网络流中读取数据,存放于字节数组中
	 * 
	 * @return
	 * @throws Exception
	 */
	private byte[] readResponse() throws Exception {
		try {
			byte[] data = null;
			if (conn != null && inputStream != null) {
				int len = (int) conn.getLength();
				// 读取模式1:直接获取数据长度

				if (conn.getRequestMethod().equals(HttpConnection.HEAD)) {

					return null;
				}

				if (len <= 0) {
					// 读取模式2:从Http连接头获取数据长度
					String bodyLength = null;
					try {
						bodyLength = conn.getHeaderField("content-length");
					} catch (IOException e) {
						e.printStackTrace();
					}

					if (bodyLength != null) {
						try {
							len = Integer.parseInt(conn.getHeaderField("Body-Length"));
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}

				if (len > 0) {
					int actual = 0;
					int bytesread = 0;
					data = new byte[len];
					while ((bytesread != len) && (actual != -1)) {
						actual = inputStream.read(data, bytesread, len - bytesread);
						if (actual >= 0) {
							bytesread += actual;
						}
					}

					if (bytesread == 0) {
						return null;
					} else if (bytesread < len) {
						byte[] actualData = new byte[bytesread];
						System.arraycopy(data, 0, actualData, 0, bytesread);

						return actualData;
					}
				} else {
					// 读取模式3:持续读取,直到数据包结束
					ByteArrayOutputStream tmp = new ByteArrayOutputStream();
					byte[] buffer = new byte[HttpConstants.BUFFER_SIZE];
					int count;
					while ((count = inputStream.read(buffer, 0, HttpConstants.BUFFER_SIZE)) != -1) {
						tmp.write(buffer, 0, count);
					}
					data = tmp.toByteArray();
					tmp.close();
					tmp = null;
					buffer = null;
				}
			}
			return data;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public void cleanup() {
		try {
			if (inputStream != null) {
				inputStream.close();
				inputStream = null;
			}
			if (outputStream != null) {
				outputStream.close();
				outputStream = null;
			}
			if (conn != null) {
				conn.close();
				conn = null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


重点关注方法是:

                     public Response getResponse(Request request) throws Exception;

代码里面涉及了Response和StructResponse,它们的代码页一并罗列:

 

package app.http;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;

import app.program.Globe;

/**
 * 返回信息的解析方法类,和StructRequest对应
 */
public class StructResponse {
	private DataInputStream in;
	private ByteArrayInputStream bin;

	private Hashtable hash;
	private Vector vec;

	private int size;

	public StructResponse(byte[] data) {
		bin = new ByteArrayInputStream(data);
		in = new DataInputStream(bin);
	}

	public StructResponse(byte[] data, boolean bTradeCipher) {
		hash = new Hashtable();
		vec = new Vector();
		if (!bTradeCipher) {
			readTradeData(data);
		} else {
			readTradeCipherData(data);
		}
		this.getTable();
	}

	private boolean bTable = false;
	private int tableIndex = 0; // 表格数据的列数

	private void readTradeData(byte[] data) {
		int i = 0;
		try {
			for (; i < data.length; i++) {
				if (data[i] == 0x01) {
					String s = new String(data, 0, i, "UTF-8");
					if (bTable) {
						vec.addElement(s);
						if (tableIndex == 0) {
							tableIndex = vec.size();
						}
					} else {
						putInHash(s);
					}
					break;
				} else if (data[i] == 0x02) {
					String s = new String(data, 0, i, "UTF-8");
					if (bTable) {
						vec.addElement(s);
					} else {
						putInHash(s);
					}
					break;
				} else if (data[i] == 0x03) {
					bTable = true;
					if (i > 0) {
						String s = new String(data, 0, i, "UTF-8");
						putInHash(s);
					}
					break;
				} else if (data[i] == 0x04) {
					bTable = false;
					String s = new String(data, 0, i, "UTF-8");
					vec.addElement(s);
					if (tableIndex == 0) {
						tableIndex = vec.size();
					}
					break;
				}
			}

			String s = new String(data, 0, i, "UTF-8");
			putInHash(s);

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		if (data.length - i - 1 > 0) {
			byte[] nData = new byte[data.length - i - 1];
			System.arraycopy(data, i + 1, nData, 0, data.length - i - 1);
			readTradeData(nData);
		}
	}

	private void readTradeCipherData(byte[] data) {
		for (int i = 0; i < data.length; i++) {
			data[i] = (byte) (data[i] ^ Globe.key[i % Globe.key.length]);
		}
		readTradeData(data);
	}

	private void putInHash(String s) {
		int index = s.indexOf("=");
		if (index >= 0) {
			String s1 = s.substring(0, index);
			String s2 = s.substring(index + 1, s.length());
			this.hash.put(s1, s2);
		}
	}

	public String getHashData(String key) {
		return (String) hash.get(key);
	}

	public String[][] getTable() {
		if (tableIndex <= 0) {
			return null;
		}

		int line = vec.size() / this.tableIndex;
		String[][] tmp = new String[line][tableIndex];
		for (int i = 0; i < line; i++) {
			for (int j = 0; j < tableIndex; j++) {
				tmp[i][j] = (String) vec.elementAt(i * tableIndex + j);
			}
		}
		return tmp;
	}

	public int readLength() {
		size = readShort();
		return size;
	}

	public int getSize() {
		return size;
	}

	public boolean readBoolean() {
		try {
			return in.readBoolean();
		} catch (Exception ex) {
			throw new RuntimeException();
		}
	}

	public boolean[] readBooleans() {
		boolean[] v = new boolean[readLength()];
		for (int i = 0; i < v.length; i++) {
			v[i] = readBoolean();
		}
		return v;
	}

	public boolean[][] readBooleans2() {
		int length = readLength();
		if (length == 0) {
			return new boolean[0][];
		}
		boolean[][] v = new boolean[length][readLength()];
		for (int i = 0; i < v.length; i++) {
			for (int j = 0; j < v[0].length; j++) {
				v[i][j] = readBoolean();
			}
		}
		return v;
	}

	public int readByte() {
		try {
			return in.readByte();
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new RuntimeException();
		}
	}

	public int[] readBytes() {
		int[] v = new int[readLength()];
		for (int i = 0; i < v.length; i++) {
			v[i] = readByte();
		}
		return v;
	}

	public int[][] readBytes2() {
		int length = readLength();
		if (length == 0) {
			return new int[0][];
		}
		int[][] v = new int[length][readLength()];
		for (int i = 0; i < v.length; i++) {
			for (int j = 0; j < v[0].length; j++) {
				v[i][j] = readByte();
			}
		}
		return v;
	}

	public int readShort() {
		try {
			int v2 = in.read();
			int v1 = in.read();
			if ((v1 | v2) < 0) {
				throw new EOFException();
			}
			return ((v1 << 8) + (v2 << 0));
		} catch (IOException ex) {
			return 0;
		}

	}

	public int[] readShorts() {
		int[] v = new int[readLength()];
		for (int i = 0; i < v.length; i++) {
			v[i] = readShort();
		}
		return v;
	}

	public int[][] readShorts2() {
		int length = readLength();
		if (length == 0) {
			return new int[0][];
		}
		int[][] v = new int[length][readLength()];
		for (int i = 0; i < v.length; i++) {
			for (int j = 0; j < v[0].length; j++) {
				v[i][j] = readShort();
			}
		}
		return v;
	}

	public int readInt() {
		try {
			int v4 = in.read();// dd
			int v3 = in.read();// b4
			int v2 = in.read();// 4
			int v1 = in.read();// 0
			if ((v1 | v2 | v3 | v4) < 0) {
				throw new EOFException();
			}
			return ((v1 << 24) + (v2 << 16) + (v3 << 8) + (v4 << 0));
		} catch (IOException ex) {
			return 0;
		}
	}

	public int[] readInts() {
		int[] v = new int[readLength()];
		for (int i = 0; i < v.length; i++) {
			v[i] = readInt();
		}
		return v;
	}

	public int[][] readInts2() {
		int length = readLength();
		if (length == 0) {
			return new int[0][];
		}
		int[][] v = new int[length][readLength()];
		for (int i = 0; i < v.length; i++) {
			for (int j = 0; j < v[0].length; j++) {
				v[i][j] = readInt();
			}
		}
		return v;
	}

	public int[] readNumbers() {
		int size = readByte();
		if (size == 1) {
			return readBytes();
		}
		if (size == 2) {
			return readShorts();
		}
		return readInts();
	}

	public int[][] readNumbers2() {
		int size = readByte();
		if (size == 1) {
			return readBytes2();
		}
		if (size == 2) {
			return readShorts2();
		}
		return readInts2();
	}

	public long readLong() {
		try {
			int v8 = in.read();
			int v7 = in.read();
			int v6 = in.read();
			int v5 = in.read();
			int v4 = in.read();
			int v3 = in.read();
			int v2 = in.read();
			int v1 = in.read();
			if ((v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8) < 0) {
				throw new EOFException();
			}
			return ((v1 << 56) + (v2 << 48) + (v3 << 40) + (v4 << 32) + (v5 << 24) + (v6 << 16) + (v7 << 8) + (v8 << 0));
		} catch (IOException ex) {
			return 0;
		}
	}

	public String readString() {
		try {

			int len = readLength();
			byte[] b = new byte[len];
			in.read(b);
			return new String(b, "UTF-8");
		} catch (IOException ex) {
			return null;
		}
	}

	public String[] readStrings() {
		String[] v = new String[readLength()];
		for (int i = 0; i < v.length; i++) {
			v[i] = readString();
		}
		return v;
	}

	public String[][] readStrings2() {
		String[][] v = new String[readLength()][];
		for (int i = 0; i < v.length; i++) {
			v[i] = readStrings();
		}
		return v;
	}

	public byte[] readByteArray() {
		byte[] v = new byte[readLength()];
		for (int i = 0; i < v.length; i++) {
			v[i] = (byte) readByte();
		}
		return v;
	}

	public byte[] getOthers() {
		try {
			int num = in.available();
			byte[] tmp = new byte[num];
			for (int i = 0; i < num; i++) {
				tmp[i] = in.readByte();
			}
			return tmp;
		} catch (IOException ex) {
			return null;
		}
	}

	public Vector readVector() {
		int num = readLength();
		Vector v = new Vector(num);
		for (int i = 0; i < num; i++) {
			v.addElement(readString());
		}
		return v;
	}

	public void cloese() {
		try {
			if (in != null) {
				in.close();
			}
			if (bin != null) {
				bin.close();
			}
			in = null;
			bin = null;
		} catch (IOException ex) {
		}
	}

}


 

 

package app.http;

import java.util.Hashtable;
import java.io.*;

/**
 * 按照私有协议,解析数据,和Request对应,把最终解析结果存放于一个hash中,存放格式是 消息码--消息内容
 */
public class Response {
	private Hashtable hash = new Hashtable();

	public int responseCode;

	public int contentLength;

	private static final byte START_FLAG = (byte) '{';
	private static final byte END_FLAG = (byte) '}';
	private static final byte OTHER_FLAG = (byte) ':';

	public Response() {
	}

	/**
	 * 分析数据 解析TYPE和真正数据content
	 * 
	 * @param data
	 *            byte[]
	 */
	public void analysisData(byte[] _data, boolean isStart) {
		StructResponse struct = new StructResponse(_data);
		byte[] data = null;
		try {
			while (isStart) {

				int v = struct.readByte();
				if (v == -1) {
					throw new IOException(" DATA");
				}

				if (v == START_FLAG) {
					break;
				}

			}

			int type = struct.readShort();

			struct.readByte(); // 0 标志位
			struct.readByte(); // 0 标志位

			data = struct.readByteArray();

			byte tmp = (byte) struct.readByte();

			if (tmp == END_FLAG) {
				hash.put(Integer.toString(type), data);
			} else if (tmp == OTHER_FLAG) {
				hash.put(Integer.toString(type), data);
				analysisData(struct.getOthers(), false);
			} else {
				throw new IOException("BAD DATA");
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}

	}

	public int getResponseCode() {
		return responseCode;
	}

	public int getContentLength() {
		return contentLength;
	}

	public byte[] getData(int key) {
		return (byte[]) hash.get(Integer.toString(key));
	}

	public int getResponseNum() {
		return hash.size();
	}

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值