Spring 3.0 RESTful控制器在重定向时失败

时间:2010-07-01 07:23:20

标签: spring rest redirect spring-mvc

我正在为具有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工具)不知道如何处理它。只是一个猜测...

提前致谢。

1 个答案:

答案 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;
    }
}