All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aoju.bus.http.bodys.RequestBody Maven / Gradle / Ivy

The newest version!
/*********************************************************************************
 *                                                                               *
 * The MIT License (MIT)                                                         *
 *                                                                               *
 * Copyright (c) 2015-2022 aoju.org and other contributors.                      *
 *                                                                               *
 * Permission is hereby granted, free of charge, to any person obtaining a copy  *
 * of this software and associated documentation files (the "Software"), to deal *
 * in the Software without restriction, including without limitation the rights  *
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell     *
 * copies of the Software, and to permit persons to whom the Software is         *
 * furnished to do so, subject to the following conditions:                      *
 *                                                                               *
 * The above copyright notice and this permission notice shall be included in    *
 * all copies or substantial portions of the Software.                           *
 *                                                                               *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR    *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,      *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE   *
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER        *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN     *
 * THE SOFTWARE.                                                                 *
 *                                                                               *
 ********************************************************************************/
package org.aoju.bus.http.bodys;

import org.aoju.bus.core.io.ByteString;
import org.aoju.bus.core.io.sink.BufferSink;
import org.aoju.bus.core.io.source.Source;
import org.aoju.bus.core.lang.Charset;
import org.aoju.bus.core.lang.MediaType;
import org.aoju.bus.core.toolkit.IoKit;
import org.aoju.bus.http.Builder;

import java.io.File;
import java.io.IOException;

/**
 * 内容对象
 *
 * @author Kimi Liu
 * @since Java 17+
 */
public abstract class RequestBody {

    /**
     * 返回传输{@code content}的新请求体。
     * 如果{@code mediaType}是非空且缺少字符集,则使用UTF-8
     *
     * @param mediaType 请求类型
     * @param content   内容
     * @return 传输请求体
     */
    public static RequestBody create(MediaType mediaType, String content) {
        java.nio.charset.Charset charset = Charset.UTF_8;
        if (mediaType != null) {
            charset = mediaType.charset();
            if (charset == null) {
                charset = Charset.UTF_8;
                mediaType = MediaType.valueOf(mediaType + "; charset=utf-8");
            }
        }
        byte[] bytes = content.getBytes(charset);
        return create(mediaType, bytes);
    }

    /**
     * 返回发送{@code content}的新请求体
     *
     * @param mediaType 请求类型
     * @param content   内容
     * @return 传输请求体
     */
    public static RequestBody create(
            final MediaType mediaType,
            final ByteString content) {
        return new RequestBody() {
            @Override
            public MediaType mediaType() {
                return mediaType;
            }

            @Override
            public long length() {
                return content.size();
            }

            @Override
            public void writeTo(BufferSink sink) throws IOException {
                sink.write(content);
            }
        };
    }

    /**
     * 发送{@code content}的新请求体
     *
     * @param mediaType 媒体类型
     * @param content   内容
     * @return 传输请求体
     */
    public static RequestBody create(final MediaType mediaType, final byte[] content) {
        return create(mediaType, content, 0, content.length);
    }

    /**
     * 发送{@code content}的新请求体
     *
     * @param mediaType 媒体类型
     * @param content   内容
     * @param offset    偏移量
     * @param byteCount 当前大小
     * @return 传输请求体
     */
    public static RequestBody create(final MediaType mediaType, final byte[] content,
                                     final int offset, final int byteCount) {
        if (null == content) {
            throw new NullPointerException("content == null");
        }
        Builder.checkOffsetAndCount(content.length, offset, byteCount);
        return new RequestBody() {
            @Override
            public MediaType mediaType() {
                return mediaType;
            }

            @Override
            public long length() {
                return byteCount;
            }

            @Override
            public void writeTo(BufferSink sink) throws IOException {
                sink.write(content, offset, byteCount);
            }
        };
    }

    /**
     * 新的请求体,该请求体传输{@code file}的内容
     *
     * @param mediaType 请求类型
     * @param file      文件
     * @return 传输请求体
     */
    public static RequestBody create(final MediaType mediaType, final File file) {
        if (null == file) {
            throw new NullPointerException("file == null");
        }

        return new RequestBody() {
            @Override
            public MediaType mediaType() {
                return mediaType;
            }

            @Override
            public long length() {
                return file.length();
            }

            @Override
            public void writeTo(BufferSink sink) throws IOException {
                try (Source source = IoKit.source(file)) {
                    sink.writeAll(source);
                }
            }
        };
    }

    /**
     * @return 返回此主体的媒体类型
     */
    public abstract MediaType mediaType();

    /**
     * 返回调用{@link #writeTo}时写入{@code sink}的字节数,如果该计数未知,则返回-1
     *
     * @return 计数信息
     * @throws IOException 异常
     */
    public long length() throws IOException {
        return -1;
    }

    /**
     * 将此请求的内容写入{@code sink}
     *
     * @param sink 缓存区
     * @throws IOException 异常信息
     */
    public abstract void writeTo(BufferSink sink) throws IOException;

    /**
     * A duplex request body is special in how it is transmitted on the network and
     * in the API contract between Http and the application.
     * This method returns false unless it is overridden by a subclass.
     * Duplex Transmission
     * With regular HTTP calls the request always completes sending before the response may begin
     * receiving. With duplex the request and response may be interleaved! That is, request body bytes
     * may be sent after response headers or body bytes have been received.
     * Though any call may be initiated as a duplex call, only web servers that are specially
     * designed for this nonstandard interaction will use it. As of 2019-01, the only widely-used
     * implementation of this pattern is gRPC.
     * Because the encoding of interleaved data is not well-defined for HTTP/1, duplex request
     * bodies may only be used with HTTP/2. Calls to HTTP/1 servers will fail before the HTTP request
     * is transmitted. If you cannot ensure that your client and server both support HTTP/2, do not
     * use this feature.
     * With regular request bodies it is not legal to write bytes to the sink passed to {@link
     * RequestBody#writeTo} after that method returns. For duplex requests bodies that condition is
     * lifted. Such writes occur on an application-provided thread and may occur concurrently with
     * reads of the {@link ResponseBody}. For duplex request bodies, {@link #writeTo} should return
     * quickly, possibly by handing off the provided request body to another thread to perform
     * writing.
     */
    public boolean isDuplex() {
        return false;
    }

    /**
     * Returns true if this body expects at most one call to {@link #writeTo} and can be transmitted
     * at most once. This is typically used when writing the request body is destructive and it is not
     * possible to recreate the request body after it has been sent.
     * This method returns false unless it is overridden by a subclass.
     * By default Http will attempt to retransmit request bodies when the original request fails
     * due to a stale connection, a client timeout (HTTP 408), a satisfied authorization challenge
     * (HTTP 401 and 407), or a retryable server failure (HTTP 503 with a {@code Retry-After: 0}
     * header).
     */
    public boolean isOneShot() {
        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy