RestTemplate URL编码问题:请求中=被编码为%3D与浏览器行为不符
解决RestTemplate编码URL中=字符的问题
我之前也碰到过一模一样的情况!浏览器发起请求时会原样保留filter参数里的==,但RestTemplate默认会把这些=转成%3D,导致后端可能解析不出正确的过滤条件。下面给你两个靠谱的解决方案:
方法一:手动构造URI,禁用自动编码
这是最直接的办法,用UriComponentsBuilder构建URL时,通过build(false)跳过自动编码,让filter里的=完全保留原始格式:
// 先定义好原始过滤条件字符串 String filterExpr = "((isVMware==true,moref==dvs-59);isVCEnabled==true)"; // 用UriComponentsBuilder拼接所有请求参数 UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl("http://www.google.com/query") .queryParam("type", "dvSwitch") .queryParam("format", "records") .queryParam("fields", "moref,name,vc,vcName") .queryParam("pageSize", 10) .queryParam("filter", filterExpr) .build(false); // 关键:false表示不对URI组件进行自动编码 // 转成URI对象后发起请求 URI targetUri = uriComponents.toUri(); RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> response = restTemplate.getForEntity(targetUri, String.class);
如果其他参数包含需要编码的特殊字符(比如空格、&),你可以手动对这些参数进行编码后再传入,这样既能保证filter参数的格式,也不影响其他参数的正确性。
方法二:自定义参数编码策略(更灵活)
如果其他参数需要正常自动编码,只有filter里的=不需要,那可以自定义UriTemplateHandler,精准控制特定参数的编码规则:
RestTemplate restTemplate = new RestTemplate(); restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory() { @Override protected void expandInternal(UriComponentsBuilder builder, Map<String, ?> uriVariables) { // 单独处理filter参数,直接原样拼接 if (uriVariables.containsKey("filter")) { String filter = (String) uriVariables.get("filter"); builder.queryParam("filter", filter); // 移除原filter变量,避免被默认逻辑编码 ((Map<String, Object>) uriVariables).remove("filter"); } // 其他参数保持默认编码逻辑 super.expandInternal(builder, uriVariables); } }); // 构造参数Map发起请求 Map<String, Object> params = new HashMap<>(); params.put("type", "dvSwitch"); params.put("format", "records"); params.put("fields", "moref,name,vc,vcName"); params.put("pageSize", 10); params.put("filter", "((isVMware==true,moref==dvs-59);isVCEnabled==true)"); ResponseEntity<String> response = restTemplate.getForEntity( "http://www.google.com/query?type={type}&format={format}&fields={fields}&pageSize={pageSize}", String.class, params );
问题根源说明
浏览器处理URL时,默认不会对查询参数值里的=进行编码;但RestTemplate的默认编码规则会把所有非标准URL字符(包括参数值里的=)转义,导致生成的URL和浏览器发起的格式不一致。上面两种方法都能让RestTemplate生成和浏览器完全一致的请求URL。
内容的提问来源于stack exchange,提问作者Salih Erikci
相关产品推荐
相关产品推荐

