個人編寫的小demo,拿走直接可以用,以下是EfengPayload.java的源文件,用法在下面寫
1 import java.awt.image.BufferedImage; 2 import java.io.BufferedInputStream; 3 import java.io.ByteArrayInputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.util.HashMap; 7 import java.util.Map; 8 import javax.imageio.ImageIO; 9 import javax.servlet.ServletException; 10 import javax.servlet.http.HttpServletRequest; 11 12 public class EfengPayload { 13 private byte[] reqdata; 14 private byte[] boundary; 15 Map<String, String> payloadinfo; 16 17 EfengPayload(HttpServletRequest req) throws ServletException, IOException { 18 this.initInputData(req); 19 } 20 21 private void initInputData(HttpServletRequest req) throws ServletException, 22 IOException {// 初始化payload 23 boundary = req.getHeader("Content-Type").split("boundary=")[1] 24 .getBytes();// 獲取payload的隨機分割線 25 int ra; 26 InputStream in = req.getInputStream();// 獲取輸入流 27 BufferedInputStream br = new BufferedInputStream(in);// 緩沖流接收輸入流 28 29 int byteslen = req.getContentLength();// 獲取輸入流長度 30 reqdata = new byte[byteslen];// 新建保存payload所有數據數組 31 for (int i = 0; (ra = br.read()) != -1; i++) { 32 reqdata[i] = (byte) ra;// 從緩沖流讀取所有的數據賦值給reqdata,之后都是對這個數組進行操作 33 } 34 br.close(); 35 in.close(); 36 37 payloadinfo = new HashMap<String, String>();// 新建map,格式 38 // name->[0,1,2];0:代表內容起始位1:代表下一個內容的分割線起始位,2:當前內容起始位 39 int a[] = new int[256];// 存放每個分割線所處位置的標記數組 40 int aindex = 0;// 上面a數組的配套下標 41 for (int i = 0; i < reqdata.length; i++) {// 從頭到尾遍歷輸入流數據 42 if (reqdata[i] == boundary[0]) { 43 for (int j = 1; j < boundary.length; j++) { 44 if (reqdata[i + j] != boundary[j]) 45 break; 46 if (j == boundary.length - 1) {// 如果有一段與boundary(隨機字母分割線)匹配則將當前位置記錄 47 a[aindex++] = i;// 記錄當前a數組位置 48 } 49 50 } 51 } 52 } 53 byte[] namebyte = " name=\"".getBytes();// name特征byte數組 例如name="xxxxx 54 boolean finded = false;// 分辨當前數據塊是否找到 55 for (int j = 0; j < aindex - 1; j++) { 56 int xb = a[j];// 獲取當前數據塊的起始坐標數值 57 finded = false;// 每次進入前設置沒找到 58 for (int k = xb; k < a[j + 1]; k++) { 59 if (reqdata[k] == namebyte[0]) { 60 61 for (int m = 1; m < namebyte.length; m++) { 62 63 if (reqdata[k + m] != namebyte[m]) 64 break; 65 if (m == namebyte.length - 1) {// 從namebyte的第一位到最后一位都匹配成功 66 finded = true;// 找到name 67 StringBuilder mapname = new StringBuilder(); 68 int n; 69 for (n = k + m + 1;; n++) {// 請求數據從name=“位置+1處開始收集name信息 70 if (reqdata[n] == (byte) '\"')// 如果”意味着name收集結束,通常格式name=“xxx” 71 break; 72 mapname.append((char) reqdata[n]);// 填入當前位 73 } 74 for (int o = n + 1; o < a[j + 1]; o++) {// 繼續往下一直搜索直到搜索到數據開頭處 75 if (reqdata[o] == (byte) '\n' 76 && reqdata[o - 2] == (byte) '\n') {// 特征符合 77 payloadinfo.put(mapname.toString(), o + 1 78 + "," + a[j + 1] + "," + a[j]);// map中記錄當前數據塊的name 79 // ,內容起始位,下一個內容的分割線起始位,當前內容起始位 80 break; 81 } 82 83 } 84 85 } 86 if (finded)// 如果找到跳出當前循環 87 break; 88 } 89 } 90 if (finded)// 如果找到跳出當前循環 91 break; 92 } 93 } 94 } 95 96 public byte[] getPayloadByteValue(String name) { 97 String[] indexs = payloadinfo.get(name).split(",");// 私有map中記錄的各塊的基本信息 98 int bstart = Integer.parseInt(indexs[0]), bend = Integer 99 .parseInt(indexs[1]);// 數據起始位與下一數據頭(頭分割線)的起始位 100 101 for (int j = bend;; j--) { 102 if (reqdata[j] == 10 && reqdata[j - 1] == 13) { 103 bend = j - 1;// 找到特征,確定結束位置 104 break; 105 } 106 } 107 byte[] retbyt = new byte[bend - bstart];// 確定返回數組大小 108 for (int i = bstart; i < bend; i++) {// 取出區間數據 109 retbyt[i - bstart] = reqdata[i]; 110 } 111 112 return retbyt; 113 114 } 115 public String getPayloadValue(String name){ 116 StringBuilder retstr=new StringBuilder(); 117 byte[] bytename=getPayloadByteValue(name); 118 for(byte a : bytename) 119 retstr.append((char)a); 120 return retstr.toString(); 121 } 122 public String getPayloadOthers(String name, String type) { 123 if ("Content-Type".equals(type)) 124 type = "\n" + type + ": "; 125 else 126 type = (" " + type + "=\""); 127 byte[] typebyte = type.getBytes(); 128 int end = Integer.parseInt(payloadinfo.get(name).split(",")[0]);// 0代表數據起始位置 129 int start = Integer.parseInt(payloadinfo.get(name).split(",")[2]);// 2代表數據前面標記的起始位置 130 for (int i = start; i < end; i++) { 131 if (reqdata[i] == typebyte[0]) { 132 for (int j = 1; j < typebyte.length; j++) { 133 if (reqdata[i + j] != typebyte[j]) 134 break; 135 if (j == typebyte.length - 1) { 136 String rtsstr = ""; 137 for (int k = i + j + 1;; k++) { 138 if ((char) reqdata[k] == ';' 139 || (char) reqdata[k] == '\"' 140 || (char) reqdata[k] == '\n' 141 || (char) reqdata[k] == (char)13)//回車 142 return rtsstr; 143 rtsstr += (char) reqdata[k]; 144 } 145 } 146 } 147 } 148 } 149 return null; 150 } 151 152 public BufferedImage getImage(String name) throws IOException { 153 154 byte nameByte[] = this.getPayloadByteValue(name); 155 ByteArrayInputStream imageinput = new ByteArrayInputStream(nameByte); 156 BufferedImage buf = ImageIO.read(imageinput); 157 return buf; 158 } 159 }
用法1:接收圖片並向servlet的響應輸出流中輸出圖片
前端代碼
1 <form method="post" target="_top" action="MyFileTest" enctype="multipart/form-data"> 2 選擇一個文件: 3 <input type="file" name="file" /><br/> 5 <input type="submit" value="上傳" /> 6 </form>
后端代碼
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { EfengPayload efeng=new EfengPayload(req); ImageIO.write( efeng.getImage("file"), //參數file是前端傳來的name值 efeng.getPayloadOthers("file", "Content-Type") .split("/")[1],//根據name值(file)查詢文件類型 resp.getOutputStream() ); }
用法2:根據name獲取指定的value值
前端添加input組件
1 <form method="post" target="_top" action="MyFileTest" enctype="multipart/form-data"> 2 選擇一個文件: 3 <input type="file" name="file" /> 4 <br/><input type="text" name="username" /><br/>//前端增加username輸入框 5 <input type="submit" value="上傳" /> 6 </form>
后端添加對應獲取語句,如下紅色部分
1 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 2 throws ServletException, IOException { 3 EfengPayload efeng=new EfengPayload(req); 4 ImageIO.write( 5 efeng.getImage("file"), 6 efeng.getPayloadOthers("file", "Content-Type") 7 .split("/")[1], 8 resp.getOutputStream() 9 ); 10 System.out.println(efeng.getPayloadValue("username"));//獲取前端name為username的組件值 11 12 }
efeng.getPayloadOthers("對應name名", "想獲取的項"),例如想獲得下面name為file的filename就可以執行:
String str=efeng.getPayloadOthers("file", "filename");
想獲得下面的數據部分可以執行
byte[] bytedata=efeng.getPayloadByteValue("file");

