springboot學習,如何使用RestTemplate調用Restful接口

      現在系統之間的功能模塊,相互調用以及數據的傳遞,如果採用http模式通訊,很少有人用webservice了,大多都是使用Restful接口,因爲方便、簡單嘛。

     先說說怎麼創建Restful接口吧,這個和普通的Controller的寫法感覺差不多,就是對外路徑稍微有所不同。直接看代碼。

package com.springboot.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.springboot.entity.ProductOrder;
import com.springboot.entity.ReqData;

import net.sf.json.JSONObject;


@RestController
public class RestfulController {
	
	
	@RequestMapping(value = "/api/data", method = RequestMethod.POST)
    public ProductOrder postObject(@RequestBody ReqData data) {
        if (data == null) {
        	return null;
        }
		return getone(data.requestType);
    }

	@RequestMapping(value = "/api/map", method = RequestMethod.POST)
    public List<ProductOrder> postMap(@RequestBody Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        return getData();
    }
	
	@RequestMapping(value = "/api/json", method = RequestMethod.POST)
    public ProductOrder postJson(@RequestBody JSONObject jsonRequest) {
        if (jsonRequest == null || jsonRequest.isEmpty()) {
            return null;
        }
        return getone("json");
    }
	
    //
	@GetMapping(value = "/api/product/{id}")
    public ProductOrder findone(@PathVariable("id") String id){
		if (id == null) 
		{
		   id = ".";	
		}
		
		return getone(id);
    }
	
    /**
     * 模擬數據
     * */
    private List<ProductOrder> getData(){
        List<ProductOrder> list=new ArrayList<ProductOrder>();

        ProductOrder m1 = new ProductOrder();
        m1.setId("1");
        m1.setName("admin1");
        m1.setPrice(0.8553f);
        m1.setPDate(new Date());
        list.add(m1);

        ProductOrder m2 = new ProductOrder();
        m2.setId("2");
        m2.setName("admin2");
        m2.setPrice(0.633f);
        m2.setPDate(new Date());
        list.add(m2);

        ProductOrder m3 = new ProductOrder();
        m3.setId("3");
        m3.setName("admin3");
        m3.setPrice(0.344f);
        m3.setPDate(new Date());
        list.add(m3);
        
        return  list;
    }

    private ProductOrder getone(String id){
        ProductOrder m1 = new ProductOrder();
        m1.setId(id);
        m1.setName("admin");
        m1.setPrice(0.8553f);
        m1.setPDate(new Date());
        return m1;
    }
}

      就是前面三個方法,這個好像很簡單,注意每個方法都帶不同的參數,ReqData,map,JSONObject ,對應不同的調用方法,也不多說直接上代碼。這個test類因爲有main方法,直接右鍵 Debug as ---> Java Application就可以運行了。

package com.springboot.service;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.client.RestTemplate;
import com.springboot.entity.Body;
import com.springboot.entity.Pojo;
import com.springboot.entity.ReqData;

import net.sf.json.JSONObject;

public class test {
	
	public static void main(String[] args) {
		 
		testModel();
		
		testMap();
		
		testJson();
	}
	
	private static void testModel()
	{
		String url = "http://localhost:8181/webapp/api/data";
		 
		RestTemplate client = new RestTemplate();
	    
	    ReqData m = new ReqData("01","2020-03-24 22:29:00");
	    
	    String result = client.postForObject(url, m, String.class);
	     
		System.out.println(result);
	}
	
	private static void testMap()
	{
		String url = "http://localhost:8181/webapp/api/map";
		 
		RestTemplate client = new RestTemplate();
	    
		Map<String, Object> hashMap = new HashMap<String, Object>();
        hashMap.put("key1", 999);
        hashMap.put("key2", "admin");
	    
        String result = client.postForObject(url, hashMap, String.class);
        
        System.out.println(result);
	}
	
	private static void testJson()
	{
		String url = "http://localhost:8181/webapp/api/json";
		 
		RestTemplate client = new RestTemplate();
	    
		 JSONObject json = new JSONObject();
	     json.put("key1", 999);
	     json.put("key2", "admin");
	    
        String result = client.postForObject(url, json, String.class);
        
        System.out.println(result);
	}
}

     RestTemplate 這個就是springboot下專門用來調用restful接口,這個看起來好像很簡單,確實也簡單。實體類代碼也簡單。   

package com.springboot.entity;

public class ReqData {
	
	public ReqData(String requestType,String timestamp){
		
		this.requestType = requestType;
		this.timestamp = timestamp;
	}
	
    public String requestType;

    public String timestamp;
    
}

  如果你的代碼不需要JSONObject,json-lib節點可以刪除。  

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

 <dependency>
      <groupId>net.sf.json-lib</groupId>
      <artifactId>json-lib</artifactId>
      <version>2.4</version>
      <classifier>jdk15</classifier>
</dependency>

  需要注意的是,這兩部分代碼理論上是放在兩個工程裏面下,現實場景中對外接口都是提供給別的第三方來調用。

  用 RestTemplate 類調用Restful接口時,默認的情況下,GET方法是不可以傳遞body數據的。需要把 RestTemplate 類擴展一下。

RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());

   HttpGetRequestWithEntity 類

package com.springboot.config;

import java.net.URI;

import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.springframework.http.HttpMethod;

public class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
    public HttpGetRequestWithEntity(final URI uri) {
        super.setURI(uri);
    }

    @Override
    public String getMethod() {
        return HttpMethod.GET.name();
    }
}

HttpComponentsClientRestfulHttpRequestFactory 類

package com.springboot.config;

import java.net.URI;

import org.apache.http.client.methods.HttpUriRequest;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

public  class HttpComponentsClientRestfulHttpRequestFactory extends HttpComponentsClientHttpRequestFactory {
   
	@Override
    protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
        if (httpMethod == HttpMethod.GET) {
            return new HttpGetRequestWithEntity(uri);
        }
        return super.createHttpUriRequest(httpMethod, uri);
    }
}

調用代碼如下

 String url = "http://127.0.0.1:8181/api/data";

RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());
		
		 HttpHeaders headers = new HttpHeaders();
		 headers.add("Content-Type", "application/json");
		 headers.add("dataType", "json");
		 
         ReqData r = new ReqData("01","2020-03-24 22:29:00");
	     
         HttpEntity<ReqData> formEntity = new HttpEntity<ReqData>(r, headers);
          
        ResponseEntity<String> exchange = restTemplate.exchange(url,HttpMethod.GET,formEntity, String.class);
 		 
         String body = exchange.getBody();

		 System.out.println(body);
		

     如果想測試代碼的話,restful接口最好是自己重新寫一個。 使用RestTemplate類還是比較方便,相對 httpclient 已經方便多了,尤其是在springboot下。

     如果是真實業務場景,寫restful接口的時候,個人建議參數類型,不要實體類型,不要map,也不要JSONObject,儘量都用String,傳進去是String,返回的也是String 。當然,這個String往往是可以json組成的,這樣一來,數據類型簡單,而且還能應付複雜的業務場景。

    這樣就是你好,我好,大家好。否則總會有各種各樣麻煩,搞個接口調試的人應該知道。這樣做似乎有點土,是笨辦法,迴避複雜的做法,但是,可以避免被人吐槽你寫的接口,甚至.......

   

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章