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

使用@RequestParam获取带加号的日期参数时加号丢失,如何解决?

解决@RequestParam中ISO日期参数加号被转为空格的问题

你遇到的核心问题是:在application/x-www-form-urlencoded编码规则里,+会被自动解码为空格,而你的请求URL里的时区部分+0000被Spring解码后变成了空格,导致@DateTimeFormat无法匹配格式,返回400错误。由于不能修改URL格式,我们可以通过以下两种方案解决:

方案一:手动替换时区部分的空格为加号(简单直接)

先以String类型接收参数,然后通过正则表达式精准替换时区前的空格为+,再手动解析为Date:

import org.springframework.format.datetime.DateFormatter;
import java.text.ParseException;
import java.util.Locale;

@GetMapping(value = "/api/{version}/test", produces = "application/json")
public ResponseEntity<MyList> getFreeList(
        @PathVariable String version,
        @RequestParam("date") String dateStr) throws ParseException {
    // 仅替换时区部分的空格为+(匹配毫秒数后的空格与时区数字)
    String correctedDateStr = dateStr.replaceAll("(\\.\\d{3})\\s(\\d{4})$", "$1+$2");
    // 手动解析为Date
    DateFormatter formatter = new DateFormatter("yyyy-MM-dd HH:mm:ss.SSSZ");
    Date date = formatter.parse(correctedDateStr, Locale.getDefault());
    return new ResponseEntity<>(myService.getList(date), HttpStatus.OK);
}

这个方案的好处是只针对你的日期格式做修改,不会影响其他参数的正常解码。

方案二:获取原始查询字符串并自定义解码(更通用)

如果你的日期格式可能有变化,或者需要保留原始参数的所有编码信息,可以直接从HttpServletRequest获取未解码的查询字符串,自己解析并解码(跳过+转空格的规则):

import org.springframework.web.util.UriUtils;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;

@GetMapping(value = "/api/{version}/test", produces = "application/json")
public ResponseEntity<MyList> getFreeList(
        @PathVariable String version,
        HttpServletRequest request) throws ParseException {
    String queryString = request.getQueryString();
    String dateStr = null;
    // 解析查询字符串,提取date参数的原始值
    if (queryString != null) {
        String[] params = queryString.split("&");
        for (String param : params) {
            if (param.startsWith("date=")) {
                dateStr = param.substring(5);
                break;
            }
        }
    }
    // 自定义解码:不将+转为空格
    String decodedDateStr = UriUtils.decode(dateStr, StandardCharsets.UTF_8.name(), false);
    // 解析为Date
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
    Date date = sdf.parse(decodedDateStr);
    return new ResponseEntity<>(myService.getList(date), HttpStatus.OK);
}

这里用到了Spring的UriUtils.decode方法,第三个参数设为false,就会保留原始的+符号,避免被转为空格。

为什么原来的代码会失败?

当Spring处理@RequestParam时,默认会按照application/x-www-form-urlencoded规则解码参数,其中+被视为空格的编码形式,所以你的+0000变成了 0000,导致@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSZ")无法匹配格式,触发400错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:05:36