1515package org .httprpc ;
1616
1717import java .io .BufferedReader ;
18- import java .io .File ;
1918import java .io .IOException ;
2019import java .io .InputStream ;
2120import java .io .InputStreamReader ;
2524import java .lang .reflect .Parameter ;
2625import java .lang .reflect .ParameterizedType ;
2726import java .lang .reflect .Type ;
28- import java .net .MalformedURLException ;
2927import java .net .URL ;
28+ import java .net .URLConnection ;
29+ import java .net .URLStreamHandler ;
3030import java .util .ArrayList ;
3131import java .util .Arrays ;
3232import 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