HttpURLConnection POST請求傳送引數和上傳檔案
阿新 • • 發佈:2019-01-07
package com.face; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HttpUtil { private static Logger log = LoggerFactory.getLogger(HttpUtil.class); private final static String BOUNDARY = UUID.randomUUID().toString() .toLowerCase().replaceAll("-", "");// 邊界標識 private final static String PREFIX = "--";// 必須存在 private final static String LINE_END = "\r\n"; public static String sendRequest(String requestUrl, Map<String, String> requestText, Map<String, File> requestFile) throws Exception{ HttpURLConnection conn = null; InputStream input = null; OutputStream os = null; BufferedReader br = null; StringBuffer buffer = null; try { URL url = new URL(requestUrl); conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); conn.setConnectTimeout(1000 * 10); conn.setReadTimeout(1000 * 10); conn.setRequestMethod("POST"); conn.setRequestProperty("Accept", "*/*"); conn.setRequestProperty("Connection", "keep-alive"); conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); conn.setRequestProperty("Charset", "UTF-8"); conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); conn.connect(); // 往伺服器端寫內容 也就是發起http請求需要帶的引數 os = new DataOutputStream(conn.getOutputStream()); // 請求引數部分 writeParams(requestText, os); // 請求上傳檔案部分 writeFile(requestFile, os); // 請求結束標誌 String endTarget = PREFIX + BOUNDARY + PREFIX + LINE_END; os.write(endTarget.getBytes()); os.flush(); // 讀取伺服器端返回的內容 System.out.println("======================響應體========================="); System.out.println("ResponseCode:" + conn.getResponseCode() + ",ResponseMessage:" + conn.getResponseMessage()); if(conn.getResponseCode()==200){ input = conn.getInputStream(); }else{ input = conn.getErrorStream(); } br = new BufferedReader(new InputStreamReader( input, "UTF-8")); buffer = new StringBuffer(); String line = null; while ((line = br.readLine()) != null) { buffer.append(line); } //...... System.out.println("返回報文:" + buffer.toString()); } catch (Exception e) { log.error(e.getMessage(), e); throw new Exception(e); } finally { try { if (conn != null) { conn.disconnect(); conn = null; } if (os != null) { os.close(); os = null; } if (br != null) { br.close(); br = null; } } catch (IOException ex) { log.error(ex.getMessage(), ex); throw new Exception(ex); } } return buffer.toString(); } /** * 對post引數進行編碼處理並寫入資料流中 * @throws Exception * * @throws IOException * * */ private static void writeParams(Map<String, String> requestText, OutputStream os) throws Exception { try{ String msg = "請求引數部分:\n"; if (requestText == null || requestText.isEmpty()) { msg += "空"; } else { StringBuilder requestParams = new StringBuilder(); Set<Map.Entry<String, String>> set = requestText.entrySet(); Iterator<Entry<String, String>> it = set.iterator(); while (it.hasNext()) { Entry<String, String> entry = it.next(); requestParams.append(PREFIX).append(BOUNDARY).append(LINE_END); requestParams.append("Content-Disposition: form-data; name=\"") .append(entry.getKey()).append("\"").append(LINE_END); requestParams.append("Content-Type: text/plain; charset=utf-8") .append(LINE_END); requestParams.append("Content-Transfer-Encoding: 8bit").append( LINE_END); requestParams.append(LINE_END);// 引數頭設定完以後需要兩個換行,然後才是引數內容 requestParams.append(entry.getValue()); requestParams.append(LINE_END); } os.write(requestParams.toString().getBytes()); os.flush(); msg += requestParams.toString(); } System.out.println(msg); }catch(Exception e){ log.error("writeParams failed", e); throw new Exception(e); } } /** * 對post上傳的檔案進行編碼處理並寫入資料流中 * * @throws IOException * * */ private static void writeFile(Map<String, File> requestFile, OutputStream os) throws Exception { InputStream is = null; try{ String msg = "請求上傳檔案部分:\n"; if (requestFile == null || requestFile.isEmpty()) { msg += "空"; } else { StringBuilder requestParams = new StringBuilder(); Set<Map.Entry<String, File>> set = requestFile.entrySet(); Iterator<Entry<String, File>> it = set.iterator(); while (it.hasNext()) { Entry<String, File> entry = it.next(); requestParams.append(PREFIX).append(BOUNDARY).append(LINE_END); requestParams.append("Content-Disposition: form-data; name=\"") .append(entry.getKey()).append("\"; filename=\"") .append(entry.getValue().getName()).append("\"") .append(LINE_END); requestParams.append("Content-Type:") .append(getContentType(entry.getValue())) .append(LINE_END); requestParams.append("Content-Transfer-Encoding: 8bit").append( LINE_END); requestParams.append(LINE_END);// 引數頭設定完以後需要兩個換行,然後才是引數內容 os.write(requestParams.toString().getBytes()); is = new FileInputStream(entry.getValue()); byte[] buffer = new byte[1024*1024]; int len = 0; while ((len = is.read(buffer)) != -1) { os.write(buffer, 0, len); } os.write(LINE_END.getBytes()); os.flush(); msg += requestParams.toString(); } } System.out.println(msg); }catch(Exception e){ log.error("writeFile failed", e); throw new Exception(e); }finally{ try{ if(is!=null){ is.close(); } }catch(Exception e){ log.error("writeFile FileInputStream close failed", e); throw new Exception(e); } } } /** * ContentType * * @Description: * @param file * @return * @throws IOException */ public static String getContentType(File file) throws Exception{ String streamContentType = "application/octet-stream"; String imageContentType = ""; ImageInputStream image = null; try { image = ImageIO.createImageInputStream(file); if (image == null) { return streamContentType; } Iterator<ImageReader> it = ImageIO.getImageReaders(image); if (it.hasNext()) { imageContentType = "image/" + it.next().getFormatName(); return imageContentType; } } catch (IOException e) { log.error("method getContentType failed", e); throw new Exception(e); } finally { try{ if (image != null) { image.close(); } }catch(IOException e){ log.error("ImageInputStream close failed", e);; throw new Exception(e); } } return streamContentType; } }