我可以在视图层中找到Spring MVC控制器的URL吗?

vyswwuz2  于 2022-10-23  发布在  Spring
关注(0)|答案(7)|浏览(368)

我想我需要的是Django中的反向url解析。假设我有一个AddUserController,它是这样的:

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

我想要的是某种方法来动态地找到指向这个控制器的url,或者形成一个带有从视图(Jsp)到它的参数的url,这样我就不必对到处都是的控制器的URL进行硬编码。这在Spring MVC中是可能的吗?

hkmswyz6

hkmswyz61#

从Spring4开始,您可以使用MvcUriComponentsBuilder
对于类型最安全的方法:

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

注此示例要求该方法返回可代理类型,例如ModelAndView,而不是Stringvoid
从4.2开始,fromMappingName方法被注册为一个名为mvcUrl的JSP函数:

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

此方法没有代理限制。

g52tjvyc

g52tjvyc2#

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

xcitsw88

xcitsw883#

可以用Java反射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.place()
2.方法覆盖>只有一种方法没有问题。如果方法重写需要给出您真正想要的参数类型的支持序列,如Method.get参数类型()
3.单个方法的多个URL>Like@RequestMap(Value={“/”,“Welcome”})。所以简单的规则就是选第一个。
4.Ant Like Style URL>Like This *.do要解决此问题,请使用多个URL,方法是将Ant Like Style放在最后一个示例中。@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>

如果没有方法重写,则参数属性是可选的。
也许我留下来思考一些问题。:)

7rtdyuoh

7rtdyuoh4#

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

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

Taglib代码可能大致类似于
1.向Spring请求带有@控制器注解的已配置Bean
1.以某种合适的顺序迭代,寻找控制器类或Bean名称上的一些合适的匹配
1.如果@RequestMap包含参数,则替换它们
1.返回字符串
这可能适用于您的特定情况(@RequestMapingStyle),但当您有多个Map时,可能会有些麻烦。也许自定义注解会让它更容易。
编辑:
AbstractUrlHandlerMap::getHandlerMap由您最可能使用的DefaultAnnotationHandlerMap继承,将URL的Map返回给处理程序
将注册的处理程序作为不可修改的Map返回,注册路径作为键,处理程序对象(如果是lazy-init处理程序,则为处理程序Bean名称)作为值。
因此,您可以迭代查找合适的匹配,其中“合适的匹配”是您想要的任何内容。

vulvrdjw

vulvrdjw5#

Spring HATEOS library提供了一个API,用于以各种方式生成指向MVC控制器方法的链接。
例如:

URI url = linkTo(methodOn(MyController.class).action(param)).toUri();
qvsjd97n

qvsjd97n6#

您可以访问任何JSP文件中的请求对象,而不必手动将对象连接到或管理到JSP中。所以这意味着你可以从请求对象中获取url路径,让Google变成一个jsp隐式对象。
这里有一个页面可以让你开始http://www.exforsys.com/tutorials/jsp/jsp-implicit-and-session-objects.html

2o7dmzc5

2o7dmzc57#

这样做的问题是,SpringMVC中没有注册和订购所有路由的中央路由器。那么反向路由不是一个静态的过程,并且视图层中的路由解析可能很难集成。
查看this project以获得集中式路由器(如Rails)和视图层中的反向路由。

相关问题