Java实现GET请求时如何对URL中包含的特殊字符进行编码处理
Java GET请求URL特殊字符处理方案
首先明确结论:你示例中的[、]属于RFC 3986规范定义的URL非安全保留字符,必须进行编码才能正常发起请求,否则会导致服务端解析参数错误,甚至直接返回400 Bad Request错误。编码时仅需要对参数的键、值分别编码,不要编码&、=这类合法的参数分隔符。
以下是不同场景下的具体实现方式:
1. 原生JDK无第三方依赖实现
使用java.net.URLEncoder指定UTF-8编码格式逐个编码参数键和值即可:
import java.net.URLEncoder; import java.nio.charset.StandardCharsets; public class UrlEncodeTest { public static void main(String[] args) throws Exception { String baseUrl = "https://xyz.tech.environment/v1/payments"; // 仅编码参数的键和值,不要编码&、=等分隔符 String pageKey = URLEncoder.encode("page[last]", StandardCharsets.UTF_8.name()); String filterKey = URLEncoder.encode("filter[reference]", StandardCharsets.UTF_8.name()); String filterValue = URLEncoder.encode("1234", StandardCharsets.UTF_8.name()); // 拼接得到最终编码后的URL,和你给出的示例编码结果完全一致 String fullUrl = String.format("%s?%s&%s=%s", baseUrl, pageKey, filterKey, filterValue); System.out.println(fullUrl); // 输出:https://xyz.tech.environment/v1/payments?page%5Blast%5D&filter%5Breference%5D=1234 } }
注意:禁止直接编码整个查询字符串或者完整URL,否则会把合法的&、=也编码,导致URL完全无法被识别
2. OkHttp客户端实现
如果使用OkHttp作为HTTP客户端,直接用自带的HttpUrl.Builder自动处理编码,无需手动编写编码逻辑,出错概率更低:
import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class OkHttpTest { public static void main(String[] args) throws Exception { OkHttpClient client = new OkHttpClient(); HttpUrl requestUrl = new HttpUrl.Builder() .scheme("https") .host("xyz.tech.environment") .addPathSegment("v1") .addPathSegment("payments") // 直接传原始参数即可,内部自动完成编码 .addQueryParameter("page[last]", "") .addQueryParameter("filter[reference]", "1234") .build(); Request request = new Request.Builder().url(requestUrl).get().build(); try (Response response = client.newCall(request).execute()) { System.out.println(response.body().string()); } } }
3. Spring生态实现(RestTemplate/WebClient)
如果是Spring项目,使用UriComponentsBuilder即可自动完成编码:
import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; public class SpringHttpTest { public static void main(String[] args) { RestTemplate restTemplate = new RestTemplate(); String requestUrl = UriComponentsBuilder .fromHttpUrl("https://xyz.tech.environment/v1/payments") .queryParam("page[last]", "") .queryParam("filter[reference]", "1234") .encode() // 触发参数编码 .toUriString(); String result = restTemplate.getForObject(requestUrl, String.class); System.out.println(result); } }
内容的提问来源于stack exchange,提问作者Shuvarna
相关产品推荐
相关产品推荐

