Java tutorial
/* * Copyright yz 2016-01-14 Email:admin@javaweb.org. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.javaweb.net; import org.apache.commons.collections.map.CaseInsensitiveMap; import org.javaweb.utils.IOUtils; import org.javaweb.utils.StringUtils; import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.DeflaterInputStream; import java.util.zip.GZIPInputStream; /** * Http?? * Created by yz on 2017/1/5. */ public class HttpResponseParser { /** * ??Header */ private static final int MAX_HEADER_LENGTH = 1024 * 1000 * 4; private static Pattern responsePattern = Pattern.compile("^(HTTP/\\d\\.\\d) (\\d{3}) (.*)$"); /** * Http? */ private String httpVersion; /** * Http??? */ private int httpStatus = -1; /** * Http??? */ private String httpStatusInfo; /** * Http??Map */ private Map<String, Object> headerMap = new CaseInsensitiveMap(); /** * Http?? */ private String header; /** * ?? */ private DataInputStream dis; /** * ?? */ private InputStream httpBodyInputStream; public HttpResponseParser(InputStream in) { this.dis = new DataInputStream(in); parse(); } /** * ??Http? * * @return */ public static int getMaxHeaderLength() { return MAX_HEADER_LENGTH; } /** * ?Http? * * @return */ public String getHttpVersion() { return httpVersion; } /** * ?Http??? * * @return */ public int getHttpStatus() { return httpStatus; } /** * Http??? * * @return */ public String getHttpStatusInfo() { return httpStatusInfo; } /** * ?Http??Map * * @return */ public Map<String, Object> getHeaderMap() { return headerMap; } /** * ?Http?? * * @return */ public String getHeader() { return header; } /** * ?Http?? * * @return */ public InputStream getHttpBodyInputStream() { return httpBodyInputStream; } /** * ?? */ private void parse() { try { parseHttpResponseHeaderString(); parseHttpResponseStatus(); parseHttpResponseHeaderMap(); parseHttpResponseBodyInputStream(); } catch (IOException e) { e.printStackTrace(); } } /** * ?Http? * * @throws IOException */ private void parseHttpResponseHeaderString() { boolean loop = true; int a = 0; StringBuilder sb = new StringBuilder(); try { String str = null; while (loop && (str = dis.readLine()) != null) { a += str.length();// ?? if (a > MAX_HEADER_LENGTH) { loop = false; } else { if (str.length() == 0) { loop = false; } else { sb.append(str).append("\n"); } } } } catch (IOException e) { e.printStackTrace(); } this.header = sb.toString(); } /** * ?Http?Map * * @throws IOException */ private void parseHttpResponseHeaderMap() throws IOException { if (StringUtils.isNotEmpty(this.header)) { BufferedReader br = null; try { String str = null; br = new BufferedReader(new StringReader(this.header)); while ((str = br.readLine()) != null) { int i = str.indexOf(":"); if (i != -1) { String key = i > 0 ? str.substring(0, i) : ""; String value = str.length() - 1 > i ? str.substring(i + 1).trim() : ""; if (!headerMap.containsKey(key)) { headerMap.put(key, value); } else { Object obj = headerMap.get(key); if (obj instanceof String) { headerMap.put(key, new String[] { (String) obj, value }); } else { List<String> list = new ArrayList<String>(); list.addAll(Arrays.asList((String[]) obj)); list.add(value); headerMap.put(key, list.toArray(new String[list.size()])); } } } } } catch (IOException e) { throw e; } finally { IOUtils.closeQuietly(br); } } } /** * ?Http??? * * @throws IOException */ private void parseHttpResponseStatus() throws IOException { try { if (StringUtils.isNotEmpty(this.header)) { StringReader sr = new StringReader(this.header); String responseStatusLine = new BufferedReader(sr).readLine(); if (StringUtils.isNotEmpty(responseStatusLine)) { Matcher m = responsePattern.matcher(responseStatusLine); if (m.find() && m.groupCount() == 3) { this.httpVersion = m.group(1); this.httpStatus = StringUtils.isNum(m.group(2)) ? Integer.parseInt(m.group(2)) : -1; this.httpStatusInfo = m.group(3); } } } } catch (IOException e) { throw e; } } /** * ?Http?? ??Transfer-Encoding Content-Encoding ?chunked? * * @throws IOException */ private void parseHttpResponseBodyInputStream() throws IOException { InputStream bodyInputStream = null; // ?chunked if (this.headerMap.containsKey("Transfer-Encoding")) { String transferEncoding = (String) this.headerMap.get("Transfer-Encoding"); if (StringUtils.isNotEmpty(transferEncoding) && "chunked".equalsIgnoreCase(transferEncoding)) { bodyInputStream = new ChunkedInputStream(dis); } else { bodyInputStream = dis; } } else { bodyInputStream = dis; } // ?gzipdeflate if (this.headerMap.containsKey("Content-Encoding")) { String contentEncoding = (String) this.headerMap.get("Content-Encoding"); InputStream compressInputStream = null; try { if ("gzip".equalsIgnoreCase(contentEncoding)) { compressInputStream = new GZIPInputStream(bodyInputStream); } else if ("deflate".equalsIgnoreCase(contentEncoding)) { compressInputStream = new DeflaterInputStream(bodyInputStream); } } catch (IOException e) { throw e; } if (compressInputStream != null) { bodyInputStream = compressInputStream; } } this.httpBodyInputStream = bodyInputStream; } }