相比于GET请求,POST报文多了如下几个要素:
1,Content-Length,这个是上送报文的长度,以字节为单位
2,Content-Type,这主要是涉及到报文的格式和字符集。
3,就是主报文
主类SimpleHttpPost:
package com.zws.http; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * * @author wensh.zhu 2017-03-11 请求报文格式: GET /greeting.do?name=jack HTTP/1.1\r\n Host: localhost:8011\r\n Connection: keep-alive\r\n Cache-Control: max-age=0\r\n Upgrade-Insecure-Requests: 1\r\n User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*此处为斜线(/)*;q=0.8\r\n Accept-Encoding: gzip, deflate, sdch, br\r\n Accept-Language: zh-CN,zh;q=0.8\r\n Content-Length: 14\r\n Content-Type, application/x-www-form-urlencoded;charset=UTF-8\r\n \r\n id=1&name=jack 响应报文格式: 一次性响应: HTTP/1.1 200 OK\r\n Server: Apache-Coyote/1.1\r\n Set-Cookie: JSESSIONID=54B11BE01CD7983726618546CF4521E1; Path=/Newer/; HttpOnly\r\n Content-Type: text/html;charset=UTF-8\r\n Content-Length: 4\r\n //报文正文长度 Date: Sat, 11 Mar 2017 15:16:10 GMT\r\n \r\n //报头结束 abcd //正文 分块响应: HTTP/1.1 200 OK\r\n Content-Type: application/json;charset=UTF-8\r\n Transfer-Encoding: chunked\r\n //表示分块响应 Date: Sat, 11 Mar 2017 14:19:25 GMT\r\n \r\n //报头结束 8\r\n //十六进制长度 abcdefgh\r\n //正文 2\r\n ab\r\n 0\r\n //结束 */ public class SimpleHttpPost { private int connectTimeout = 2000; //链接超时时间 private int readTimeout = 5000; //读超时时间 private String host; private int port = 80; private String resource = "/"; private String reqLine; private String body; private Map<String, String> headers = new HashMap<String, String>(); public SimpleHttpPost(String uri) { initRequestHeader(); parseRequestLine(uri); } public SimpleHttpPost(String uri, int connectTimeout, int readTimeOut) { initRequestHeader(); parseRequestLine(uri); this.connectTimeout = connectTimeout; this.readTimeout = readTimeOut; } /** * 解析出IP地址、端口以及请求资源 * @param uri */ private void parseRequestLine(String uri) { String url = uri; if (url == null) throw new NullPointerException("uri can not be null"); if (!url.startsWith("http")) url = "http://" + uri; String[] parts = url.split("//"); if (parts.length >= 2) { String mainPart = parts[1]; int ipFlag = mainPart.indexOf("/"); if (ipFlag != -1) { String ipPart = mainPart.substring(0, ipFlag); resource = mainPart.substring(ipFlag); String[] ipParts = ipPart.split(":"); if (ipParts.length > 1) { host = ipParts[0]; String portStr = ipParts[1]; if (portStr != null && portStr.length() > 0) port = Integer.parseInt(portStr); } else { host = ipPart; } } else { host = mainPart; } } else { throw new IllegalArgumentException("非法的uri"); } String hostVal = host; if (port != 80) hostVal += ":" + port; headers.put("Host", hostVal); reqLine = "POST " + resource + " HTTP/1.1\r\n"; } /** * 初始化请求头 */ private void initRequestHeader() { headers.put("Connection", "keep-alive"); headers.put("Upgrade-Insecure-Requests", "1"); headers.put("User-Agent", "Java client"); headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); headers.put("Accept-Encoding", "gzip"); headers.put("Accept-Language", "zh-CN,zh"); headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); } public void setHeader(String key, String value) { headers.put(key, value); } private void concatParam(Map<String, String> parameters){ if (parameters == null || parameters.isEmpty()) return; String params = ""; Iterator<String> itor = parameters.keySet().iterator(); while (itor.hasNext()) { String key = itor.next(); String val = parameters.get(key); params += ("&" + key + "=" + val); } body = params.replaceFirst("&", ""); } public RespMsg req(Map<String, String> parameters) { concatParam(parameters); int contentLen = 0; if (body != null) contentLen = body.getBytes().length; this.headers.put("Content-Length", String.valueOf(contentLen)); RespMsg msg = null; Socket socket = null; OutputStream out = null; InputStream in = null; try { SocketAddress endpoint = new InetSocketAddress(host, port); socket = new Socket(); socket.connect(endpoint, connectTimeout); socket.setSoTimeout(readTimeout); out = socket.getOutputStream(); write(out); in = socket.getInputStream(); msg = read(in); } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null) out.close(); if (in != null) in.close(); if (socket != null) socket.close(); } catch (Exception e2) { e2.printStackTrace(); } } return msg; } private void write(OutputStream out) throws IOException { String reqBody = reqLine; Iterator<String> itor = headers.keySet().iterator(); while (itor.hasNext()) { String key = itor.next(); String val = headers.get(key); String header = key + ":" + val + "\r\n"; reqBody += header; } reqBody += "\r\n"; reqBody += body; out.write(reqBody.getBytes("UTF-8")); } private RespMsg read(InputStream in) throws IOException { RespMsg respMsg = new RespMsg(); byte[] heads = HttpStreamReader.readHeaders(in); String headStr = new String(heads); String[] lines = headStr.split("\r\n"); RespHeader resp = new RespHeader(); if (lines.length > 0) resp.setRespLine(lines[0]); for (int i = 1; i < lines.length; i++) resp.addHeader(lines[i]); String body = null; if (resp.isChunked()) { body = readChunked(in); } else { int bodyLen = resp.getContentLenth(); byte[] bodyBts = new byte[bodyLen]; in.read(bodyBts); body = new String(bodyBts, "UTF-8"); } respMsg.setRespBody(body); String respLine = resp.getRespLine(); respMsg.setRespCodeMsg(respLine); return respMsg; } /** * 分块读取 * @param in * @return * @throws IOException */ private static String readChunked(InputStream in) throws IOException { String content = ""; String lenStr = "0"; while (!(lenStr = new String(HttpStreamReader.readLine(in))).equals("0")) { int len = Integer.valueOf(lenStr.toUpperCase(),16);//长度16进制表示 byte[] cnt = new byte[len]; in.read(cnt); content += new String(cnt, "UTF-8"); in.skip(2); } return content; } }
测试类Example:
package com.zws.http; import java.util.HashMap; import java.util.Map; public class Example { public static void main(String[] args) { post(); } public static void post() { String uri = "http://localhost:8080/Newer/server.action"; Map<String, String> params = new HashMap<String, String>(); params.put("id", "123"); params.put("name", "张三"); SimpleHttpPost post = new SimpleHttpPost(uri); RespMsg msg = post.req(params); String respCodeMsg = msg.getRespCodeMsg(); String respBody = msg.getRespBody(); System.out.println(respCodeMsg); System.out.println(respBody); } }
时间: 2024-10-14 11:18:18