Java vertx 3.2 file upload using bodyhandler -
java.lang.illegalstateexception: request has been read exception in vertx3.0. tried in many ways. simple formupload working fine. when use body handler, throwing below exception. can ?
import io.vertx.core.abstractverticle; import io.vertx.core.http.httpheaders; import io.vertx.ext.web.router; import io.vertx.ext.web.handler.bodyhandler; /* * @author gogs */ public class testserver extends abstractverticle { // convenience method can run in ide public static void main(string[] args) { runner.runexample(testserver.class); } @override public void start() throws exception { router router = router.router(vertx); // enable multipart form data parsing router.route().handler(bodyhandler.create()); router.route("/").handler(routingcontext -> { routingcontext.response().putheader("content-type", "text/html").end( "<form action=\"/form\" enctype=\"multipart/form-data\" method=\"post\" name=\"wibble\">\n" + "choose file upload:<input type=\"file\" name=\"myfile\"/><br>"+ " <input type=\"submit\"/>"+ "</form>" ); }); // handle form router.post("/form").handler(ctx -> { ctx.request().setexpectmultipart(true); ctx.request().uploadhandler(upload -> { upload.exceptionhandler(cause -> { ctx.response().setchunked(true).end("upload failed"); }); upload.endhandler(v -> { ctx.response().setchunked(true).end("successfully uploaded " + upload.filename()); }); // fixme - potential security exploit! in real system must check filename // make sure you're not saving place don't want! // or better still, use vert.x-web controls upload area. upload.streamtofilesystem(upload.filename()); }); }); vertx.createhttpserver().requesthandler(router::accept).listen(8090); } } seeing below exception. feb 02, 2016 6:48:54 pm io.vertx.ext.web.impl.routingcontextimplbase severe: unexpected exception in route java.lang.illegalstateexception: request has been read @ io.vertx.core.http.impl.httpserverrequestimpl.checkended(httpserverrequestimpl.java:426) @ io.vertx.core.http.impl.httpserverrequestimpl.setexpectmultipart(httpserverrequestimpl.java:322) @ io.vertx.ext.web.impl.httpserverrequestwrapper.setexpectmultipart(httpserverrequestwrapper.java:166) @ com.vertx.http.upload.testserver.lambda$1(testserver.java:43) @ io.vertx.ext.web.impl.routeimpl.handlecontext(routeimpl.java:221) @ io.vertx.ext.web.impl.routingcontextimplbase.iteratenext(routingcontextimplbase.java:78) @ io.vertx.ext.web.impl.routingcontextimpl.next(routingcontextimpl.java:93) @ io.vertx.ext.web.handler.impl.bodyhandlerimpl$bhandler.doend(bodyhandlerimpl.java:155) @ io.vertx.ext.web.handler.impl.bodyhandlerimpl$bhandler.uploadended(bodyhandlerimpl.java:135) @ io.vertx.ext.web.handler.impl.bodyhandlerimpl$bhandler.lambda$null$35(bodyhandlerimpl.java:109) @ io.vertx.core.http.impl.httpserverfileuploadimpl.notifyendhandler(httpserverfileuploadimpl.java:213) @ io.vertx.core.http.impl.httpserverfileuploadimpl.lambda$handlecomplete$165(httpserverfileuploadimpl.java:206) @ io.vertx.core.file.impl.asyncfileimpl.lambda$doclose$226(asyncfileimpl.java:470) @ io.vertx.core.impl.contextimpl.lambda$wraptask$16(contextimpl.java:335) @ io.netty.util.concurrent.singlethreadeventexecutor.runalltasks(singlethreadeventexecutor.java:358) @ io.netty.channel.nio.nioeventloop.run(nioeventloop.java:357) @ io.netty.util.concurrent.singlethreadeventexecutor$2.run(singlethreadeventexecutor.java:112) @ java.lang.thread.run(unknown source)
you reading request body twice. first read via bodyhandler
(see bodyhanderimpl
) , second own handler (see httpserverrequestimpl
, httpserverfileuploadimpl
).
bodyhandler
reads body request , makes available in context.body
. way router configured:
router.route().handler(bodyhandler.create());
the body read on every single request handled router.
your handler reading request body , writing contents file system. router configured execute handler when post made /form
.
to recap flow, when submit upload /form
bodyhandler
reading request fully, storing contents in context.body, , marking request body read. router matches uri path upload handler , attempts read body again since has been read exception raised.
some thoughts...
if intent write uploaded file file system don't need bodyhandler configured in router. want use bodyhandler when needed body in memory in order process in way. unless intend execute handler on single request received router, should not configure handler without matching criteria (i.e. router.route().handler(...)
). use case type of handler cookiehandler.
Comments
Post a Comment