Skip to content

Commit a221afb

Browse files
committed
增加对HTTP文件上传的支持
1 parent 446d9af commit a221afb

4 files changed

Lines changed: 264 additions & 5 deletions

File tree

src/main/java/org/eh/core/common/Constants.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import org.eh.core.util.PropertyUtil;
1212

1313
/**
14-
*
14+
*
1515
* @author guojing
1616
* @date 2014-3-3
1717
*/
@@ -25,7 +25,7 @@ public class Constants {
2525
public static Map<String, String> UrlClassMap = new HashMap<String, String>(); // url与class映射
2626
public static Map<String, String> OTHER_CONFIG_INFO = new HashMap<String, String>(); // 其他配置信息
2727
public static List<String> STATIC_SUFFIXS = new ArrayList<String>(Arrays.asList(".css", ".js",
28-
".jpg", ".png", ".gif")); // 静态文件后缀
28+
".jpg", ".png", ".gif", ".html")); // 静态文件后缀
2929

3030
/* 常量值 */
3131
public static String PROPERTIES_NAME = "web.properties"; // 配置文件名

src/main/java/org/eh/core/http/EHHttpHandler.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.eh.core.common.Constants;
1414
import org.eh.core.common.ReturnType;
1515
import org.eh.core.model.ResultInfo;
16+
import org.eh.core.util.FileUploadContentAnalysis;
1617
import org.eh.core.util.FileUtil;
1718
import org.eh.core.util.IOUtil;
1819
import org.eh.core.util.StringUtil;
@@ -140,7 +141,7 @@ private void responseStaticToClient(HttpExchange httpExchange, Integer code, byt
140141
*/
141142
@SuppressWarnings("rawtypes")
142143
private ResultInfo invokController(HttpExchange httpExchange) throws ClassNotFoundException,
143-
InstantiationException, IllegalAccessException, UnsupportedEncodingException {
144+
InstantiationException, IllegalAccessException, IOException {
144145
String path = httpExchange.getRequestURI().getPath();
145146

146147
String classPath = Constants.UrlClassMap.get(path.substring(0, path.lastIndexOf(".")));
@@ -150,7 +151,23 @@ private ResultInfo invokController(HttpExchange httpExchange) throws ClassNotFou
150151
Class controllerClass = Class.forName(classPath);
151152
Controller controller = (Controller) controllerClass.newInstance();
152153

153-
return controller.process(analysisParms(httpExchange));
154+
Map<String, Object> map = null;
155+
// 判断表单类型,若是multipart/form-data,则是文件上传;否则做普通处理
156+
Headers headers = httpExchange.getRequestHeaders();
157+
// 获取ContentType
158+
String contentType = headers.get("Content-type").toString().replace("[", "")
159+
.replace("]", "");
160+
if (contentType.indexOf("multipart/form-data") != -1) {
161+
// 获取content长度
162+
int length = Integer.parseInt(headers.get("Content-length").toString().replace("[", "")
163+
.replace("]", ""));
164+
map = FileUploadContentAnalysis.parse(httpExchange.getRequestBody(), contentType,
165+
length);
166+
} else {
167+
map = analysisParms(httpExchange);
168+
}
169+
170+
return controller.process(map);
154171
}
155172

156173
/**
@@ -168,15 +185,20 @@ private String invokViewHandler(ResultInfo resultInfo) throws IOException {
168185
private Map<String, Object> analysisParms(HttpExchange httpExchange)
169186
throws UnsupportedEncodingException {
170187
Map<String, Object> map = new HashMap<String, Object>();
188+
171189
URI requestedUri = httpExchange.getRequestURI();
172190
String queryGet = requestedUri.getRawQuery();
173191
String queryPost = IOUtil.getRequestContent(httpExchange.getRequestBody());
192+
System.out.println(queryPost);
174193
String query = "";
175194
if (!StringUtil.isEmpty(queryGet)) {
176195
query = queryGet;
177196
}
178197
if (!StringUtil.isEmpty(queryPost)) {
179-
query = query + "&" + queryPost;
198+
query = StringUtil.isEmpty(query) ? queryPost : (query + "&" + queryPost);
199+
}
200+
if (StringUtil.isEmpty(query)) {
201+
return map;
180202
}
181203

182204
for (String kv : query.split("&")) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.eh.core.model;
2+
3+
public class FileInfo {
4+
5+
private String filename; //文件名
6+
private String fieldname; // 表单中参数名
7+
private int length; //文件长度
8+
private byte[] bytes; //文件字节数组
9+
10+
public String getFilename() {
11+
return filename;
12+
}
13+
public void setFilename(String filename) {
14+
this.filename = filename;
15+
}
16+
public int getLength() {
17+
return length;
18+
}
19+
public void setLength(int length) {
20+
this.length = length;
21+
}
22+
public byte[] getBytes() {
23+
return bytes;
24+
}
25+
public void setBytes(byte[] bytes) {
26+
this.bytes = bytes;
27+
}
28+
29+
public String getFieldname() {
30+
return fieldname;
31+
}
32+
33+
public void setFieldname(String fieldname) {
34+
this.fieldname = fieldname;
35+
}
36+
37+
38+
}
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package org.eh.core.util;
2+
3+
import java.io.BufferedReader;
4+
import java.io.DataInputStream;
5+
import java.io.IOException;
6+
import java.io.InputStream;
7+
import java.io.StringReader;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
11+
import org.eh.core.model.FileInfo;
12+
13+
/**
14+
* 解析content获取上传文件表单信息
15+
* @author guojing
16+
* @date 2014-3-10
17+
*/
18+
public class FileUploadContentAnalysis {
19+
static final int NONE = 0;
20+
static final int DATAHEADER = 1;
21+
static final int FILEDATA = 2;
22+
static final int FIELDDATA = 3;
23+
static final int MXA_SEGSIZE = 1000 * 1024 * 10; //最大文件长度
24+
25+
public static Map<String, Object> parse(InputStream ins, String contentType, int totalLength)
26+
throws IOException {
27+
28+
FileInfo fileInfo =new FileInfo();
29+
String fieldname = ""; // 表单域的名称
30+
String fieldvalue = ""; // 表单域的值
31+
String filename = ""; // 文件名
32+
String boundary = ""; // 分界符
33+
String lastboundary = ""; // 结束符
34+
String filefieldname = ""; // 文件表单域名
35+
Map<String, Object> formfields = new HashMap<String, Object>();
36+
int filesize = 0; // 文件长度
37+
38+
int pos = contentType.indexOf("boundary=");
39+
40+
if (pos != -1) { // 取得分界符和结束符
41+
pos += "boundary=".length();
42+
boundary = "--" + contentType.substring(pos);
43+
lastboundary = boundary + "--";
44+
}
45+
int state = NONE;
46+
// 得到数据输入流reqbuf
47+
DataInputStream in = new DataInputStream(ins);
48+
// 将请求消息的实体送到b变量中
49+
int totalBytes = totalLength;
50+
String message = "";
51+
if (totalBytes > MXA_SEGSIZE) {// 每批大于10m时
52+
message = "Each batch of data can not be larger than " + MXA_SEGSIZE / (1000 * 1024)
53+
+ "M";
54+
return null;
55+
}
56+
byte[] b = new byte[totalBytes];
57+
in.readFully(b);
58+
in.close();
59+
String reqContent = new String(b, "UTF-8");//
60+
BufferedReader reqbuf = new BufferedReader(new StringReader(reqContent));
61+
62+
boolean flag = true;
63+
int i = 0;
64+
while (flag == true) {
65+
String s = reqbuf.readLine();
66+
if ((s == null) || (s.equals(lastboundary)))
67+
break;
68+
69+
switch (state) {
70+
case NONE:
71+
if (s.startsWith(boundary)) {
72+
state = DATAHEADER;
73+
i += 1;
74+
}
75+
break;
76+
case DATAHEADER:
77+
pos = s.indexOf("filename=");
78+
if (pos == -1) { // 将表单域的名字解析出来
79+
pos = s.indexOf("name=");
80+
pos += "name=".length() + 1;
81+
s = s.substring(pos);
82+
int l = s.length();
83+
s = s.substring(0, l - 1);
84+
fieldname = s;
85+
state = FIELDDATA;
86+
} else {
87+
String temp = s;
88+
// 将文件表单参数名解析出来
89+
pos = s.indexOf("name=");
90+
pos += "name=".length() + 1;
91+
s = s.substring(pos);
92+
int pos1 = s.indexOf("\";");
93+
filefieldname = s.substring(0, pos1);
94+
95+
// 将文件名解析出来
96+
pos = s.indexOf("filename=");
97+
pos += "filename=".length() + 1;
98+
s = s.substring(pos);
99+
int l = s.length();
100+
s = s.substring(0, l - 1);// 去掉最后那个引号”
101+
pos = s.lastIndexOf("\\");
102+
s = s.substring(pos + 1);
103+
filename = s;
104+
// 从字节数组中取出文件数组
105+
pos = byteIndexOf(b, temp, 0);
106+
b = subBytes(b, pos + temp.getBytes().length + 2, b.length);// 去掉前面的部分
107+
int n = 0;
108+
/**
109+
* 过滤boundary下形如 Content-Disposition: form-data; name="bin"; filename="12.pdf" Content-Type:
110+
* application/octet-stream Content-Transfer-Encoding: binary 的字符串
111+
*/
112+
while ((s = reqbuf.readLine()) != null) {
113+
if (n == 1)
114+
break;
115+
if (s.equals(""))
116+
n++;
117+
118+
b = subBytes(b, s.getBytes().length + 2, b.length);
119+
}
120+
pos = byteIndexOf(b, boundary, 0);
121+
if (pos != -1)
122+
b = subBytes(b, 0, pos - 1);
123+
124+
filesize = b.length - 1;
125+
state = FILEDATA;
126+
}
127+
break;
128+
case FIELDDATA:
129+
s = reqbuf.readLine();
130+
fieldvalue = s;
131+
formfields.put(fieldname, fieldvalue);
132+
state = NONE;
133+
break;
134+
case FILEDATA:
135+
while ((!s.startsWith(boundary)) && (!s.startsWith(lastboundary))) {
136+
s = reqbuf.readLine();
137+
if (s.startsWith(boundary)) {
138+
state = DATAHEADER;
139+
break;
140+
}
141+
}
142+
break;
143+
}
144+
}
145+
fileInfo.setFieldname(filefieldname);
146+
fileInfo.setBytes(b);
147+
fileInfo.setFilename(filename);
148+
fileInfo.setLength(filesize);
149+
formfields.put(filefieldname, fileInfo);
150+
return formfields;
151+
152+
}
153+
154+
// 字节数组中的INDEXOF函数,与STRING类中的INDEXOF类似
155+
public static int byteIndexOf(byte[] b, String s, int start) {
156+
return byteIndexOf(b, s.getBytes(), start);
157+
}
158+
159+
// 字节数组中的INDEXOF函数,与STRING类中的INDEXOF类似
160+
public static int byteIndexOf(byte[] b, byte[] s, int start) {
161+
int i;
162+
if (s.length == 0) {
163+
return 0;
164+
}
165+
int max = b.length - s.length;
166+
if (max < 0)
167+
return -1;
168+
if (start > max)
169+
return -1;
170+
if (start < 0)
171+
start = 0;
172+
search: for (i = start; i <= max; i++) {
173+
if (b[i] == s[0]) {
174+
int k = 1;
175+
while (k < s.length) {
176+
if (b[k + i] != s[k]) {
177+
continue search;
178+
}
179+
k++;
180+
}
181+
return i;
182+
}
183+
}
184+
return -1;
185+
}
186+
187+
// 用于从一个字节数组中提取一个字节数组
188+
public static byte[] subBytes(byte[] b, int from, int end) {
189+
byte[] result = new byte[end - from];
190+
System.arraycopy(b, from, result, 0, end - from);
191+
return result;
192+
}
193+
194+
// 用于从一个字节数组中提取一个字符串
195+
public static String subBytesString(byte[] b, int from, int end) {
196+
return new String(subBytes(b, from, end));
197+
}
198+
199+
}

0 commit comments

Comments
 (0)