Spring Boot 2.5中RestTemplate发送application/x-www-form-urlencoded请求时因Content-Type含charset报错的问题排查
解决RestTemplate发送application/x-www-form-urlencoded请求的Content-Type报错问题
我之前也碰到过一模一样的情况——目标接口对Content-Type的校验特别严格,只接受纯application/x-www-form-urlencoded,不允许携带;charset=utf-8后缀。下面是几个经过验证的可行方案:
方案1:直接设置Content-Type字符串(最简单)
Spring的MediaType.APPLICATION_FORM_URLENCODED常量默认会附加;charset=utf-8,所以我们可以跳过这个常量,直接手动设置纯字符串形式的Content-Type:
public HttpHeaders getHeaders(){ HttpHeaders headers = new HttpHeaders(); // 直接指定纯Content-Type字符串,避免自动添加charset headers.set("Content-Type", "application/x-www-form-urlencoded"); headers.add("header1", "aaa"); return headers; }
方案2:自定义不带charset的MediaType实例
如果更倾向于使用MediaType对象,可以创建一个不包含字符集的实例:
public HttpHeaders getHeaders(){ HttpHeaders headers = new HttpHeaders(); // 构建不带charset的application/x-www-form-urlencoded类型 MediaType formMediaType = new MediaType("application", "x-www-form-urlencoded"); headers.setContentType(formMediaType); headers.add("header1", "aaa"); return headers; }
方案3:通过请求拦截器统一修改Content-Type
如果需要在多个请求中统一处理这种情况,可以给RestTemplate添加一个拦截器,自动移除Content-Type中的charset后缀:
public void getToken(){ RestTemplate restTemplate = new RestTemplate(); // 添加请求拦截器,修正Content-Type格式 restTemplate.getInterceptors().add((request, body, execution) -> { HttpHeaders headers = request.getHeaders(); MediaType contentType = headers.getContentType(); if (contentType != null && contentType.toString().contains("charset=utf-8")) { // 替换为纯application/x-www-form-urlencoded headers.set("Content-Type", "application/x-www-form-urlencoded"); } return execution.execute(request, body); }); ResponseEntity<TokenResponseDTO> responses = restTemplate .postForEntity(url, new HttpEntity<>(getForm(), getHeaders()), TokenResponseDTO.class); log.info(responses.toString()); }
问题根源
Spring中MediaType.APPLICATION_FORM_URLENCODED的定义是application/x-www-form-urlencoded;charset=UTF-8,当你调用headers.setContentType()时,会把这个完整的字符串设置到请求头里。而有些接口的校验逻辑是精确匹配Content-Type值,不允许有额外的参数,因此就会返回"endpoint only accepts application/x-www-form-urlencoded for POST requests"的错误。
内容的提问来源于stack exchange,提问作者W. Silva
相关产品推荐
相关产品推荐

