33import com .qiniu .common .QiniuException ;
44import com .qiniu .http .Client ;
55import com .qiniu .http .MethodType ;
6+ import com .qiniu .http .RequestStreamBody ;
67import com .qiniu .util .StringMap ;
78import com .qiniu .util .StringUtils ;
9+ import okhttp3 .MediaType ;
10+ import okhttp3 .RequestBody ;
11+ import okio .BufferedSink ;
812
13+ import java .io .InputStream ;
914import java .net .URL ;
1015import java .net .URLEncoder ;
1116import java .util .*;
@@ -35,14 +40,11 @@ protected com.qiniu.http.Response requestByClient(Request request) throws QiniuE
3540 if (request .method == MethodType .GET ) {
3641 return client .get (request .getUrl ().toString (), request .getHeader ());
3742 } else if (request .method == MethodType .POST ) {
38- return client .post (request .getUrl ().toString (), request .body , request .bodyOffset , request .bodySize ,
39- request .getHeader (), request .bodyContentType );
43+ return client .post (request .getUrl ().toString (), request .getRequestBody (), request .getHeader ());
4044 } else if (request .method == MethodType .PUT ) {
41- return client .put (request .getUrl ().toString (), request .body , request .bodyOffset , request .bodySize ,
42- request .getHeader (), request .bodyContentType );
45+ return client .put (request .getUrl ().toString (), request .getRequestBody (), request .getHeader ());
4346 } else if (request .method == MethodType .DELETE ) {
44- return client .delete (request .getUrl ().toString (), request .body , request .bodyOffset , request .bodySize ,
45- request .getHeader (), request .bodyContentType );
47+ return client .delete (request .getUrl ().toString (), request .getRequestBody (), request .getHeader ());
4648 } else {
4749 throw QiniuException .unrecoverable ("暂不支持这种请求方式" );
4850 }
@@ -91,12 +93,14 @@ public static class Request {
9193 private final Map <String , String > header = new HashMap <>();
9294
9395 /**
94- * 请求数据是在 body 中,从 bodyOffset 开始,获取 bodySize 大小的数据
96+ * 请求 body
9597 */
96- private byte [] body = new byte [0 ];
97- private int bodySize = 0 ;
98- private int bodyOffset = 0 ;
99- private String bodyContentType = Client .DefaultMime ;
98+ private RequestBody body ;
99+ /**
100+ * 请求时,每次从流中读取的数据大小
101+ * 注: body 使用 InputStream 时才有效
102+ */
103+ private long streamBodySinkSize = 1024 * 10 ;
100104
101105 /**
102106 * 构造请求对象
@@ -174,7 +178,7 @@ protected void buildPath() throws QiniuException {
174178 * @param value value
175179 */
176180 protected void addQueryPair (String key , String value ) {
177- if (StringUtils .isNullOrEmpty (key ) || value == null ) {
181+ if (StringUtils .isNullOrEmpty (key )) {
178182 return ;
179183 }
180184 queryPairs .add (new Pair <String , String >(key , value ));
@@ -237,7 +241,7 @@ protected void setMethod(MethodType method) {
237241 * @param key key
238242 * @param value value
239243 */
240- protected void addHeaderField (String key , String value ) {
244+ public void addHeaderField (String key , String value ) {
241245 if (StringUtils .isNullOrEmpty (key ) || StringUtils .isNullOrEmpty (value )) {
242246 return ;
243247 }
@@ -292,16 +296,59 @@ public URL getUrl() throws QiniuException {
292296 * @param contentType 请求数据类型
293297 */
294298 protected void setBody (byte [] body , int offset , int size , String contentType ) {
295- this .body = body ;
296- this .bodyOffset = offset ;
297- this .bodySize = size ;
298- if (!StringUtils .isNullOrEmpty (contentType )) {
299- this .bodyContentType = contentType ;
299+ if (StringUtils .isNullOrEmpty (contentType )) {
300+ contentType = Client .DefaultMime ;
301+ }
302+ MediaType type = MediaType .parse (contentType );
303+ this .body = RequestBody .create (type , body , offset , size );
304+ }
305+
306+ /**
307+ * 设置请求体
308+ *
309+ * @param body 请求数据源
310+ * @param contentType 请求数据类型
311+ * @param limitSize 最大读取 body 的大小;body 有多余则被舍弃;body 不足则会上传多有 body;
312+ * 如果提前不知道 body 大小,但想上传所有 body,limitSize 设置为 -1 即可;
313+ */
314+ protected void setBody (InputStream body , String contentType , long limitSize ) {
315+ if (StringUtils .isNullOrEmpty (contentType )) {
316+ contentType = Client .DefaultMime ;
300317 }
318+ MediaType type = MediaType .parse (contentType );
319+ this .body = new RequestStreamBody (body , type , limitSize );
301320 }
302321
322+ /**
323+ * 使用 streamBody 时,每次读取 streamBody 的大小,读取后发送
324+ * 默认:{@link Api.Request#streamBodySinkSize}
325+ * 相关:{@link RequestStreamBody#writeTo(BufferedSink) sinkSize}
326+ *
327+ * @param streamBodySinkSize 每次读取 streamBody 的大小
328+ */
329+ public Request setStreamBodySinkSize (long streamBodySinkSize ) {
330+ this .streamBodySinkSize = streamBodySinkSize ;
331+ return this ;
332+ }
333+
334+ /**
335+ * 是否有请求体
336+ *
337+ * @return 是否有请求体
338+ */
303339 public boolean hasBody () {
304- return body != null && body .length > 0 && bodySize > 0 ;
340+ return body != null ;
341+ }
342+
343+ private RequestBody getRequestBody () {
344+ if (hasBody ()) {
345+ if (body instanceof RequestStreamBody ) {
346+ ((RequestStreamBody ) body ).setSinkSize (streamBodySinkSize );
347+ }
348+ return body ;
349+ } else {
350+ return RequestBody .create (null , new byte [0 ]);
351+ }
305352 }
306353
307354 /**
@@ -310,11 +357,7 @@ public boolean hasBody() {
310357 * @throws QiniuException
311358 */
312359 protected void buildBodyInfo () throws QiniuException {
313- if (body == null ) {
314- body = new byte [0 ];
315- bodySize = 0 ;
316- bodyOffset = 0 ;
317- }
360+
318361 }
319362
320363 /**
@@ -328,10 +371,7 @@ protected void prepareToRequest() throws QiniuException {
328371 buildBodyInfo ();
329372 }
330373
331- void test () {
332- }
333-
334- private static class Pair <K , V > {
374+ protected static class Pair <K , V > {
335375
336376 /**
337377 * Key of this <code>Pair</code>.
@@ -367,7 +407,7 @@ V getValue() {
367407 * @param key The key for this pair
368408 * @param value The value to use for this pair
369409 */
370- Pair (K key , V value ) {
410+ protected Pair (K key , V value ) {
371411 this .key = key ;
372412 this .value = value ;
373413 }
0 commit comments