使用MvcUriComponentsBuilder :: fromMethodCall和String作为返回类型

时间:2015-02-18 09:42:02

标签: spring spring-mvc

我想使用MvcUriComponentsBuilder::fromMethodCall方法从我的控制器构建网址。我通常有一个String返回类型(返回视图名称)和一个Model实例作为我的控制器方法中的方法参数,如:

@Controller
public class MyController {
    @RequestMapping("/foo")
    public String foo(Model uiModel) {
        uiModel.addAttribute("pi", 3.1415);
        return "fooView";
    }
}

我尝试生成一个网址,例如像:

String url = MvcUriComponentsBuilder.fromMethodCall(on(MyController.class).foo(null)).build().toUriString();

这导致了这个例外:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class java.lang.String
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) ~[spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]

这是因为String返回类型想要代理,但不能作为最终类。

有什么方法可以克服这个问题?我想将String保持为返回类型,并从我的控制器方法中的参数获取Model作为输入,因为IMHO比在每个控制器方法中处理ModelAndView实例更容易。

2 个答案:

答案 0 :(得分:2)

fromMethodCall在此过程中使用CGLIB代理,这就是您遇到此问题的原因。本文详细说明原因。 https://github.com/spring-projects/spring-hateoas/issues/155 。如果要维护String返回类型,请尝试使用fromMethodName。

MvcUriComponentsBuilder.fromMethodName(MyController.class, "foo", new Object()).build();

答案 1 :(得分:0)

考虑更改方法的签名以返回Spring的ModelAndView与返回String。例如:

@Controller
public class MyController {
    @RequestMapping("/foo")
    public ModelAndView foo() {
        return new ModelAndView("fooView", "pi", 3.1415);
    }
}

使用这个重构的签名,相应的fromMethodCall调用将如下所示:

UriComponents uri = fromMethodCall(on(MyController.class).foo()).build();