gpt4 book ai didi

java - 扩展 RequestMappingHandlerMapping 以注册备用 URL 模式

转载 作者:行者123 更新时间:2023-11-30 03:06:24 25 4
gpt4 key购买 nike

我们编写的 Web 应用程序需要双语 URL。我们之前使用过“plain Spring/Spring MVC”,但我们已经开始过渡到 Spring boot。

在我们较旧的 Spring 3.x/4.x 应用程序中,我们通过展开大部分“自动配置”来解决此问题,以便覆盖 getMappingPathPatterns 以包含 URL 的翻译版本。例如:

@Override
protected Set<String> getMappingPathPatterns(RequestMappingInfo info) {
Set<String> unilingualPatterns = super.getMappingPathPatterns(info);
Set<String> bilingualPatterns = new HashSet<String>();
for (String pattern : unilingualPatterns) {
bilingualPatterns.add(pattern);
// Create the French and English URLs.
// "resolver" translates the english URL to French.
final String fraURL = resolver.convertUrl(pattern, Locale.CANADA_FRENCH);

if (!pattern.equals(fraURL)) {
bilingualPatterns.add(fraURL);
}
}

return bilingualPatterns;
}

这样, Controller 就有这样的方法:

@RequestMapping(value = "/home")
public String homeView() {
return "home";
}

将自动拥有“/accueil”的第二个映射。本质上,就好像该方法实际上是这样注释的:

@RequestMapping(value = {"/home", "/accueil"})
public String homeView() {
return "home";
}

正如我上面提到的,这需要展开大量的“自动配置”,这使得设置变得更加复杂。

我们开始在新项目中使用 Spring Boot,我们的目标之一是降低配置的复杂性。我希望找到一种更简洁的方法来包含此功能。

我尝试在配置类中创建自己的 RequestMappingHandlerMapping bean,但它没有被使用。事实上,Spring 似乎并不真正希望你重写这个类。

之后,我尝试获取 Spring Boot 创建的 RequestMappingHandlerMapping,迭代 handlerMethods 列表,并为翻译后的 PatternsRequestCondition 添加新的方法,但是我从 RequestMappingHandlerMapping.getHandlerMethods() 返回的 map 是不可修改的,所以这也是一个死胡同。

无论如何,我觉得我走错了路。我发现,当使用 Spring 时,如果我的解决方案变得复杂(就像这个),那么我就做错了,我只需要找到“简单的方法”。

如果有人知道如何手动添加新的 HandlerMethods(基本上是复制现有的,但使用翻译后的 URL 模式),那就太棒了。

提前致谢。

最佳答案

在尝试了多种不同的解决方案后,似乎“最标准”的解决方案是对 URL 使用单个属性文件。这就是我使用 Spring Boot 完成此任务的方法。

首先,我在 scr/main/resources 下创建了一个名为 urls.properties 的新属性文件,其中包含我的应用程序的 url,例如:

url.home=/home
url.start=/start

我在 WebConfig 配置文件中添加了 @PropertySource 注释:

/**
* Web configuration.
*
* Since 1.0.0
*/
@Configuration
@PropertySource("classpath:i18n/urls.properties")
public class WebConfig extends WebMvcConfigurerAdapter {

/**
* Locale resolver.
*
* @return <code>LocaleResolver</code>
*/
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.CANADA);
return localeResolver;
}

/**
* Locale change interceptor.
*
* @return <code>LocaleChangeInterceptor</code>
*/
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}

/** {@inheritDoc} */
@Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(localeChangeInterceptor());
}

}

这使我可以访问 Controller 中的这些属性。

/**
* Demo API controller.
*
* @since 1.0.0
*/
@Controller
@RequestMapping("${url.home}")
public class DemoController {

/**
* Demo GET method binding.
*
* @return <code>String</code>
*/
@RequestMapping(method = RequestMethod.GET)
public String getHome() {
return "home";
}

}

并确保 urls.properties 属性文件在我的 application.properties 文件中列为属性源。

spring.messages.basename=messages,urls

这使我可以访问 Thymeleaf 模板中的这些 URL。例如:

<a th:href="@{#{url.home}}">Home</a>

使用 @PropertySource 注释还可以轻松访问测试用例中的 URL,例如:

/**
* DemoController test class.
*
* @since 1.0.0
*/
public class DemoControllerTest extends AbstractMockMvcTest {

@Value("${url.home}")
private String urlHome;

/**
* Test get username.
*
* @throws Exception Exception
*/
@Test
public void getUsername() throws Exception {
// Request.
resultActions = mockMvc.perform(get(urlHome));
// Verify response.
resultActions.andExpect(status().isOk());
}

}

现在,当需要翻译 url 时,只需发送 urls.properties 文件进行翻译。需要注意的是,这仍然只是一个文件(没有 _en 和 _fr 变体),因此文件最终看起来像:

url.home=/home-accueil
url.start=/start-debut

我希望这对其他人有帮助。找出完成这项工作的最佳方法是一件痛苦的事情。

如果其他人想出更好的方法来做到这一点(不需要过多地修改 Spring),请告诉我!

谢谢。

关于java - 扩展 RequestMappingHandlerMapping 以注册备用 URL 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34663629/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com