You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring HATEOAS升级后链接查询参数自动编码问题求助

Spring HATEOAS 1.3.7 → 2.2.0 升级后URL查询参数自动编码的解决方案

问题背景

将Spring HATEOAS从1.3.7升级到2.2.0后,生成的HAL链接中查询参数会被自动编码(比如时间戳中的冒号:被转为%3A),而旧版本不会对这类字符编码。示例对比:

1.3.7版本生成的链接

"_links": {
    "before": {
        "href": "https://localhost:8080/api/time?before=2024-03-01T06:08:07Z&itemsPerPage=10"
    }
}

2.2.0版本生成的链接

"_links": {
    "before": {
        "href": "http://localhost:8080/api/time?before=2024-03-01T06%3A08%3A07Z&itemsPerPage=10"
    }
}

链接生成代码:

result
  .add(
    linkTo(
      methodOn(TimeController.class).before(instant, itemsPerPage)
    )
  .withRel("before"));

这一变化源于2.x版本开始严格遵循RFC 3986规范对URL参数进行编码,编码逻辑位于org.springframework.hateoas.server.core.WebHandler的TemplateVariable.prepareAndEncode(Object value)方法中。

解决方案

1. 全局自定义编码逻辑

通过实现TemplateVariable.VariableFormatter接口,自定义参数编码规则,并注册为Spring Bean,全局覆盖默认编码行为:

自定义格式化器

import org.springframework.hateoas.server.core.TemplateVariable;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriUtils;
import java.nio.charset.StandardCharsets;

@Component
public class CustomVariableFormatter implements TemplateVariable.VariableFormatter {

    @Override
    public String format(Object value) {
        if (value == null) {
            return null;
        }
        String stringValue = value.toString();
        // 示例:保留冒号,仅编码RFC强制要求的特殊字符
        return UriUtils.encode(stringValue, StandardCharsets.UTF_8.name())
                .replace("%3A", ":")
                .replace("%3a", ":");
    }
}

注册到HATEOAS配置

import org.springframework.hateoas.config.HateoasConfiguration;
import org.springframework.hateoas.server.core.TemplateVariable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomHateoasConfig extends HateoasConfiguration {

    @Bean
    public TemplateVariable.VariableFormatter customVariableFormatter() {
        return new CustomVariableFormatter();
    }
}

2. 手动构建链接绕过自动编码

如果不需要全局配置,可直接使用UriComponentsBuilder手动控制编码开关:

import org.springframework.hateoas.Link;
import org.springframework.web.util.UriComponentsBuilder;

// 手动构建URL,禁用自动编码
String href = UriComponentsBuilder.fromHttpUrl("https://localhost:8080/api/time")
        .queryParam("before", instant.toString())
        .queryParam("itemsPerPage", itemsPerPage)
        .encode(false) // 关闭自动编码
        .toUriString();

// 添加到结果中
result.add(Link.of(href).withRel("before"));

注意:encode(false)会完全禁用编码,若参数包含空格、&等必须编码的字符,需手动处理以保证URL合法性。

3. 客户端适配标准编码

从合规性角度,建议客户端适配编码后的URL。Spring HATEOAS 2.x的严格编码是符合RFC规范的正确行为,旧版本的非编码行为存在潜在风险。若客户端已自行编码,需修改逻辑避免双重编码。

内容的提问来源于stack exchange,提问作者tuda224

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:07:28