我的
Java spring REST API控制器如下所示:
public void signup(@RequestBody RequestBody requestBody) throws IOException,ServletException {
我得到这个例外:
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Stream closed; nested exception is java.io.IOException: Stream closed
发生这种情况是因为我想将请求体强制转换为RequestBody类(打开请求输入流并完成它),并将其转发/重定向到另一个端点.
实际的控制器是:
@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) { } }
我该怎么处理?
解决方法
请求主体对象是一个只能读取一次的流.所以转发它并不是一件轻而易举的事.解决此问题的一种方法是创建一个过滤器,该过滤器读取输入流并将输入流替换为可以多次读取的内容.示例可以在另一个答案中找到:
How can I read request body multiple times in Spring ‘HandlerMethodArgumentResolver’?
至于你的方法,还有另一个问题:
public void signup(@RequestBody RequestBody requestBody)
据我所知,RequestBody是一个注释,你不能像那样映射它.但是要获取原始数据,可以将其映射为String.
public void signup(@RequestBody String requestBody)
然后,您可以使用String请求体手动对要转发的api进行REST调用.只需确保将内容类型设置为原始类型,我假设在这种情况下将是JSON.