Gajendra Kumar
Gajendra Kumar

Reputation: 928

request forwarding with ServletHttpHandlerAdapter spring web-flux in servlet 3.1 container

As per documentation on servlet 3.1 container ServletHttpHandlerAdapter can be registered as a servlet and can support nio. I need to forward request to some other resource as below

asyncContext.getRequest().getServletContext().getRequestDispatcher("/OtherResource")
                .forward(asyncContext.getRequest(), asyncContext.getResponse());

on calling forward i'm getting below error.

java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:624)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:211)
at com.nucleus.OtherServlet.doGet(OtherServlet.java:30)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:470)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:395)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316)
at com.nucleus.AsyncRequestProcessor.run(AsyncRequestProcessor.java:55)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Which is correct as spring creates org.springframework.http.server.reactive.ServletServerHttpResponse and calls response.getOutputStream() initially, now how to support request forwarding?

Issue also logged to spring jira for discussion - Link

Upvotes: 0

Views: 835

Answers (1)

Brian Clozel
Brian Clozel

Reputation: 59141

Spring WebFlux can be deployed on a Servlet 3.1 container thanks to the ServletHttpHandlerAdapter - but it doesn't mean you are allowed to use Servlet specific APIs in that application.

First, once you're using the async I/O Servlet features you're not allowed to mix them with blocking I/O calls on the Servlet API (see this presentation about Servlet 3.1 async IO).

So in general, you should never try and fetch Servlet-specific objects from the ServerWebExchange, but rather code against this new HTTP foundation in Spring WebFlux.

There is an issue about supporting forwarding at the WebFlux level, but I'm not sure this would ultimately solve your problem. I don't understand the specifics of the issue you're hitting, but Spring WebFlux already supports templating engines that use blocking I/O (see Freemarker support here).

If the templating engine you're trying to support is tied to Servlet, then you won't be able to get proper WebFlux support as you can run Spring WebFlux applications on non-servlet environments.

Upvotes: 0

Related Questions