我可以在视图层找到spring mvc控制器的URL吗?

问题描述 投票:0回答:6

我认为我需要的是 Django 中的反向 url 解析。假设我有一个像这样的 AddUserController:

@Controller
@RequestMapping("/create-user")
public class AddUserController{ ... }

我想要的是某种方法来动态查找此控制器的 url 或从视图 (JSP) 形成带有参数的 url,这样我就不必在各处对控制器的 url 进行硬编码。这在 Spring MVC 中可能吗?

java spring jsp spring-mvc
6个回答
5
投票

从 Spring 4 开始,您可以使用

MvcUriComponentsBuilder

对于最类型安全的方法:

String url = fromMethodCall(on(MyController.class).action("param")).toUriString();

注意此示例要求该方法返回可代理类型 - 例如

ModelAndView
ResponseEntity
,不是
String
也不是
void


从 4.2 开始,

fromMappingName
方法被注册为名为
mvcUrl
:

的 JSP 函数
<a href="${spring:mvcUrl('MyController#action').arg('param').build()}">Login</a>

此方法没有代理限制。


2
投票

您是否考虑过使用一个 bean 将您需要的所有控制器 URL 聚合到 HashMap 中,然后将此控制器/URL Map 添加到任何需要它的模型中?每个 Spring 控制器都能够调用 init() 方法,您可以让每个控制器将其名称和 URL 添加到 init() 方法中的控制器/URL 映射中,以便在控制器上线时可以使用。


2
投票

可以用Java Reflection API解决。通过创建自定义标签库。方法看起来像这样

Class c = Class.forName("Your Controller");

            for(Method m :c.getMethods()){
                if(m.getName()=="Your Method"){
                    Annotation cc = m.getAnnotation(RequestMapping.class);
                    RequestMapping rm = (RequestMapping)cc;
                    for(String s:rm.value()){
                        System.out.println(s);
                    }
                }
            }

您可能面临的问题是

1.路径变量 > 像这样 /pet/show/{id} 所以应该支持路径名和值的设置,然后在返回 url 之前替换此 String.replace()

2.方法重写 > 只有一种方法没有问题。如果方法重写需要提供您真正想要的参数类型的支持序列,例如 Method.getParametersType()

3.多网址转单一方法>如@RequestMapping(value={"/", "welcome"})。所以简单的规则就是选择第一个。

4.Ant Like Style Url > 像这样

*.do
解决这个问题是通过在最后一个例子中放置ant like style来使用多个url。
@RequestMapping(value={"/pet","/pet/*.do"})


所以可能的链接标签样式是

<my:link controller="com.sample.web.PetController" method="show" params="java.lang.Integer">
<my:path name="id" value="1" />
</my:link>

如果没有方法重写,则 parmas 属性是可选的。


也许我要思考一些问题。 :)


1
投票

我可能会尝试构建一个标签库来检查您正在使用的注释,以便找到合适的匹配:

<x:url controller="myController">
    <x:param name="action" value="myAction"/>
</x:url>

Taglib 代码可能大致类似于

  1. 向 Spring 询问带有 @Controller 注释的配置 bean
  2. 以某种合适的顺序进行迭代,在控制器类或 bean 名称上寻找合适的匹配项
  3. 如果@RequestMapping包含参数,则替换它们
  4. 返回字符串

这可能适用于您的特定情况(@RequestMapping 样式),但当您有多个映射时,它可能会变得有点麻烦。也许自定义注释会让事情变得更容易。

编辑:

AbstractUrlHandlerMapping::getHandlerMap,由您最有可能使用的 DefaultAnnotationHandlerMapping 继承,返回一个 URL 映射到 Handler

将注册的处理程序作为 不可修改的地图,已注册 路径作为键和处理程序对象(或 处理程序 bean 名称(如果是) 惰性初始化处理程序)作为值。

因此,您可以迭代寻找合适的匹配,其中“合适的匹配”就是您想要的任何内容。


0
投票

您可以访问任何 JSP 文件中的请求对象,而无需手动连接或管理 JSP 中的对象。这意味着您可以从请求对象中获取 url 路径,通过 google 搜索 JSP 隐式对象。

这是一个帮助您入门的页面 http://www.exforsys.com/tutorials/jsp/jsp-implicit-and-session-objects.html


0
投票

这样做的问题是 SpringMVC 中没有中央路由器来注册和排序所有路由。那么反向路由不是一个静态过程,视图层中的路由解析可能很难集成。

查看这个项目,了解集中式路由器(如 Rails)和视图层中的反向路由。

© www.soinside.com 2019 - 2024. All rights reserved.