主类:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLSocketFactory;
public class HttpProcessor {
static String encode = "UTF-8";
public static final String GET = "GET";
public static final String HEAD = "HEAD";
public static final String POST = "POST";
public static final String PUT = "PUT";
public static final String DELETE = "DELETE";
public static final String OPTIONS = "OPTIONS";
public static final Integer EXPIRE_MILLISECOND = 15000;
public static HttpEntity get(String url) throws IOException {
return http(url, HttpProcessor.GET, null, null, HttpProcessor.EXPIRE_MILLISECOND);
}
public static HttpEntity get(String url, Integer expireMillisecond) throws IOException {
return http(url, HttpProcessor.GET, null, null, expireMillisecond);
}
public static HttpEntity get(String url, Map<String, String> header, Integer expireMillisecond) throws IOException {
return http(url, HttpProcessor.GET, null, header, expireMillisecond);
}
public static HttpEntity post(String url, byte[] data) throws IOException {
return http(url, HttpProcessor.POST, data, null, HttpProcessor.EXPIRE_MILLISECOND);
}
public static HttpEntity post(String url, byte[] data, Integer expireMillisecond) throws IOException {
return http(url, HttpProcessor.POST, data, null, expireMillisecond);
}
public static HttpEntity post(String url, byte[] data, Map<String, String> header, Integer expireMillisecond)
throws IOException {
return http(url, HttpProcessor.POST, data, header, expireMillisecond);
}
public static HttpEntity http(String url, String method, byte[] data, Map<String, String> header,
Integer expireMillisecond) throws IOException {
if (header == null) {
header = new HashMap<String, String>();
}
if (!header.containsKey("Accept")) {
header.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
}
if (!header.containsKey("User-Agent")) {
header.put("User-Agent",
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36");
}
if (!header.containsKey("Connection")) {
header.put("Connection", "close");
}
if (data != null) {
header.put("Content-Length", String.valueOf(data.length));
}
StringBuilder headerBuilder = new StringBuilder();
URL address = new URL(url);
String host = address.getHost();
Integer port = (address.getPort() == -1) ? (url.toLowerCase().startsWith("https") ? 443 : 80)
: address.getPort();
headerBuilder.append(method).append(" ").append(address.getPath()).append(" HTTP/1.1").append("\r\n");
headerBuilder.append("Host: ").append(host).append("\r\n");
for (String key : header.keySet()) {
headerBuilder.append(key).append(": ").append(header.get(key)).append("\r\n");
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
stream.write(headerBuilder.toString().getBytes(encode));
stream.write("\r\n".getBytes(encode));
if (data != null) {
stream.write(data);
}
data = stream.toByteArray();
stream.close();
return socket(host, port, data, expireMillisecond);
}
public static HttpEntity socket(String host, Integer port, byte[] data, Integer expireMillisecond)
throws UnknownHostException, IOException {
Socket socket = (port != 443) ? new Socket(host, port) : SSLSocketFactory.getDefault().createSocket(host, port);
socket.setSoTimeout(expireMillisecond);
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
HttpEntity entity = new HttpEntity();
// 解析响应码
String line = ByteUtils.readLineString(socket.getInputStream(), encode);
if (line == null) {
throw new RuntimeException("请求无响应");
}
Integer code = Integer.valueOf(StringUtil.stringCutCenter(line, " ", " "));
entity.setCode(code);
// 解析head
line = ByteUtils.readLineString(socket.getInputStream(), encode);
while (!CommonUtil.isNullOrEmpty(line.trim())) {
try {
String[] attrs = line.split(":");
if (attrs.length != 2) {
continue;
}
String key = attrs[0].trim();
String value = attrs[1].trim();
if (entity.getHeader().containsKey(key)) {
value = entity.getHeader().get(key) + ";" + value;
}
entity.getHeader().put(key, value);
} finally {
line = ByteUtils.readLineString(socket.getInputStream(), encode);
}
}
// 判断是否压缩
String value = entity.getHeader().get("Content-Encoding");
entity.setGzip((value != null && value.contains("gzip")) ? true : false);
// 判断是否分段加载
value = entity.getHeader().get("Transfer-Encoding");
entity.setChunked((value != null && value.contains("chunked")) ? true : false);
// 解析内容
if (!entity.isChunked()) {
Integer length = Integer.valueOf(entity.getHeader().get("Content-Length"));
byte[] body = ByteUtils.read(socket.getInputStream(), length);
entity.setBody(body);
return entity;
}
// 分段解析内容
String chunk = ByteUtils.readLineString(socket.getInputStream(), encode);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
while (chunk != null && !CommonUtil.isNullOrEmpty(chunk.trim()) && !"0".equals(chunk.trim())) {
try {
Integer length = Integer.valueOf(chunk.trim(), 16);
while (length > 0) {
byte[] chunked = new byte[length];
int readed = socket.getInputStream().read(chunked);
length = length - readed;
stream.write(chunked, 0, readed);
}
} finally {
chunk = ByteUtils.readLineString(socket.getInputStream(), encode);
chunk = ByteUtils.readLineString(socket.getInputStream(), encode);
}
}
entity.setBody(stream.toByteArray());
stream.close();
return entity;
}
}
模型类:
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("serial")
public class HttpEntity implements Serializable {
private Integer code;
private byte[] body;
private boolean isGzip;
private boolean chunked;
private Map<String, String> header = new HashMap<String, String>();
public boolean isChunked() {
return chunked;
}
public void setChunked(boolean chunked) {
this.chunked = chunked;
}
public boolean isGzip() {
return isGzip;
}
public void setGzip(boolean isGzip) {
this.isGzip = isGzip;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public byte[] getBody() {
if (isGzip) {
return GZIPUtils.uncompress(this.body);
}
return body;
}
public String getBody(String encode) throws UnsupportedEncodingException {
return new String(this.getBody(), encode);
}
public void setBody(byte[] body) {
this.body = body;
}
public Map<String, String> getHeader() {
return header;
}
public void setHeader(Map<String, String> header) {
this.header = header;
}
}
工具类ByteUtils:
package org.coody.framework.core.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
@SuppressWarnings("unchecked")
public class ByteUtils {
public static byte[] readLine(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
while (true) {
byte a = (byte) inputStream.read();
if (a == '\n' || a == 0) {
break;
}
outputStream.write(a);
}
return outputStream.toByteArray();
}
public static String readLineString(InputStream inputStream, String encode) {
try {
byte[] data = readLine(inputStream);
if (CommonUtil.isNullOrEmpty(data)) {
return null;
}
return new String(data, encode);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static byte[] read(InputStream inputStream) {
ByteArrayOutputStream outputStream = null;
try {
outputStream = buildToOutputStream(inputStream);
return outputStream.toByteArray();
} catch (Exception e) {
return null;
} finally {
try {
outputStream.close();
} catch (IOException e) {
}
}
}
public static byte[] read(InputStream inputStream, Integer length) {
if (length < 1) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
while (length > 0) {
byte[] chunked = new byte[length];
int readed = inputStream.read(chunked);
length = length - readed;
outputStream.write(chunked, 0, readed);
}
byte[] bytes = outputStream.toByteArray();
outputStream.close();
return bytes;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static byte[] read(SocketChannel channel, Integer length) {
if (length < 1) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
while (length > 0) {
ByteBuffer buffer = ByteBuffer.allocate(length);
int readed = channel.read(buffer);
length = length - readed;
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
outputStream.write(data);
}
byte[] bytes = outputStream.toByteArray();
outputStream.close();
return bytes;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static <T extends OutputStream> T buildToOutputStream(InputStream inputStream) {
OutputStream outputStream = new ByteArrayOutputStream();
try {
buildToOutputStream(inputStream, outputStream);
return (T) outputStream;
} catch (Exception e) {
return null;
}
}
public static <T extends OutputStream> T buildToOutputStream(InputStream inputStream, OutputStream outputStream) {
if (outputStream == null) {
outputStream = new ByteArrayOutputStream();
}
try {
outputStream = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int rc = 0;
while ((rc = inputStream.read(buff, 0, 1024)) > 0) {
outputStream.write(buff, 0, rc);
}
return (T) outputStream;
} catch (Exception e) {
return null;
}
}
}
工具类CommonUtil:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public class CommonUtil {
public static boolean isNullOrEmpty(Object obj) {
try {
if (obj == null) {
return true;
}
if (obj instanceof CharSequence) {
return ((CharSequence) obj).length() == 0;
}
if (obj instanceof Collection) {
return ((Collection<?>) obj).isEmpty();
}
if (obj instanceof Map) {
return ((Map<?, ?>) obj).isEmpty();
}
if (obj instanceof Object[]) {
Object[] object = (Object[]) obj;
if (object.length == 0) {
return true;
}
boolean empty = true;
for (int i = 0; i < object.length; i++) {
if (!isNullOrEmpty(object[i])) {
empty = false;
break;
}
}
return empty;
}
return false;
} catch (Exception e) {
return true;
}
}
}
工具类StringUtil:
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StringUtil {
public static String stringCutCenter(String allTxt, String firstTxt, String lastTxt) {
try {
String tmp = "";
int n1 = allTxt.indexOf(firstTxt);
if (n1 == -1) {
return "";
}
tmp = allTxt.substring(n1 + firstTxt.length(), allTxt.length());
int n2 = tmp.indexOf(lastTxt);
if (n2 == -1) {
return "";
}
tmp = tmp.substring(0, n2);
return tmp;
} catch (Exception e) {
return "";
}
}
public static List<String> stringCutCenters(String allTxt, String firstTxt, String lastTxt) {
try {
List<String> results = new ArrayList<String>();
while (allTxt.contains(firstTxt)) {
int n = allTxt.indexOf(firstTxt);
allTxt = allTxt.substring(n + firstTxt.length(), allTxt.length());
n = allTxt.indexOf(lastTxt);
if (n == -1) {
return results;
}
String result = allTxt.substring(0, n);
results.add(result);
allTxt = allTxt.substring(n + firstTxt.length(), allTxt.length());
}
return results;
} catch (Exception e) {
return null;
}
}
}
工具类GZIPUtils:
package org.coody.framework.core.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
*
* @author Coody
*
*/
public class GZIPUtils {
public static final String GZIP_ENCODE_UTF_8 = "UTF-8";
/**
* 字符串压缩为GZIP字节数组
*
* @param str
* @return
*/
public static byte[] compress(String str) {
try {
return compress(str.getBytes(GZIP_ENCODE_UTF_8));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串压缩为GZIP字节数组
*
* @param str
* @param encoding
* @return
*/
public static byte[] compress(byte[] data) {
if (data == null || data.length == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = null;
try {
gzip = new GZIPOutputStream(out);
gzip.write(data);
} catch (IOException e) {
} finally {
try {
gzip.close();
} catch (Exception e2) {
}
try {
out.close();
} catch (Exception e2) {
}
}
return out.toByteArray();
}
/**
* GZIP解压缩
*
* @param bytes
* @return
*/
public static byte[] uncompress(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
GZIPInputStream ungzip = null;
try {
ungzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = ungzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
} catch (IOException e) {
} finally {
try {
in.close();
} catch (Exception e2) {
}
try {
out.close();
} catch (Exception e2) {
}
try {
ungzip.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
return out.toByteArray();
}
}
用法:工具类都非常简单,几个常用的方法都可以抽离。无其他依赖。
HttpEntity entity = HttpProcessor.get("https://www.oschina.net/");
System.out.println("响应码->" + entity.getCode());
System.out.println("响应内容->\r\n" + entity.getBody("UTF-8"));