Java Tapestry 5-将页面类名与URL解耦

Java Tapestry 5-将页面类名与URL解耦,java,webserver,tapestry,Java,Webserver,Tapestry,是否有任何烘焙方式或已建立的Tapestry模式将页面类的名称与呈现它的URL分离 我的具体问题是,我有一个英文代码库中的页面类,但我希望URL使用另一种语言 例如,Hello.java页面应该可以从www.example.com/hola而不是标准的www.example.com/Hello访问,尽管如果这两个URL都能正常工作也没关系 理想情况下,我需要类似注释的东西来为每个单独的页面类配置不同的URL名称 我可以用URL到页面类名的映射和自定义的RequestFilter对每个请求进行映射

是否有任何烘焙方式或已建立的Tapestry模式将页面类的名称与呈现它的URL分离

我的具体问题是,我有一个英文代码库中的页面类,但我希望URL使用另一种语言

例如,
Hello.java
页面应该可以从www.example.com/hola而不是标准的www.example.com/Hello访问,尽管如果这两个URL都能正常工作也没关系

理想情况下,我需要类似注释的东西来为每个单独的页面类配置不同的URL名称

我可以用URL到页面类名的映射和自定义的
RequestFilter
对每个请求进行映射来解决这个问题,但是如果有一个现成的方法或者任何人都能推荐的更好的模式,我不想重新发明轮子

Tapestry有一个默认行为,但我总是发现缺少API,因为您无法访问默认行为。Igor写了一篇关于LinkTransformer API的博客文章

我总是发现有必要装饰ComponentEventLinkEncoder,以便访问默认行为并对其进行调整。有关调整默认行为并对URL执行一些字符串操作的示例,请参见和

Thiago创建了一个url重写器api,但我自己从未使用过。我很确定他的解决方案是基于为出站URL装饰ComponentEventLinkEncoder和为入站URL装饰RequestFilter。

Tynamo's可以帮助您。这取决于您希望如何生成指向www.example.com/hola和www.example.com/hello的链接

@At注释每页只允许一条路由,但您可以通过AppModule提供所有需要的路由,如下所示:

@Primary
@Contribute(RouteProvider.class)
public static void addRoutes(OrderedConfiguration<Route> configuration, ComponentClassResolver componentClassResolver) {
    String pageName = componentClassResolver.resolvePageClassNameToPageName(Home.class.getName());
    String canonicalized = componentClassResolver.canonicalizePageName(pageName);
    configuration.add("home1", new Route("/home1", canonicalized));
    configuration.add("home2", new Route("/home2", canonicalized));
    configuration.add("home3", new Route("/home3", canonicalized));
    configuration.add("home4", new Route("/home4", canonicalized));
    configuration.add("hola", new Route("/hola", canonicalized)); // the last one is going to be use by default to create links to the page
}
@Primary
@贡献(RouteProvider.class)
公共静态void addRoutes(OrderedConfiguration配置,ComponentClassResolver ComponentClassResolver){
字符串pageName=componentClassResolver.resolvePageClassNameToPageName(Home.class.getName());
字符串canonicalized=componentClassResolver.canonicalizePageName(pageName);
添加(“home1”,新路由(“/home1”,规范化));
添加(“home2”,新路由(“/home2”,规范化));
添加(“home3”,新路由(“/home3”,规范化));
添加(“home4”,新路由(“/home4”,规范化));
configuration.add(“hola”,新路由(“/hola”,规范化));//默认情况下,最后一个路由将用于创建指向页面的链接
}
路由是有序的,默认情况下,最后一个路由将用于生成链接。
目前无法避免使用默认路由生成链接

注意,RequestFilter只能解决一半的问题(入站请求)。您仍然需要解决url生成的另一个问题(eventlink/pagelink等)。这就是我想知道的-如果我要为eventlink和pagelink生成外语url,它们会通过入站翻译返回吗?我的做法与Igor的博文中所讨论的正好相反——我没有改变页面名称,也没有试图让它与旧url一起工作,只是为了向后兼容,我试图保持相同的页面名称,但启用(对于内部链接,强制)新url的使用。我认为您需要修饰
组件EventLinkEncoder
以生成url(传出)。您可以选择使用
RequestFilter
或再次在
ComponentEventLinkEncoder
中处理入站URL。这是将我的内部页面链接重写到新URL,但它似乎不会将URL路由回页面-这是它应该如何工作的-只是链接重写的一种方式吗?从源代码看,这似乎是有目的的-它在RouterLinkTransformer.decodePageRenderRequest()中明确不干预请求。不,这不是它应该如何工作的,路由是双向的。RouterLink Transformer不是请求处理管道的一部分,RouterDispatcher.Dispatcher负责将请求路由到正确的页面。如果贡献不起作用,请首先尝试使用单个@At注释,而不使用贡献来了解这应该如何工作。啊,是的,这很有意义-我把它与ComponentEventLinkedEncoder接口混淆了。无论如何,RouterDispatcher永远不会为我调用,因为我的项目中的自定义ComponentClassResolver总是将呈现的页面默认为tapestry的PageRenderDispatcher上的主页,这意味着它总是返回true,并且从不遵从RouterDispatcher,后者被配置为以后运行。无论如何,我想tapestry路由通常是一个很好的解决方案,但将它与我的应用程序集成需要一些努力。谢谢你指点我!