Fork me on GitHub

RestTemplate的exchange()方法,解决put和delete请求拿不到返回值的问题

嗷嗷待哺的controller(被调用provider的controller方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//测试get少量参数
@RequestMapping(value = "detailsGetD",method = RequestMethod.GET)
public String test05(Integer id,String name){
    System.out.println("GET-"+id+"-"+name);
    return "error";
}
//测试post
@RequestMapping(value = "detailsPostD",method = RequestMethod.POST)
public String test06(Integer id,String name){
    System.out.println("POST-"+id+"-"+name);
    return "error";
}
//测试put
@RequestMapping(value = "detailsPutD",method = RequestMethod.PUT)
public String test07(Integer id,String name){
    System.out.println("PUT-"+id+"-"+name);
    return "error";
}
//测试delete
@RequestMapping(value = "detailsDeleteD",method = RequestMethod.DELETE)
public String test08(Integer id,String name){
    System.out.println("DELETE-"+id+"-"+name);
    return "error";
}

  consumer的调用传参(url拼接少量参数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//get传递单参
ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsGetD?id={id}&name={name}", HttpMethod.GET, null, String.class,1,"zsw");
//post传递单参
ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsPostD?id={id}&name={name}", HttpMethod.POST, null, String.class,1,"zsw");
//put传递单参
Map<String,Object> map=new HashMap<>();
map.put("id",1);
map.put("name","zsw");
ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsPutD?id={id}&name={name}", HttpMethod.PUT, null, String.class,map);
//delete传递单参
Map<String,Object> map=new HashMap<>();
map.put("id",1);
map.put("name","zsw");
ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsDeleteD?id={id}&name={name}", HttpMethod.DELETE, null, String.class,map);
 
//返回内容
String result = resp.getBody();
System.out.println(result);

  使用map和直接写参数都可以。

 

 再介绍一下传json对象。

  首先登场的是provider方controller。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//测试get
@RequestMapping(value = "detailsGet",method = RequestMethod.GET)
public String test01(@RequestBody Detail detail){
    System.out.println("GET-"+detail);
    return "error";
}
//测试post
@RequestMapping(value = "detailsPost",method = RequestMethod.POST)
public String test02(@RequestBody Detail detail){
    System.out.println("POST-"+detail);
    return "error";
}
//测试put
@RequestMapping(value = "detailsPut",method = RequestMethod.PUT)
public String test03(@RequestBody Detail detail){
    System.out.println("PUT-"+detail);
    return "error";
}
//测试delete
@RequestMapping(value = "detailsDelete",method = RequestMethod.DELETE)
public String test04(@RequestBody Detail detail){
    System.out.println("DELETE-"+detail);
    return "error";
}

  我们再来看consumer的选手,传参json对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
String json = "{\"author\":\"zsw\",\"createdate\":1582010438846,\"id\":1,\"summary\":\"牡丹\",\"title\":\"菏泽\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(json,headers);
ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsPost", HttpMethod.POST, entity, String.class);
HttpStatus statusCode = resp.getStatusCode(); // 获取响应码
int statusCodeValue = resp.getStatusCodeValue(); // 获取响应码值
HttpHeaders headers1 = resp.getHeaders(); // 获取响应头
System.out.println("statusCode:" + statusCode);
System.out.println("statusCodeValue:" + statusCodeValue);
System.out.println("headers:" + headers1);
 
//或者直接传对象,底层自己处理
Detail detail=new Detail();
detail.setId(1L);
detail.setSummary("牡丹");
detail.setTitle("菏泽");
detail.setAuthor("zsw");
detail.setCreatedate(new Timestamp(new Date().getTime()));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Detail> entity = new HttpEntity<>(detail,headers);
ResponseEntity<String> resp = restTemplate.exchange("http://localhost:8080/detailsDelete", HttpMethod.DELETE, entity, String.class);
 
//拿到返回值
String result = resp.getBody();
System.out.println(result);
return result;

  post、put、delete请求都可以用这种方法。但是测试get时就不行了直接报错:org.springframework.web.client.HttpClientErrorException: 400 null(错误请求,服务器不理解请求的语法),get请求不支持这种方式的传参,get请求只能将请求参数拼接URI后边,而不能单独传递request body参数,除非你改用POST。如果用resuful风格,必须要get传参对象,也不是没有办法的。根据(https://blog.belonk.com/c/http_resttemplate_get_with_body.html)这篇文章,小弟把情况摸清楚了,上手!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.zhou.entity.Detail;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Repository;
import org.springframework.web.client.RestTemplate;
 
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
@Repository
public class DetailMapper {
 
    public String test(){
        RestTemplate restTemplate1 = new RestTemplate();
        restTemplate1.setRequestFactory(new HttpComponentsClientHttpRequestWithBodyFactory());
 
        String json = "{\"author\":\"zsw\",\"createdate\":1582010438846,\"id\":1,\"summary\":\"牡丹\",\"title\":\"菏泽\"}";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<>(json,headers);
        ResponseEntity<String> resp = restTemplate1.exchange("http://localhost:8080/detailsGet", HttpMethod.GET, entity, String.class);
 
        String result = resp.getBody();
        System.out.println(result);
        return result;
    }
    private static final class HttpComponentsClientHttpRequestWithBodyFactory extends HttpComponentsClientHttpRequestFactory {
        @Override
        protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
            if (httpMethod == HttpMethod.GET) {
                return new HttpGetRequestWithEntity(uri);
            }
            return super.createHttpUriRequest(httpMethod, uri);
        }
    }
    private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
        public HttpGetRequestWithEntity(final URI uri) {
            super.setURI(uri);
        }
 
        @Override
        public String getMethod() {
            return HttpMethod.GET.name();
        }
    }
}

  大致就是这个样子。对于没接触过httpclient的我,有些类不能导包,属实有的懵。百度百度百度。。。  找到httpclient的maven的依赖,下载导包,成功!启动项目:无法访问org.apache.http.annotation.ThreadSafe,找不到org.apache.http.annotation.ThreadSafe的类文件 ???,我记忆中没有用过这个类,全局搜索一下也找不到(ctrl+shift+f  -  查询自己写的代码)。继续百度,说httpclient4.5.2版本和httpcore4.4.4版本更配哦,maven自动下载的httpcore4.4.13,今天这个maven咋回事(好感-1),参考(https://www.jianshu.com/p/f35eac56c334)文章,最终的pom文件:

  重新启动,访问,拿到参数。

 附上github地址:https://github.com/wwck-zsw/RestTemplate

参考链接:

    https://segmentfault.com/a/1190000021123356

    https://www.cnblogs.com/jnba/p/10522608.html(灵感来源)

 

posted @   威威超酷  阅读(7832)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
点击右上角即可分享
微信分享提示