Rest Template 常见错误

1.参数类型是 MultiValueMap


@RestController
public class HelloWorldController {
    @RequestMapping(path = "hi", method = RequestMethod.POST)
    public String hi(@RequestParam("para1") String para1, @RequestParam("para2") String para2){
        return "helloworld:" + para1 + "," + para2;
    };
}



RestTemplate template = new RestTemplate();
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("para1", "001");
paramMap.put("para2", "002");

String url = "http://localhost:8080/hi";
String result = template.postForObject(url, paramMap, String.class);
System.out.println(result);

测试后你会发现事与愿违,返回提示 400 错误

  • 实际上,只有当我们发送的 Body 是 MultiValueMap 才能使用表单来提交
  • 定义的就是普通的 HashMap,最终是按请求 Body 的方式发送出去的。(json)

//错误:
//Map<String, Object> paramMap = new HashMap<String, Object>();
//paramMap.put("para1", "001");
//paramMap.put("para2", "002");

//修正代码:
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
paramMap.add("para1", "001");
paramMap.add("para2", "002");

2.当 URL 中含有特殊字符


String url = "http://localhost:8080/hi?para1=1#2";
HttpEntity<?> entity = new HttpEntity<>(null);

RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET,entity,String.class);

System.out.println(response.getBody());

服务器并不认为 #2 是 para1 的内容;para1 丢掉的 #2 实际是以 Fragment 的方式被记录下来了
URL 的格式定义:

protocol://hostname[:port]/path/[?query]#fragment

  • Query(查询参数):页面加载请求数据时需要的参数,用 & 符号隔开,每个参数的名和值用 = 符号隔开
  • Fragment(锚点):#开始,字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用 Fragment 直接定位到某一名词的解释。例如定位网页滚动的位置,可以参考下面一些使用示例:https://github.com/alu4r/flink-demo/blob/master/pom.xml#L10
    修正:

String url = "http://localhost:8080/hi?para1=1#2";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
URI uri = builder.build().encode().toUri();
HttpEntity<?> entity = new HttpEntity<>(null);

RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET,entity,String.class);

System.out.println(response.getBody());

3.小心多次 URL Encoder


@RestController
public class HelloWorldController {
    @RequestMapping(path = "hi", method = RequestMethod.GET)
    public String hi(@RequestParam("para1") String para1){
        return "helloworld:" + para1;
    };
}

RestTemplate restTemplate = new RestTemplate();

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/hi");
builder.queryParam("para1", "开发测试 001");
String url = builder.toUriString();

ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
System.out.println(forEntity.getBody());

// 响应
helloworld:%E5%BC%80%E5%8F%91%E6%B5%8B%E8%AF%95001

以上代码:builder.toUriString();restTemplate.getForEntity都进行了一次编码
修正:

RestTemplate restTemplate = new RestTemplate();
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/hi");
builder.queryParam("para1", "开发测试 001");
URI url = builder.encode().build().toUri();
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
System.out.println(forEntity.getBody());
RestTemplate是一个由Spring框架提供的用于调用REST服务的类。它简化了与HTTP服务的通信方式,统一了RESTful的标准,并封装了HTTP连接。使用RestTemplate,我们只需要传入URL和返回值类型即可实现对REST服务的调用。相比于之前常用的HttpClient,RestTemplate提供了更为优雅的方式来调用RESTful服务。 RestTemplate提供了多个方法来执行不同的HTTP请求,包括HEAD、GET、POST、PUT和DELETE等。其中,delete()方法用于发送DELETE请求。然而,需要注意的是,RestTemplate的delete()方法不支持上传RequestBody,只能指定URL中的参数。所以,如果需要上传RequestBody,就需要使用其他方法或自定义配置。 在使用RestTemplate时,我们可以使用默认的配置,它依赖于JDK提供的HttpURLConnection来进行HTTP连接。如果需要,也可以通过setRequestFactory方法来替换为其他的HTTP库,例如Apache HttpComponent、Netty或OKHttp。RestTemplate也提供了许多其他方法来满足不同的需求,例如headForHeaders()、getForObject()、putForObject()等。 综上所述,RestTemplate是一个非常方便的工具,用于在Spring应用程序中访问第三方REST服务。无论是使用默认配置还是进行自定义配置,都能够满足日常使用中对RESTful API的调用需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [RestTemplate](https://blog.csdn.net/D1842501760/article/details/124216538)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值