Java – use @ requestbody and forward to another endpoint to throw an exception and close the stream
My java spring rest API controller is as follows:
public void signup(@RequestBody RequestBody requestBody) throws IOException,ServletException {
I get this exception:
@R_403_1455@ to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Stream closed; nested exception is java.io.IOException: Stream closed
This happens because I want to cast the request body to the requestbody class (open the request input stream and complete it) and forward / redirect it to another endpoint
The actual controller is:
@RequestMapping(value = "/signup",method = RequestMethod.POST) public void signup(@RequestBody CustomUserDetails user,HttpServletRequest request,HttpServletResponse response) { String userName = user.getUsername(); logger.debug("User signup attempt with username: " + userName); try{ if(customUserDetailsService.exists(userName)) { logger.debug("Duplicate username " + userName); userName + " already exists"); String newUrl = "login"; RequestDispatcher view = request.getRequestDispatcher(newUrl); view.forward(request,response); } else { customUserDetailsService.save(user); authenticateUserAndSetSession(user,response); } } catch(Exception ex) { } }
What should I do?
Solution
The request body object is a stream that can only be read once So forwarding it is not an easy task One way to solve this problem is to create a filter that reads the input stream and replaces it with something that can be read multiple times Examples can be found in another answer:
How can I read request body multiple times in Spring ‘HandlerMethodArgumentResolver’?
As for your method, there is another problem:
public void signup(@RequestBody RequestBody requestBody)
As far as I know, requestbody is an annotation, and you can't map it like that However, to get the raw data, you can map it to string
public void signup(@RequestBody String requestBody)
You can then manually make rest calls to the API to be forwarded using the string request body Just make sure that the content type is set to the original type, and I assume that in this case it will be JSON