java - 如何在非servlet环境中使用UriComponentsBuilder?

标签 java spring spring-mvc

文档指出,如果我不在 servlet 调用线程内,但仍想使用 UriComponentsBuilder (例如在批量导入中),我可以使用 ServletUriComponentsBuilder.fromCurrentContextPath ().

@参见https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-uri-building

我从文档中尝试了以下操作:

public String createUrl() {
    UriComponentsBuilder base = ServletUriComponentsBuilder.fromCurrentContextPath().path("/en");
    MvcUriComponentsBuilder builder = MvcUriComponentsBuilder.relativeTo(base);
    builder.withMethodCall(on(BookingController.class).getBooking(21)).buildAndExpand(42);

    URI uri = uriComponents.encode().toUri();
    return uri.toString();
}

用于测试非 servlet 调用:

@PostConstruct
public void init() {
    builder.createUrl();
}

但总是遇到异常:

Caused by: java.lang.IllegalStateException: Could not find current request via RequestContextHolder
    at org.springframework.util.Assert.state(Assert.java:392) ~[spring-core-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.web.servlet.support.ServletUriComponentsBuilder.getCurrentRequest(ServletUriComponentsBuilder.java:190) ~[spring-webmvc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.web.servlet.support.ServletUriComponentsBuilder.fromCurrentContextPath(ServletUriComponentsBuilder.java:158) ~[spring-webmvc-4.3.4.RELEASE.jar:4.3.4.RELEASE]

那么这里可能出了什么问题?

最佳答案

您提到的文档明确指出静态方法用于 Servlet 环境:

In a Servlet environment the ServletUriComponentsBuilder sub-class provides static factory methods [...]

因此,如果您不在上述 Servlet 环境中,则需要使用普通的 UriComponentsBuilder:

UriComponentsBuilder.newInstance().scheme("http").host("example.com")

这适合您的代码

public String createUrl() {
    UriComponentsBuilder base = UriComponentsBuilder.newInstance().scheme("http").host("example.com").path("/en");
    MvcUriComponentsBuilder builder = MvcUriComponentsBuilder.relativeTo(base);
    builder.withMethodCall(on(BookingController.class).getBooking(21)).buildAndExpand(42);

    URI uri = uriComponents.encode().toUri();
    return uri.toString();
}

这背后的原因是,在 servlet 环境中,您可以通过查询 Servlet/ServletContext 等来访问方案、主机和上下文路径。在 Web 应用程序外部运行,此信息(方案、主机、上下文路径)需要来自其他地方。

关于java - 如何在非servlet环境中使用UriComponentsBuilder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40527179/

相关文章:

java - Spring Security - 无效的列索引异常

java - 使用 @EnableWebSecurity 时,至少有一个非空 i..... 作为 @Bean。提示尝试扩展 WebSecurityConfigurerAdapter

java - Obsidian Scheduler 为实现作业设置问题

java - 无法从 Raspberry Pi 获得 REST 响应

java - spring 3 启动的奇怪信息

java - Spring Mobile - 未应用拦截器?设备为空

java - 鼠标离开 JTable 时发生鼠标事件?

java - Android BLE onCharacteristicChanged 未触发

java - 从 Hibernate 和 Spring 连接到多个数据库

java - EntityManagerFactory 已关闭 - 仅在特定机器上