spring rest template - downgoon/hello-world GitHub Wiki

RestClient

REST 服务盛行,那么作为客户端如何访问REST服务呢?

最简单的方式用 Apache Http Client 去访问 Web 服务,对返回值用 Jackson 反序列化成 Java 对象。

在 Spring 里面,负责这功能的工具是 RestTemplate, 它的确也是依据上面的原理。

实验-1: 访问 ping.json

访问在线REST服务,比如 http://example.com/ping.json,返回的JSON是:

{attachment=null, debug=20170119135706172357:系统运行正常, message=成功, status=200}

RestTemplate访问:

import java.net.URI;
import java.util.Map;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class RestTemplateExample {

	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {

       RestTemplate rest = new RestTemplate();
       ResponseEntity<Object> response = rest.getForEntity(new URI("http://example.com/ping.json"), Object.class);
       System.out.println(response);
       
       HttpStatus status = response.getStatusCode();
       HttpHeaders headers = response.getHeaders();
       
       
       /* 
        * JSON: 
        * 	{attachment=null, debug=20170119135706172357:系统运行正常, message=成功, status=200}
        * 
        * Object:
        * 	java.util.LinkedHashMap 
        * 
        * */
       Map<String,?> body = (Map<String,?>) response.getBody();
       
       System.out.println("status: " + status);
       System.out.println("headers: " + headers);
       System.out.println("body: " + body);
       System.out.println(body.get("message"));
       
    }
	
}

主要代码:

RestTemplate rest = new RestTemplate(); ResponseEntity response = rest.getForEntity(new URI("http://example.com/ping.json"), Object.class);


pom 中的依赖:

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.3.3.RELEASE</version>
</parent>

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
           <dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
	</dependency>
           <dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-core</artifactId>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
	</dependency>
	 
</dependencies>

其中``RestTemplate``位于:

org.springframework spring-web ```

演示需要的代码位于:

$ git checkout spring-rest-template
$ git checkout spring-rest-template-c1-json

实验-2:反序列化成Java对象

指定Body的类型:

RestTemplate rest = new RestTemplate();
ResponseEntity<RestJson> response = rest.getForEntity(new URI("http://example.com/ping.json"), RestJson.class);

按JSON定义的Java类型:

public class RestJson {

	/*
	 * {attachment=null, debug=20170119135706172357:系统运行正常, message=成功, status=200}
	 * */
	
	private Integer status;
	
	private String message;
	
	private String debug;
	
	private Object attachment;

	public Integer getStatus() {
		return status;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String getDebug() {
		return debug;
	}

	public void setDebug(String debug) {
		this.debug = debug;
	}

	public Object getAttachment() {
		return attachment;
	}

	public void setAttachment(Object attachment) {
		this.attachment = attachment;
	}

	@Override
	public String toString() {
		return "RestJson [status=" + status + ", message=" + message + ", debug=" + debug + ", attachment=" + attachment
				+ "]";
	}
	
	
}

演示代码:

$ git checkout spring-rest-template
$ git checkout spring-rest-template-c2-json2obj

实验-3: 一个marshape rest 客户端

marshape 是一家做 API Gateway 的公司。它有客户端Unirest

进入代码:

$ git checkout spring-rest-template
$ git checkout spring-rest-template-c3-marsharp

pom依赖:

<dependency>
      <groupId>com.mashape.unirest</groupId>
      <artifactId>unirest-java</artifactId>
      <version>1.4.9</version>
</dependency>


  <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
</dependency>
<dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
</dependency>

并且 unirest-java 的HTTP实现都依赖 Apache HttpClient 。

样例代码:

import java.io.IOException;

import org.json.JSONArray;
import org.json.JSONObject;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.ObjectMapper;
import com.mashape.unirest.http.Unirest;

public class MarsharpClientExample {

	public static void main(String[] args) throws Exception {

		String api = "http://example.com/ping.json";
		HttpResponse<JsonNode> response = Unirest.get(api).queryString("r", "123456").asJson();

		int status = response.getStatus();
		System.out.println("http status: " + status);

		JsonNode node = response.getBody();

		if (node.isArray()) {
			JSONArray jsonArray = node.getArray();
			System.out.println(jsonArray);

		} else {
			JSONObject jsonObject = node.getObject();
			String message = (String) jsonObject.get("message");
			System.out.println(message);
		}

		/*
		 * Serialization
		 * */
		Unirest.setObjectMapper(new ObjectMapper() {
			
			private com.fasterxml.jackson.databind.ObjectMapper jacksonObjectMapper
            = new com.fasterxml.jackson.databind.ObjectMapper();
			
			public <T> T readValue(String value, Class<T> valueType) {
		        try {
		            return jacksonObjectMapper.readValue(value, valueType);
		        } catch (IOException e) {
		            throw new RuntimeException(e);
		        }
		    }

		    public String writeValue(Object value) {
		        try {
		            return jacksonObjectMapper.writeValueAsString(value);
		        } catch (JsonProcessingException e) {
		            throw new RuntimeException(e);
		        }
		    }
		    
		});
		
		
		// as object
		HttpResponse<RestJson> resp2 = Unirest.get(api)
				.queryString("r", "123456")
				.asObject(RestJson.class);
		
		System.out.println(resp2.getBody().getMessage());
		

	}

}

参考资料

⚠️ **GitHub.com Fallback** ⚠️