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

Jam*_*mes 5 spring spring-mvc

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

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

我尝试生成一个 URL,例如:

String url = MvcUriComponentsBuilder.fromMethodCall(on(MyController.class).foo(null)).build().toUriString();
Run Code Online (Sandbox Code Playgroud)

这导致了这个异常:

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]
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为 String 返回类型想要被代理,但不能作为最终类。

有什么方法可以克服这个问题?我想保留 String 作为返回类型,并从控制器方法中的参数获取模型作为输入,因为恕我直言,这比在每个控制器方法中处理 ModelAndView 实例要容易得多。

min*_*ion 4

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

MvcUriComponentsBuilder.fromMethodName(MyController.class, "foo", new Object()).build();
Run Code Online (Sandbox Code Playgroud)

  • 将方法名称作为字符串分散在各处,使得所有内容都非常容易重构,所以我不想这样做。我只是想知道是否有一种简单的方法来获取 java 8 方法引用的字符串表示形式,以便您可以使用类似以下内容的内容: `MvcUriComponentsBuilder.fromMethodName(MyController.class, methodName(MyController::foo), new Object()) .build();`。如果 MvcUriComponentsBuilder 首先支持方法引用就更好了...... (3认同)