Skip to content

Commit 49129a3

Browse files
committed
Simplify multipart attachment handling.
1 parent dd14ffb commit 49129a3

File tree

3 files changed

+99
-100
lines changed

3 files changed

+99
-100
lines changed

httprpc-test/src/main/webapp/index.jsp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
<a href="${pageContext.request.contextPath}/test?api">Test (API)</a><br/>
6767
<br/>
6868
<a href="${pageContext.request.contextPath}/test?string=héllo&strings=a&strings=b&strings=c&number=123&flag=true&date=0&localDate=2018-06-28&localTime=10:45&localDateTime=2018-06-28T10:45">GET</a><br/>
69-
<a href="${pageContext.request.contextPath}/test/a/123/b/héllo/c/456/d/göodbye">GET (Key List)</a><br/>
69+
<a href="${pageContext.request.contextPath}/test/a/123/b/héllo/c/456/d/göodbye">GET (Keys)</a><br/>
7070
<a href="${pageContext.request.contextPath}/test/fibonacci">GET (Fibonacci)</a><br/>
7171

7272
<hr/>

httprpc/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ plugins {
2020
}
2121

2222
group = 'org.httprpc'
23-
version = '5.9.1'
23+
version = '5.9.2'
2424

2525
repositories {
2626
mavenCentral()

httprpc/src/main/java/org/httprpc/WebService.java

Lines changed: 97 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package org.httprpc;
1616

1717
import java.io.BufferedReader;
18-
import java.io.File;
1918
import java.io.IOException;
2019
import java.io.InputStream;
2120
import java.io.InputStreamReader;
@@ -25,8 +24,9 @@
2524
import java.lang.reflect.Parameter;
2625
import java.lang.reflect.ParameterizedType;
2726
import java.lang.reflect.Type;
28-
import java.net.MalformedURLException;
2927
import java.net.URL;
28+
import java.net.URLConnection;
29+
import java.net.URLStreamHandler;
3030
import java.util.ArrayList;
3131
import java.util.Arrays;
3232
import java.util.Collections;
@@ -72,6 +72,39 @@ private static class Resource {
7272
public String key = null;
7373
}
7474

75+
private static class PartURLConnection extends URLConnection {
76+
private Part part;
77+
78+
public PartURLConnection(URL url, Part part) {
79+
super(url);
80+
81+
this.part = part;
82+
}
83+
84+
@Override
85+
public void connect() {
86+
// No-op
87+
}
88+
89+
@Override
90+
public InputStream getInputStream() throws IOException {
91+
return part.getInputStream();
92+
}
93+
}
94+
95+
private static class PartURLStreamHandler extends URLStreamHandler {
96+
private Part part;
97+
98+
public PartURLStreamHandler(Part part) {
99+
this.part = part;
100+
}
101+
102+
@Override
103+
protected URLConnection openConnection(URL url) {
104+
return new PartURLConnection(url, part);
105+
}
106+
}
107+
75108
private Resource root = null;
76109

77110
private ThreadLocal<HttpServletRequest> request = new ThreadLocal<>();
@@ -213,109 +246,96 @@ protected void service(HttpServletRequest request, HttpServletResponse response)
213246
request.setCharacterEncoding(UTF_8);
214247
}
215248

216-
this.request.set(request);
217-
this.response.set(response);
249+
Map<String, List<?>> parameterMap = new HashMap<>();
218250

219-
this.keyList.set(keyList);
220-
this.keyMap.set(keyMap);
251+
Enumeration<String> parameterNames = request.getParameterNames();
221252

222-
LinkedList<File> files = new LinkedList<>();
253+
while (parameterNames.hasMoreElements()) {
254+
String name = parameterNames.nextElement();
223255

224-
try {
225-
Map<String, List<?>> parameterMap = new HashMap<>();
226-
227-
Enumeration<String> parameterNames = request.getParameterNames();
228-
229-
while (parameterNames.hasMoreElements()) {
230-
String name = parameterNames.nextElement();
231-
232-
parameterMap.put(name, Arrays.asList(request.getParameterValues(name)));
233-
}
234-
235-
String contentType = request.getContentType();
236-
237-
if (contentType != null && contentType.startsWith("multipart/form-data")) {
238-
for (Part part : request.getParts()) {
239-
String submittedFileName = part.getSubmittedFileName();
240-
241-
if (submittedFileName == null || submittedFileName.length() == 0) {
242-
continue;
243-
}
256+
parameterMap.put(name, Arrays.asList(request.getParameterValues(name)));
257+
}
244258

245-
String name = part.getName();
259+
String contentType = request.getContentType();
246260

247-
ArrayList<File> values = (ArrayList<File>)parameterMap.get(name);
261+
if (contentType != null && contentType.startsWith("multipart/form-data")) {
262+
for (Part part : request.getParts()) {
263+
String submittedFileName = part.getSubmittedFileName();
248264

249-
if (values == null) {
250-
values = new ArrayList<>();
265+
if (submittedFileName == null || submittedFileName.length() == 0) {
266+
continue;
267+
}
251268

252-
parameterMap.put(name, values);
253-
}
269+
String name = part.getName();
254270

255-
File file = File.createTempFile(part.getName(), "_" + submittedFileName);
271+
ArrayList<URL> values = (ArrayList<URL>)parameterMap.get(name);
256272

257-
files.add(file);
258-
values.add(file);
273+
if (values == null) {
274+
values = new ArrayList<>();
259275

260-
part.write(file.getAbsolutePath());
276+
parameterMap.put(name, values);
261277
}
262-
}
263278

264-
Method method = getMethod(handlerList, parameterMap);
265-
266-
if (method == null) {
267-
response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
268-
return;
279+
values.add(new URL("part", null, -1, submittedFileName, new PartURLStreamHandler(part)));
269280
}
281+
}
270282

271-
Object result;
272-
try {
273-
result = method.invoke(this, getArguments(method, parameterMap));
274-
} catch (InvocationTargetException | IllegalAccessException exception) {
275-
if (response.isCommitted()) {
276-
throw new ServletException(exception);
277-
} else {
278-
Throwable cause = exception.getCause();
279-
280-
if (cause != null) {
281-
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
282-
response.setContentType(String.format("text/plain;charset=%s", UTF_8));
283+
Method method = getMethod(handlerList, parameterMap);
283284

284-
PrintWriter writer = response.getWriter();
285+
if (method == null) {
286+
response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
287+
return;
288+
}
285289

286-
writer.append(cause.getMessage());
287-
writer.flush();
290+
this.request.set(request);
291+
this.response.set(response);
288292

289-
return;
290-
} else {
291-
throw new ServletException(exception);
292-
}
293-
}
294-
}
293+
this.keyList.set(keyList);
294+
this.keyMap.set(keyMap);
295295

296+
Object result;
297+
try {
298+
result = method.invoke(this, getArguments(method, parameterMap));
299+
} catch (InvocationTargetException | IllegalAccessException exception) {
296300
if (response.isCommitted()) {
297-
return;
298-
}
301+
throw new ServletException(exception);
302+
} else {
303+
Throwable cause = exception.getCause();
299304

300-
Class<?> returnType = method.getReturnType();
305+
if (cause != null) {
306+
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
307+
response.setContentType(String.format("text/plain;charset=%s", UTF_8));
301308

302-
if (returnType != Void.TYPE && returnType != Void.class) {
303-
response.setStatus(HttpServletResponse.SC_OK);
309+
PrintWriter writer = response.getWriter();
304310

305-
encodeResult(request, response, result);
306-
} else {
307-
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
311+
writer.append(cause.getMessage());
312+
writer.flush();
313+
314+
return;
315+
} else {
316+
throw new ServletException(exception);
317+
}
308318
}
309319
} finally {
310320
this.request.set(null);
311321
this.response.set(null);
312322

313323
this.keyList.set(null);
314324
this.keyMap.set(null);
325+
}
315326

316-
for (File file : files) {
317-
file.delete();
318-
}
327+
if (response.isCommitted()) {
328+
return;
329+
}
330+
331+
Class<?> returnType = method.getReturnType();
332+
333+
if (returnType != Void.TYPE && returnType != Void.class) {
334+
response.setStatus(HttpServletResponse.SC_OK);
335+
336+
encodeResult(request, response, result);
337+
} else {
338+
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
319339
}
320340
}
321341

@@ -378,7 +398,7 @@ private static Object[] getArguments(Method method, Map<String, List<?>> paramet
378398
list = new ArrayList<>(values.size());
379399

380400
for (Object value : values) {
381-
list.add(getArgument(value, (Class<?>)elementType));
401+
list.add(BeanAdapter.adapt(value, (Class<?>)elementType));
382402
}
383403
} else {
384404
list = Collections.emptyList();
@@ -393,7 +413,7 @@ private static Object[] getArguments(Method method, Map<String, List<?>> paramet
393413
value = null;
394414
}
395415

396-
argument = getArgument(value, type);
416+
argument = BeanAdapter.adapt(value, type);
397417
}
398418

399419
arguments[i] = argument;
@@ -408,27 +428,6 @@ private static String getName(Parameter parameter) {
408428
return (requestParameter == null) ? parameter.getName() : requestParameter.value();
409429
}
410430

411-
private static Object getArgument(Object value, Class<?> type) {
412-
Object argument;
413-
if (type == URL.class) {
414-
if (value == null) {
415-
argument = null;
416-
} else if (value instanceof File) {
417-
try {
418-
argument = ((File)value).toURI().toURL();
419-
} catch (MalformedURLException exception) {
420-
throw new RuntimeException(exception);
421-
}
422-
} else {
423-
throw new IllegalArgumentException();
424-
}
425-
} else {
426-
argument = BeanAdapter.adapt(value, type);
427-
}
428-
429-
return argument;
430-
}
431-
432431
/**
433432
* Returns the servlet request.
434433
*

0 commit comments

Comments
 (0)