1. 程式人生 > >java 解析http報文POST

java 解析http報文POST

private byte[] parse(HttpServletRequest request) throws IOException {

		final int NONE = 0;
		final int DATAHEADER = 1;
		final int FILEDATA = 2;
		final int FIELDDATA = 3;

		final int MXA_SEGSIZE = 1000 * 1024 * 10;//每批最大的資料量 10M

		String contentType = request.getContentType();// 請求訊息型別
		String fieldname = ""; // 表單域的名稱
		String fieldvalue = ""; // 表單域的值
		String filename = ""; // 檔名
		String boundary = ""; // 分界符
		String lastboundary = ""; // 結束符
		String filePath = "";
		Hashtable<String, String> formfields = new Hashtable<String, String>();
		int filesize = 0; // 檔案長度

		int pos = contentType.indexOf("boundary=");

		if (pos != -1) { // 取得分界符和結束符
			pos += "boundary=".length();
			boundary = "--" + contentType.substring(pos);
			lastboundary = boundary + "--";
		}
		int state = NONE;
		// 得到資料輸入流reqbuf
		DataInputStream in = new DataInputStream(request.getInputStream());
		// 將請求訊息的實體送到b變數中
		int totalBytes = request.getContentLength();
		String message = "";
		if (totalBytes > MXA_SEGSIZE) {//每批大於10m時
			message = "Each batch of data can not be larger than " + MXA_SEGSIZE / (1000 * 1024)
					+ "M";
			return null;
		}
		byte[] b = new byte[totalBytes];
		in.readFully(b);
		in.close();
		String reqContent = new String(b, "UTF-8");//
		BufferedReader reqbuf = new BufferedReader(new StringReader(reqContent));

		boolean flag = true;
		int i = 0;
		while (flag == true) {
			String s = reqbuf.readLine();
			if ((s == null) || (s.equals(lastboundary)))
				break;

			switch (state) {
				case NONE:
					if (s.startsWith(boundary)) {
						state = DATAHEADER;
						i += 1;
					}
					break;
				case DATAHEADER:
					pos = s.indexOf("filename=");
					if (pos == -1) { // 將表單域的名字解析出來
						pos = s.indexOf("name=");
						pos += "name=".length() + 1;
						s = s.substring(pos);
						int l = s.length();
						s = s.substring(0, l - 1);
						fieldname = s;
						state = FIELDDATA;
					} else { // 將檔名解析出來
						String temp = s;
						pos = s.indexOf("filename=");
						pos += "filename=".length() + 1;
						s = s.substring(pos);
						int l = s.length();
						s = s.substring(0, l - 1);// 去掉最後那個引號”
						filePath = s;
						pos = s.lastIndexOf("\\");
						s = s.substring(pos + 1);
						filename = s;
						// 從位元組陣列中取出檔案陣列
						pos = byteIndexOf(b, temp, 0);
						b = subBytes(b, pos + temp.getBytes().length + 2, b.length);// 去掉前面的部分
						int n = 0;
						/**
						 * 過濾boundary下形如 Content-Disposition: form-data; name="bin";
						 * filename="12.pdf" Content-Type: application/octet-stream
						 * Content-Transfer-Encoding: binary 的字串
						 */
						while ((s = reqbuf.readLine()) != null) {
							if (n == 1)
								break;
							if (s.equals(""))
								n++;

							b = subBytes(b, s.getBytes().length + 2, b.length);
						}
						pos = byteIndexOf(b, boundary, 0);
						if (pos != -1)
							b = subBytes(b, 0, pos - 1);

						filesize = b.length - 1;
						formfields.put("filesize", String.valueOf(filesize));
						state = FILEDATA;
					}
					break;
				case FIELDDATA:
					s = reqbuf.readLine();
					fieldvalue = s;
					formfields.put(fieldname, fieldvalue);
					state = NONE;
					break;
				case FILEDATA:
					while ((!s.startsWith(boundary)) && (!s.startsWith(lastboundary))) {
						s = reqbuf.readLine();
						if (s.startsWith(boundary)) {
							state = DATAHEADER;
							break;
						}
					}
					break;
			}
		}
		return b;

	}

	// 位元組陣列中的INDEXOF函式,與STRING類中的INDEXOF類似
	public static int byteIndexOf(byte[] b, String s, int start) {
		return byteIndexOf(b, s.getBytes(), start);
	}

	// 位元組陣列中的INDEXOF函式,與STRING類中的INDEXOF類似
	public static int byteIndexOf(byte[] b, byte[] s, int start) {
		int i;
		if (s.length == 0) {
			return 0;
		}
		int max = b.length - s.length;
		if (max < 0)
			return -1;
		if (start > max)
			return -1;
		if (start < 0)
			start = 0;
		search: for (i = start; i <= max; i++) {
			if (b[i] == s[0]) {
				int k = 1;
				while (k < s.length) {
					if (b[k + i] != s[k]) {
						continue search;
					}
					k++;
				}
				return i;
			}
		}
		return -1;
	}

	// 用於從一個位元組陣列中提取一個位元組陣列
	public static byte[] subBytes(byte[] b, int from, int end) {
		byte[] result = new byte[end - from];
		System.arraycopy(b, from, result, 0, end - from);
		return result;
	}

	// 用於從一個位元組陣列中提取一個字串
	public static String subBytesString(byte[] b, int from, int end) {
		return new String(subBytes(b, from, end));
	}

相關推薦

java 解析http報文POST

private byte[] parse(HttpServletRequest request) throws IOException { final int NONE = 0; final int DATAHEADER = 1; final int FILEDATA = 2; final 

http-parser解析http報文詳解

說明 專案裡用到力http-parser,在這裡簡單說明一下其用法吧 下載地址:https://github.com/joyent/http-parser 其使用說明很詳細。 開源用例 開源tcpflow 1.4.4中使用http-parser的原始碼 <span

Java實現httppost、get)請求

package com.wolaidai.credit.management.utils; import com.alibaba.fastjson.JSON; import org.apache.commons.logging.Log; import org.apache

javahttppost請求

package com.psds.zhengxin.apiweb.util; import java.io.*; import java.net.HttpURLConnection; import java.net.MalformedURLException;

Java傳送http get/post請求,呼叫介面/方法

由於專案中要用,所以找了一些資料,整理下來。 GitHub地址: https://github.com/iamyong    轉自:http://blog.csdn.net/capmiachael/article/details/51833531 例1:使用 HttpCl

JAVA 呼叫HTTP介面POST或GET實現方式

package com.yoodb.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.apac

Java實現HttpPost、Get、代理訪問請求

package getMethod; import java.io.BufferedReader;  import java.io.IOException; import java.io.InputStream;  import java.io.InputStream

java實現HTTPpost請求 key-value格式與json格式的區別

之前寫過介面接收json格式的post請求,當時自己寫完以為可以適應各種報文的傳送,最近對方說要有個”content=傳送內容”,這不就是最簡單的post請求嗎,那直接用我之前寫的http://blog.csdn.net/do_finsh/article/det

JAVA傳送http get/post請求,呼叫http介面、方法

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; impo

javahttp模擬post上傳檔案到服務端 模擬form上傳檔案

需求是這樣的: **1,前後端分離,前端對接pc軟體進行檔案同步的介面,後的springboot微服務進行檔案接收和處理。 2,軟體不能直接呼叫微服務的介面進行上傳,只能先走一下前端controller進行轉發過來()。 3,這樣就只能用httpclien

java基於HTTP協議post傳參,獲取引數

post傳參和獲取引數: /** * 獲取post引數 * @param is * @param charset * @return */ public static String getContent(InputStream is, St

java解析http請求

public class GetSiteTest {public static void testPost() throws IOException {            /**           * 首先要和URL下的URLConnection對話。 URLConn

Java 模擬 HTTP Get Post 請求實現論壇自動回帖

設計思路 最近想自動發帖回帖,拿某論壇試驗了一下,發現可行,不過後續沒有再使用,免得影響論壇正常執行。 帖子連結的格式為 http://bbs.***.***.**/forum.php?mod=viewthread&tid=774210

java 解析http協議介面返回的json字串

String url = "http://114.119.10.14/younserver/authUserLogin.do?logintype=3&&username="+USERNAME+"&passwd="+PASSWORD;String st

JAVA使用http傳送post或get請求例項

package wzh.Http; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.n

詳解http報文(2)-web容器是如何解析http報文

摘要 在詳解http報文一文中,詳細介紹了http報文的文字結構。那麼作為服務端,web容器是如何解析http報文的呢?本文以jetty和undertow容器為例,來解析web容器是如何處理http報文的。 在前文中我們從概覽中可以瞭解到,http報文其實就是一定規則的字串,那麼解析它們,就是解析字串,看看是

JAVA 實現HTTP POST請求報文格式分析

在開發中,我們使用的比較多的HTTP請求方式基本上就是GET、POST。其中GET用於從伺服器獲取資料,POST主要用於向伺服器提交一些表單資料,例如檔案上傳等。而我們在使用HTTP請求時中遇到的比較麻煩的事情就是構造檔案上傳的HTTP報文格式,這個格式雖說也比較簡單,

java客戶端http報文傳送和解析的詳細程式碼(轉)

HTTP請求報文解剖HTTP請求報文由3部分組成(請求行+請求頭+請求體): 下面是一個實際的請求報文: ①是請求方法,GET和POST是最常見的HTTP方法,除此以外還包括DELETE、HEAD、OPTIONS、PUT、TRACE。不過,當前的大多數瀏覽器只支援GET和P

java客戶端http報文傳送和解析的詳細程式碼

本人新手,最近在java 的xml格式的http報文,希望哪位大俠給指點指點。 現給出報文格式,跪求類似傳送和解析http報文的詳細例子。 傳送的報文格式: POST *********************************************** Acce

Java發送http get/post請求,調用接口/方法

strong org 釋放 github string charset 獲取url lean catch 由於項目中要用,所以找了一些資料,整理下來。 GitHub地址: https://github.com/iamyong 轉自:http://blog.csdn.n