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官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM