我正在为具有XML表示的Todo资源设置一个简单的RESTful控制器。一切都很好 - 直到我尝试重定向。例如,当我POST
新Todo并尝试重定向到其新网址时(例如/todos/5
),我收到以下错误:
Error 500 Unable to locate object to be marshalled in model: {}
我知道POST
有效,因为我可以手动转到新网址(/todos/5
)并查看新创建的资源。它只有在尝试重定向时我才会失败。我知道在我的例子中我可以返回新创建的Todo对象,但我还有其他情况,重定向是有意义的。该错误看起来像一个编组问题,但就像我说的那样,它只会在我向RESTful方法添加重定向时才会出现,如果手动点击我重定向到的URL则不会发生。
代码片段:
@Controller
@RequestMapping("/todos")
public class TodoController {
@RequestMapping(value="/{id}", method=GET)
public Todo getTodo(@PathVariable long id) {
return todoRepository.findById(id);
}
@RequestMapping(method=POST)
public String newTodo(@RequestBody Todo todo) {
todoRepository.save(todo); // generates and sets the ID on the todo object
return "redirect:/todos/" + todo.getId();
}
... more methods ...
public void setTodoRepository(TodoRepository todoRepository) {
this.todoRepository = todoRepository;
}
private TodoRepository todoRepository;
}
你能发现我失踪的东西吗?我怀疑它可能与返回重定向字符串有关 - 也许它不是触发重定向而是实际传递给我的视图解析器使用的XML编组视图(未显示 - 但是所有在线示例的典型),和JAXB(配置的OXM工具)不知道如何处理它。只是一个猜测...
提前致谢。
答案 0 :(得分:2)
这是因为redirect:
前缀由InternalResourceViewResolver
处理(实际上是UrlBasedViewResolver
)。因此,如果您没有InternalResourceViewResolver
或者您的请求在视图解析过程中没有进入,则不会处理重定向。
要解决此问题,您可以从控制器方法返回RedirectView
,也可以添加自定义视图解析程序来处理重定向:
public class RedirectViewResolver implements ViewResolver, Ordered {
private int order = Integer.MIN_VALUE;
public View resolveViewName(String viewName, Locale arg1) throws Exception {
if (viewName.startsWith(UrlBasedViewResolver.REDIRECT_URL_PREFIX)) {
String redirectUrl = viewName.substring(UrlBasedViewResolver.REDIRECT_URL_PREFIX.length());
return new RedirectView(redirectUrl, true);
}
return null;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}