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

org.dromara.hutool.http.client.Response Maven / Gradle / Ivy

There is a newer version: 6.0.0.M3
Show newest version
/*
 * Copyright (c) 2013-2024 Hutool Team and hutool.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.dromara.hutool.http.client;

import org.dromara.hutool.core.convert.ConvertUtil;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.http.HttpException;
import org.dromara.hutool.http.client.body.ResponseBody;
import org.dromara.hutool.http.meta.ContentTypeUtil;
import org.dromara.hutool.http.meta.HeaderName;
import org.dromara.hutool.http.meta.HttpHeaderUtil;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 响应内容接口,包括响应状态码、HTTP消息头、响应体等信息
 *
 * @author looly
 * @since 6.0.0
 */
public interface Response extends Closeable {

	/**
	 * 获取状态码
	 *
	 * @return 状态码
	 */
	int getStatus();

	/**
	 * 根据name获取头信息
* 根据RFC2616规范,header的name不区分大小写 * * @param name Header名 * @return Header值 */ String header(final String name); /** * 获取headers * * @return Headers Map */ Map> headers(); /** * 获取字符集编码,默认为响应头中的编码 * * @return 字符集 */ default Charset charset() { return ContentTypeUtil.getCharset(header(HeaderName.CONTENT_TYPE)); } /** * 获得服务区响应流
* 流获取后处理完毕需关闭此类 * * @return 响应流 */ InputStream bodyStream(); /** * 获取响应体,包含服务端返回的内容和Content-Type信息 * * @return {@link ResponseBody} */ default ResponseBody body() { return new ResponseBody(this, bodyStream(), false, true); } /** * 获取响应主体 * * @return String * @throws HttpException 包装IO异常 */ default String bodyStr() throws HttpException { try (final ResponseBody body = body()) { return body.getString(); } catch (final IOException e) { throw new IORuntimeException(e); } } /** * 获取响应流字节码
* 此方法会转为同步模式,读取响应流并关闭之 * * @return byte[] */ default byte[] bodyBytes() { try (final ResponseBody body = body()) { return body.getBytes(); } catch (final IOException e) { throw new IORuntimeException(e); } } /** * 请求是否成功,判断依据为:状态码范围在200~299内。 * * @return 是否成功请求 */ default boolean isOk() { final int status = getStatus(); return status >= 200 && status < 300; } /** * 根据name获取头信息 * * @param name Header名 * @return Header值 */ default String header(final HeaderName name) { if (null == name) { return null; } return header(name.toString()); } /** * 根据name获取对应的头信息列表 * * @param name Header名 * @return Header值 */ default List headerList(final String name) { return HttpHeaderUtil.headerList(headers(), name); } /** * 获取内容编码 * * @return String */ default String contentEncoding() { return header(HeaderName.CONTENT_ENCODING); } /** * 获取内容长度,以下情况长度无效: *
    *
  • Transfer-Encoding: Chunked
  • *
  • Content-Encoding: XXX
  • *
* 参考:https://blog.csdn.net/jiang7701037/article/details/86304302 * * @return 长度,-1表示服务端未返回或长度无效 * @since 5.7.9 */ default long contentLength() { long contentLength = ConvertUtil.toLong(header(HeaderName.CONTENT_LENGTH), -1L); if (contentLength > 0 && (isChunked() || StrUtil.isNotBlank(contentEncoding()))) { //按照HTTP协议规范,在 Transfer-Encoding和Content-Encoding设置后 Content-Length 无效。 contentLength = -1; } return contentLength; } /** * 是否为Transfer-Encoding:Chunked的内容 * * @return 是否为Transfer-Encoding:Chunked的内容 * @since 4.6.2 */ default boolean isChunked() { return "Chunked".equalsIgnoreCase(header(HeaderName.TRANSFER_ENCODING)); } /** * 获取本次请求服务器返回的Cookie信息 * * @return Cookie字符串 * @since 3.1.1 */ default String getCookieStr() { return header(HeaderName.SET_COOKIE); } /** * 从Content-Disposition头中获取文件名,以参数名为`filename`为例,规则为: *
    *
  • 首先按照RFC5987规范检查`filename*`参数对应的值,即:`filename*="example.txt"`,则获取`example.txt`
  • *
  • 如果找不到`filename*`参数,则检查`filename`参数对应的值,即:`filename="example.txt"`,则获取`example.txt`
  • *
* 按照规范,`Content-Disposition`可能返回多个,此处遍历所有返回头,并且`filename*`始终优先获取,即使`filename`存在并更靠前。
* 参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition * * @param paramName 文件参数名,如果为{@code null}则使用默认的`filename` * @return 文件名,empty表示无 */ default String getFileNameFromDisposition(final String paramName) { return HttpHeaderUtil.getFileNameFromDisposition(headers(), paramName); } /** * 链式处理结果 * * @param consumer {@link Consumer} */ default void then(final Consumer consumer) { consumer.accept(this); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy