个人编写的小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");
来源:https://www.cnblogs.com/efengsoft/p/12631626.html