zoukankan      html  css  js  c++  java
  • RestTemplate的exchange()方法,解决put和delete请求拿不到返回值的问题

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

        //测试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拼接少量参数)

            //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。

        //测试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对象。

            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)这篇文章,小弟把情况摸清楚了,上手!

    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文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.12.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.zhou</groupId>
        <artifactId>news-consumer</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>news-consumer</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- 分页 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.2.3</version>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.13</version>
            </dependency>
    
            <!-- Apache Commons IO -->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.2</version>
            </dependency>
            <!-- Apache Commons IO -->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpcore</artifactId>
                <version>4.4.4</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

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

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

    参考链接:

        https://segmentfault.com/a/1190000021123356

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

  • 相关阅读:
    MapReduce实例
    hadoop 分布式安装
    redis缓存
    Flink初始
    Flume初始
    大数据学习之路(持续更新中...)
    使用VisualVM分析性能
    JVM的理解
    Java日记
    UI笔记2
  • 原文地址:https://www.cnblogs.com/wwct/p/12333497.html
Copyright © 2011-2022 走看看