View Javadoc
1   package com.foxinmy.weixin4j.http.support.okhttp;
2   
3   import java.io.IOException;
4   import java.net.MalformedURLException;
5   import java.util.List;
6   import java.util.Map.Entry;
7   
8   import okhttp3.MediaType;
9   import okhttp3.OkHttpClient;
10  import okhttp3.RequestBody;
11  import okio.BufferedSink;
12  
13  import com.foxinmy.weixin4j.http.AbstractHttpClient;
14  import com.foxinmy.weixin4j.http.HttpClientException;
15  import com.foxinmy.weixin4j.http.HttpHeaders;
16  import com.foxinmy.weixin4j.http.HttpRequest;
17  import com.foxinmy.weixin4j.http.HttpResponse;
18  import com.foxinmy.weixin4j.http.entity.HttpEntity;
19  import com.foxinmy.weixin4j.util.StringUtil;
20  
21  /**
22   * OkHttp3
23   * 
24   * @className OkHttpClient3
25   * @author jinyu(foxinmy@gmail.com)
26   * @date 2016年7月25日
27   * @since JDK 1.6
28   */
29  public class OkHttpClient3 extends AbstractHttpClient {
30  
31  	private final OkHttpClient okClient;
32  
33  	public OkHttpClient3(OkHttpClient okClient) {
34  		this.okClient = okClient;
35  	}
36  
37  	@Override
38  	public HttpResponse execute(HttpRequest request) throws HttpClientException {
39  		HttpResponse response = null;
40  		try {
41  			okhttp3.Request okRequest = createRequest(request);
42  			okhttp3.Response okResponse = okClient.newCall(okRequest).execute();
43  			response = new OkHttpResponse3(okResponse, okResponse.body()
44  					.bytes());
45  			handleResponse(response);
46  		} catch (IOException e) {
47  			throw new HttpClientException("I/O error on "
48  					+ request.getMethod().name() + " request for \""
49  					+ request.getURI().toString(), e);
50  		} finally {
51  			if (response != null) {
52  				response.close();
53  			}
54  		}
55  		return response;
56  	}
57  
58  	/**
59  	 * create OkRequest
60  	 */
61  	protected okhttp3.Request createRequest(HttpRequest request)
62  			throws HttpClientException {
63  		okhttp3.Request.Builder requestBuilder = createBuilder(request);
64  		resolveHeaders(requestBuilder, request);
65  		resolveContent(requestBuilder, request);
66  		return requestBuilder.build();
67  	}
68  
69  	/**
70  	 * create Request.Builder
71  	 * 
72  	 * @throws HttpClientException
73  	 */
74  	protected okhttp3.Request.Builder createBuilder(HttpRequest request)
75  			throws HttpClientException {
76  		okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder();
77  		try {
78  			requestBuilder.url(request.getURI().toURL());
79  		} catch (MalformedURLException e) {
80  			throw new HttpClientException("format URI error", e);
81  		}
82  		return requestBuilder;
83  	}
84  
85  	/**
86  	 * resolve Request.Headers
87  	 * */
88  	protected void resolveHeaders(okhttp3.Request.Builder builder,
89  			HttpRequest request) {
90  		com.foxinmy.weixin4j.http.HttpHeaders headers = request.getHeaders();
91  		if (headers == null) {
92  			headers = new HttpHeaders();
93  		}
94  		// Add default accept headers
95  		if (!headers.containsKey(HttpHeaders.ACCEPT)) {
96  			headers.set(HttpHeaders.ACCEPT, "*/*");
97  		}
98  		// Add default user agent
99  		if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
100 			headers.set(HttpHeaders.USER_AGENT, "square/okhttp3");
101 		}
102 		for (Entry<String, List<String>> header : headers.entrySet()) {
103 			if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
104 				builder.header(header.getKey(),
105 						StringUtil.join(header.getValue(), ';'));
106 			} else {
107 				for (String headerValue : header.getValue()) {
108 					builder.header(header.getKey(),
109 							headerValue != null ? headerValue : "");
110 				}
111 			}
112 		}
113 	}
114 
115 	/**
116 	 * resolve Request.Content
117 	 */
118 	protected void resolveContent(okhttp3.Request.Builder builder,
119 			HttpRequest request) throws HttpClientException {
120 		final HttpEntity entity = request.getEntity();
121 		okhttp3.RequestBody body = null;
122 		if (entity != null) {
123 			body = new RequestBody() {
124 
125 				@Override
126 				public long contentLength() throws IOException {
127 					return entity.getContentLength();
128 				}
129 
130 				@Override
131 				public void writeTo(BufferedSink sink) throws IOException {
132 					entity.writeTo(sink.outputStream());
133 				}
134 
135 				@Override
136 				public MediaType contentType() {
137 					return MediaType.parse(entity.getContentType().toString());
138 				}
139 			};
140 		}
141 		builder.method(request.getMethod().name(), body);
142 	}
143 }