我的Java spring REST API控制器如下所示:
public void signup(@RequestBody RequestBody requestBody) throws IOException, ServletException {
Run Code Online (Sandbox Code Playgroud)
我得到这个例外:
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Stream closed; nested exception is java.io.IOException: Stream closed
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为我想将请求体强制转换为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) {
}
}
Run Code Online (Sandbox Code Playgroud)
我该怎么处理?
小智 5
您可以转发到ExceptionHandler中的登录页面,如下所示:
@RequestMapping(value = "/signup", method = RequestMethod.POST)
public void signup(@RequestBody CustomUserDetails user, HttpServletResponse response) {
String userName = user.getUsername();
logger.debug("User signup attempt with username: " + userName);
//try{
if (customUserDetailsService.exists(userName)) {
logger.debug("Duplicate username " + userName);
throw new SignupException(userName + " already exists");
} else {
customUserDetailsService.save(user);
authenticateUserAndSetSession(user, response);
}
/*} catch(Exception ex) {
}*/
}
Run Code Online (Sandbox Code Playgroud)
在同一个Controller中定义ExceptionHandler:
@ExceptionHandler(SignupException.class)
public String duplicateName() {
return "login";
}
Run Code Online (Sandbox Code Playgroud)
并且SignupException可能是这样的:
public class SignupException extends RuntimeException {
public SignupException(String message) {
super(message);
}
public SignupException() {
}
}
Run Code Online (Sandbox Code Playgroud)
请求主体对象是一个只能读取一次的流。所以转发它并不是一件很简单的事。解决这个问题的一种方法是创建一个过滤器来读取输入流并将输入流替换为可以多次读取的内容。示例可以在另一个答案中找到:
如何在 Spring 'HandlerMethodArgumentResolver' 中多次读取请求正文?
至于你的方法,还存在另一个问题:
public void signup(@RequestBody RequestBody requestBody)
Run Code Online (Sandbox Code Playgroud)
据我所知,RequestBody 是一个注释,你不能这样映射它。但要获取原始数据,您可以将其映射为字符串。
public void signup(@RequestBody String requestBody)
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用 String 请求正文手动对要转发到的 api 进行 REST 调用。只需确保将内容类型设置为原始类型,我假设在本例中为 JSON。
| 归档时间: |
|
| 查看次数: |
6624 次 |
| 最近记录: |