• RestTemplate较为通用的使用方法


    RestTemplate较为通用的使用方法

    一丶http请求响应

      1. http请求主要包括3个部分, 请求行(get,post等请求方法   url地址   http协议版本),     请求头( key value形式),   请求体(任意文本, 通常与请求头content-type对应).

      

      2. http响应主要包括3个部分, 响应消息行(协议/版本  响应状态码  对响应状态码的描述),  响应消息头(key value形式),  响应消息正文(任意文本, 通常与响应消息头content-type对应)

      

     

      更详细的请看此博文

     二丶restTemplate使用简述

      处理http请求, 主要是构造生成http请求报文, 处理转换http响应报文.

      在实际项目中, 主要是使用get, post两种请求.

      1) get请求, 主要是在请求行中的url带上请求参数, 如http://localhost:8080/server/userId?userId=2 中的userId=2,  url路径中的部分数据也可以作为请求参数, 如http://localhost:8080/server/userId/2中的2, 可以和前一个url等同

      restTemplate主要是通过占位符{}来构造url,

      #getForObject(url, responseType, uriVariables), #getForEntity(url, responseType, uriVariables) 等方法用于get请求,

      其中responseType指定了反序列化响应体后的类型,     url, uriVariables 用于构造请求url,        getForEntity可以得到响应码等状态信息

       点此查看官方文档

      2) post请求, 主要是在请求体中带上自定义的数据, 通常为json,  在使用时, 通常需要在请求头指定请求体的内容类型, json内容类型为 "Content-Type: application/json"

      请求头:对应于org.springframework.http.HttpHeaders

      请求体:对应于org.springframework.http.HttpEntity#body属性

      请求头和请求体 对应于org.springframework.http.HttpEntity

      

      #postForObject(String url,  Object request, Class<T> responseType,Object... uriVariables)

      #postForEntity(String url, Object request,Class<T> responseType, Object... uriVariables) 等用于Post方法

      3) resttemplate较为自由的执行方法

      #exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables)

       可以自定义httpmethod, url,请求头,q请求体,响应类型

      4) 简单总结

      使用restTemaplate主要围绕http报文来使用, 基本熟悉了http报文的结构, 以及resttemaplate的实现思想, 就可以很好的使用resttemplate了

    三丶较为通用的使用样例

       

    @Component
    @Slf4j
    public class RestTemplateManager {
        @Autowired
        private RestTemplateConfig config;
        private RestTemplate restTemplate;
    
    
        private String SERVER_PREFIX;
    
        @PostConstruct
        public void init(){
            restTemplate=new RestTemplate();
            //使用fastjson转换json
            restTemplate.getMessageConverters().add(0, new FastJsonHttpMessageConverter());
            //打印调试日志
            restTemplate.setInterceptors(Arrays.asList(new LoggingRequestInterceptor()));
    
            SERVER_PREFIX=config.getUrl();
        }
    
        /**
         * get请求
         * @param requestDto
         */
        public GetExampleDataDto getExample(GetExampleRequestDto requestDto){
            String url=SERVER_PREFIX+"/get-example?userId={userId}&age={age}";
            try{
                //请求参数
                Map vars=(JSONObject)JSON.toJSON(requestDto);
                ResponseEntity<String>  entity=restTemplate.getForEntity(url, String.class, vars);
                Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
                GetExampleDataDto dataDto=getData(entity.getBody(), GetExampleDataDto.class);
                return dataDto;
            }catch (Exception e){
                String message="请求url: "+url+"出错";
                log.error(message, e);
                log.error("请求参数: {}", JSON.toJSON(requestDto));
                throw new RuntimeException(message, e);
            }
    
        }
    
    
        /**
         * get请求, 带上请求头
         * @param requestDto
         * @param token 登录token
         */
        public GetExampleDataDto getExampleWithHeader(GetExampleRequestDto requestDto, String token){
            String url=SERVER_PREFIX+"/get-example?userId={userId}&age={age}";
            try{
                //请求参数
                Map vars=(JSONObject)JSON.toJSON(requestDto);
                //一般在请求头的cookie带上登录token
                HttpCookie tokenCookie=new HttpCookie("token", token);
                HttpHeaders headers=new HttpHeaders();
                headers.add(HttpHeaders.COOKIE, tokenCookie.toString());
                HttpEntity requestEntity=new HttpEntity(headers);
    
                ResponseEntity<String>  entity=restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class, vars);
                Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
                GetExampleDataDto dataDto=getData(entity.getBody(), GetExampleDataDto.class);
                return dataDto;
            }catch (Exception e){
                String message="请求url: "+url+"出错";
                log.error(message, e);
                log.error("请求参数: {}", JSON.toJSON(requestDto));
                throw new RuntimeException(message, e);
            }
    
        }
    
    
    
    
        /**
         * post请求
         * @param requestDto
         */
        public PostExampleDataDto postExample(PostExampleRequestDto requestDto){
            String url=SERVER_PREFIX+"/post-example";
            try{
                //请求参数
                HttpEntity httpEntity=new HttpEntity(requestDto, createJsonHeader());
                ResponseEntity<String>  entity=restTemplate.postForEntity(url, httpEntity, String.class);
                Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
                PostExampleDataDto dataDto=getData(entity.getBody(), PostExampleDataDto.class);
                return dataDto;
            }catch (Exception e){
                String message="请求url: "+url+"出错";
                log.error(message, e);
                log.error("请求参数: {}", JSON.toJSON(requestDto));
                throw new RuntimeException(message, e);
            }
    
        }
    
        private HttpHeaders createJsonHeader(){
            HttpHeaders headers=new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            return headers;
        }
    
        private <T> T getData(String responseString, Class<T> clazz){
            StringDataResponseDto responseDto=JSONObject.parseObject(responseString)
                    .toJavaObject(StringDataResponseDto.class);
            if(responseDto.getCode()!=0){
                throw new RuntimeException("code不等于0, 值为["+responseDto.getCode()+"]," +
                        " message=["+responseDto.getMessage()+"]");
            }
            String stringData=responseDto.getData();
            return JSONObject.parseObject(stringData).toJavaObject(clazz);
        }
    
    
        @Data
        private static class StringDataResponseDto extends ResponseDto<String> {
    
        }
    
    }

    四丶单元测试

      主要是使用mockserver来模拟请求服务器 ^_^ 非常好的工具

            <dependency>
                <groupId>org.mock-server</groupId>
                <artifactId>mockserver-netty</artifactId>
                <version>5.8.1</version>
                <scope>test</scope>
            </dependency>
    /**
     * https://github.com/mock-server/mockserver/tree/master/mockserver-examples
     *
     * https://github.com/mock-server/mockserver/blob/master/mockserver-examples/src/main/java/org/mockserver/examples/mockserver/MockServerClientExamples.java
     *
     * @author TimFruit
     * @date 19-12-30 下午7:54
     */
    @SpringBootTest
    @RunWith(SpringJUnit4ClassRunner.class)
    @ActiveProfiles("unittest")
    public class ResttemplateManagerTests {
    
        private int port=8055;
        @Rule
        public MockServerRule mockServerRule = new MockServerRule(this, port);
        private MockServerClient client=new MockServerClient("localhost", port);
        private String prefixurl="/mockserver";
    
    
        @Autowired
        RestTemplateManager templateManager;
    
        /*
        public void createExpectationMockServerClient() {
            new MockServerClient("localhost", 1080)
                .when(
                    request()
                        .withMethod("GET")
                        .withPath("/view/cart")
                        .withCookies(
                            cookie("session", "4930456C-C718-476F-971F-CB8E047AB349")
                        )
                        .withQueryStringParameters(
                            param("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092")
                        )
                )
                .respond(
                    response()
                        .withBody("some_response_body")
                );
        }
         */
    
    
        @Test
        public void shouldGet() throws IOException {
            //given
            String expectedResponseBody=FileUtils.readContent("httpmanager/get-example-response.json");
            client.when(
                    request().withMethod("GET").withPath(prefixurl+"/get-example")
                    .withQueryStringParameters(
                            param("userId", "1"), param("age", "1")
                    )
            ).respond(
                    response().withContentType(MediaType.APPLICATION_JSON)
                            //mock 结果来验证
                            .withBody(expectedResponseBody)
            );
    
    
            //when
            GetExampleRequestDto requestDto=new GetExampleRequestDto();
            requestDto.setUserId(1);
            requestDto.setAge(1);
    
            GetExampleDataDto dataDto=templateManager.getExample(requestDto);
    
    
            //then
            Assert.assertEquals(5, dataDto.getUserId().intValue());
            Assert.assertEquals(99, dataDto.getAge().intValue());
    
    
        }
    
    
        @Test
        public void shouldGetWithHeader() throws IOException {
            //given
            String token="timfruit2019";
            String expectedResponseBody=FileUtils.readContent("httpmanager/get-example-response.json");
            client.when(
                    request().withMethod("GET").withPath(prefixurl+"/get-example")
                            .withQueryStringParameters(
                                    param("userId", "1"), param("age", "1")
                            )
                            //header-cookie
                            .withCookie("token", token)
            ).respond(
                    response().withContentType(MediaType.APPLICATION_JSON)
                            //mock 结果来验证
                            .withBody(expectedResponseBody)
            );
    
    
            //when
            GetExampleRequestDto requestDto=new GetExampleRequestDto();
            requestDto.setUserId(1);
            requestDto.setAge(1);
    
            GetExampleDataDto dataDto=templateManager.getExampleWithHeader(requestDto, token);
    
    
            //then
            Assert.assertEquals(5, dataDto.getUserId().intValue());
            Assert.assertEquals(99, dataDto.getAge().intValue());
    
    
        }
    
    
        @Test
        public void shouldPost(){
            //given
            String expectedRequestBody=FileUtils.readContent("httpmanager/post-example-request.json");
            String expectedResponseBody=FileUtils.readContent("httpmanager/post-example-response.json");
            client.when(
                    request().withMethod("POST").withPath(prefixurl+"/post-example")
                            .withContentType(MediaType.APPLICATION_JSON)
                            .withBody(new JsonBody(expectedRequestBody))
            ).respond(
                    response().withContentType(MediaType.APPLICATION_JSON)
                            //mock 结果来验证
                            .withBody(expectedResponseBody)
            );
    
    
            //when
            PostExampleRequestDto requestDto=new PostExampleRequestDto();
            requestDto.setUserId(5);
            requestDto.setBookIds(Arrays.asList(1, 2 , 3, 4));
    
            PostExampleDataDto dataDto=templateManager.postExample(requestDto);
    
    
            //then
            Assert.assertEquals(5, dataDto.getUserId().intValue());
            Assert.assertEquals(4, dataDto.getBookIdCount().intValue());
        }
    }

      点击查看完整源码

    学习资料:

      MockServer 简单示例

      mockserver官方文档

      restTemplate官方文档

    人生没有彩排,每一天都是现场直播
  • 相关阅读:
    【建兰普及模拟赛第一场】20181023
    【Uva11400 Lighting System Design】动态规划
    【洛谷 P2388 阶乘之乘】模拟
    【Uva1025 A Spy in the Metro】动态规划
    【洛谷P2028 龙兄摘苹果】动态规划
    【洛谷P1507 NASA的食物计划】动态规划
    【洛谷P1795 无穷的序列_NOI导刊2010提高(05)】模拟
    【洛谷P1281 书的复制】二分+动态规划
    【洛谷P4933 大师】动态规划
    「GXOI / GZOI2019」旧词
  • 原文地址:https://www.cnblogs.com/timfruit/p/12124315.html
Copyright © 2020-2023  润新知