当前位置: 首页>编程语言>正文

ResponseEntity 下载模板 responseentity 详解

文章目录

  • 一、ResponseEntity深入
  • 简介
  • 使用场景
  • 1、场景一
  • 2、场景二
  • 3、场景三:
  • 父类HttpEntity
  • ResponseEntity的研究
  • 1、ResponseEntity的属性
  • 2、ResponseEntity的6个构造方法:
  • 3、HttpStatus
  • 简介
  • HTTP状态码
  • 属性
  • 构造方法
  • 其他方法
  • 序列号
  • 4、ResponseEntity的其他方法
  • 5、BodyBuilder和HeadersBuilder介绍
  • 6、静态方法

一、ResponseEntity深入

简介

ResponseEntity可以表示整个HTTP响应,包括:状态码、头部信息以及响应体。ResponseEntity的API:

public class ResponseEntity<T> extends HttpEntity<T> {
}

接下来看看它的官方介绍:

Extension of HttpEntity that adds an HttpStatus status code. Used in RestTemplate as well as in @Controller methods.

HttpEntity的扩展,添加了一个HttpStatus状态代码。在RestTemplate和@Controller方法中使用。

使用场景

1、场景一

In RestTemplate, this class is returned by getForEntity() and exchange():

在RestTemplate中,这个类由getForEntity()和exchange()返回

【说明】RestTemplate:是Spring提供的模板工具类,堆基于HTTP的客户端进行了封装,并且实现了对象与json的序列化和反序列化.

下面看一下getForEntity(),传入URL和响应的类,就会返回一个ResponseEntity

//通过对URL执行GET来检索表示。响应被转换并存储在ResponseEntity中。
//Retrieve a representation by doing a GET on the URL . The response is converted and stored in an ResponseEntity.
<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;

使用:

ResponseEntity<String> entity = template.getForEntity("https://example.com", String.class);
   String body = entity.getBody();
   MediaType contentType = entity.getHeaders().getContentType();
   HttpStatus statusCode = entity.getStatusCode();
2、场景二

This can also be used in Spring MVC as the return value from an @Controller method:

这也可以在Spring MVC中用作@Controller方法的返回值:

使用:

@RequestMapping("/handle")
   public ResponseEntity<String> handle() {
     URI location = ...;
     HttpHeaders responseHeaders = new HttpHeaders();
     responseHeaders.setLocation(location);
     responseHeaders.set("MyResponseHeader", "MyValue");
     return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
   }
3、场景三:

Or, by using a builder accessible via static methods:

或者,可以通过静态方法的构建器进行访问

使用:

@RequestMapping("/handle")
   public ResponseEntity<String> handle() {
     URI location = ...;
     return ResponseEntity.created(location).header("MyResponseHeader", "MyValue").body("Hello World");
   }

父类HttpEntity

Represents an HTTP request or response entity, consisting of headers and body.

HttpEntity:表示HTTP请求或响应实体,由报头和正文组成。

这就证实了之前的说明,ResponseEntity是HttpEntity的扩展,在HttpEntity的基础之上添加了状态码。

它有两个属性:报头和身体

private final HttpHeaders headers;

//身体允许为空
@Nullable
private final T body;

//同时定义了一个空的HttpEntity,没有报头和身体
public static final HttpEntity<?> EMPTY = new HttpEntity<>();

有4个构造方法:

//创建一个空的HttpEntity
protected HttpEntity() {this(null, null);}

//创建了一个有身体的HttpEntity,但是没有报头
public HttpEntity(T body) {this(body, null);}

//创建了一个有报头但是没有身体的HttpEntity
public HttpEntity(MultiValueMap<String, String> headers) {this(null, headers);}

//创建了一个既有身体又有报头的HttpEntity
public HttpEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers) {
		this.body = body;
		this.headers = HttpHeaders.readOnlyHttpHeaders(headers != null ? headers : new HttpHeaders());
	}

剩下的都是get/set方法,用于获取身体和报头;判断是否有身体等方法,在这里就赘述了。

接下来好好研究ResponseEntity。

ResponseEntity的研究

从上面的结论中已经知道,ResponseEntity继承自HttpEntity,以及ResponseEntity的使用场景,接下来好好研究它内部的方法,首先看看它的属性有哪些

1、ResponseEntity的属性

状态码 status code.

private final Object status;
2、ResponseEntity的6个构造方法:
//1、创建一个仅仅只有状态码的ResponseEntity
public ResponseEntity(HttpStatus status) {
		this(null, null, status);
	}

//2、创建一个有身体和状态码的ResponseEntity
public ResponseEntity(@Nullable T body, HttpStatus status) {
		this(body, null, status);
	}
//3、创建一个有报头和状态码的ResponseEntity
public ResponseEntity(MultiValueMap<String, String> headers, HttpStatus status) {
		this(null, headers, status);
	}
//4、创建一个有身体、报头和状态码的ResponseEntity
public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status) {
		this(body, headers, (Object) status);
	}

//5、Create a {@code ResponseEntity} with a body, headers, and a raw status code.
// @param rawStatus the status code value  
//创建一个有身体、报头、自己给定状态码   的ResponseEntity
public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, int rawStatus) {
		this(body, headers, (Object) rawStatus);
	}

	/**6、私有构造器
	 * Private constructor.
	 */
	private ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, Object status) {
		super(body, headers);
		Assert.notNull(status, "HttpStatus must not be null");
		this.status = status;
	}
3、HttpStatus
简介

从上面的构造器中可以看到状态码都是使用了:HttpStatus中的状态码,接下来咱们看看又是一个什么鬼

/**
Enumeration of HTTP status codes.
The HTTP status code series can be retrieved via series().
HTTP状态代码系列可以通过series()检索。
*/
public enum HttpStatus {...}
HTTP状态码

HttpStatus是HTTP状态码的枚举,看看里面都有些啥内容,在这之前,我给大家看一份HTTP的官方文档

有时间看看HTTP协议的内容

Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content 超文本传输协议(HTTP/1.1):语义和内容

https://datatracker.ietf.org/doc/html/rfc7231#section-6.2.1

超文本传输协议(HTTP)是一种无状态的应用用于分布式、协作、超文本信息的级别协议系统。本文档定义了HTTP/1.1消息的语义,如请求方法,请求报头字段,响应状态码,响应报头字段,以及消息(元数据和正文内容)和内容机制谈判

这是一个互联网标准跟踪文档。

这里面会具体介绍HTTP状态码,如果你需要学习其他的内容,自己有空去看看。

下面是常见的状态码,给大家罗列出来:

• 1XX:服务器收到请求,需要请求者继续执行操作 
  
• 100 Continue :继续。客户端应继续其请求
• 101 Switching Protocols :切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
• 2XX :成功,操作被成功接收并处理 
  
• 200 OK :请求已成功。
• 201 Created :201 (Created)状态码表示请求已经被创建完成并导致一个或多个新的资源创建。
• 202 Accepted:已接受。已经接受请求,但未处理完成
• 204 No Content: 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
• 。。。。
• 3XX:重定向,需要进一步的操作以完成请求
• 4XX:客户端错误,请求包含语法错误或无法完成请求 
  
• 400 Bad Request:客户端请求的语法错误,服务器无法理解
• 404 Not Found:服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
• 5XX:服务器错误,服务器在处理请求的过程中发生了错误 
  
• 500 Internal Server Error:服务器内部错误,无法完成请求
• 502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
• 504 Gateway Timeout:充当网关或代理的服务器,未及时从远端服务器获取请求
• 。。。。。

看完了上述的内容,再来看一下HttpStatus这个枚举类里面的内容,它和上面的内容相对应

// 1xx Informational
	CONTINUE(100, Series.INFORMATIONAL, "Continue"),
	SWITCHING_PROTOCOLS(101, Series.INFORMATIONAL, "Switching Protocols"),
	PROCESSING(102, Series.INFORMATIONAL, "Processing"),
	CHECKPOINT(103, Series.INFORMATIONAL, "Checkpoint"),

	// 2xx Success
	OK(200, Series.SUCCESSFUL, "OK"),
	CREATED(201, Series.SUCCESSFUL, "Created"),
	ACCEPTED(202, Series.SUCCESSFUL, "Accepted"),
	NON_AUTHORITATIVE_INFORMATION(203, Series.SUCCESSFUL, "Non-Authoritative Information"),
	NO_CONTENT(204, Series.SUCCESSFUL, "No Content"),
	RESET_CONTENT(205, Series.SUCCESSFUL, "Reset Content"),
	PARTIAL_CONTENT(206, Series.SUCCESSFUL, "Partial Content"),
	MULTI_STATUS(207, Series.SUCCESSFUL, "Multi-Status"),
	ALREADY_REPORTED(208, Series.SUCCESSFUL, "Already Reported"),
	IM_USED(226, Series.SUCCESSFUL, "IM Used"),

	// 3xx Redirection
	MULTIPLE_CHOICES(300, Series.REDIRECTION, "Multiple Choices"),
	MOVED_PERMANENTLY(301, Series.REDIRECTION, "Moved Permanently"),
	FOUND(302, Series.REDIRECTION, "Found"),
	@Deprecated
	MOVED_TEMPORARILY(302, Series.REDIRECTION, "Moved Temporarily"),
	SEE_OTHER(303, Series.REDIRECTION, "See Other"),
	NOT_MODIFIED(304, Series.REDIRECTION, "Not Modified"),
	@Deprecated
	USE_PROXY(305, Series.REDIRECTION, "Use Proxy"),
	TEMPORARY_REDIRECT(307, Series.REDIRECTION, "Temporary Redirect"),
	PERMANENT_REDIRECT(308, Series.REDIRECTION, "Permanent Redirect"),

	// --- 4xx Client Error ---
	BAD_REQUEST(400, Series.CLIENT_ERROR, "Bad Request"),
	UNAUTHORIZED(401, Series.CLIENT_ERROR, "Unauthorized"),
	PAYMENT_REQUIRED(402, Series.CLIENT_ERROR, "Payment Required"),
	FORBIDDEN(403, Series.CLIENT_ERROR, "Forbidden"),
	NOT_FOUND(404, Series.CLIENT_ERROR, "Not Found"),
	METHOD_NOT_ALLOWED(405, Series.CLIENT_ERROR, "Method Not Allowed"),
	NOT_ACCEPTABLE(406, Series.CLIENT_ERROR, "Not Acceptable"),
	PROXY_AUTHENTICATION_REQUIRED(407, Series.CLIENT_ERROR, "Proxy Authentication Required"),
	REQUEST_TIMEOUT(408, Series.CLIENT_ERROR, "Request Timeout"),
	CONFLICT(409, Series.CLIENT_ERROR, "Conflict"),
	GONE(410, Series.CLIENT_ERROR, "Gone"),
	LENGTH_REQUIRED(411, Series.CLIENT_ERROR, "Length Required"),
	PRECONDITION_FAILED(412, Series.CLIENT_ERROR, "Precondition Failed"),
	PAYLOAD_TOO_LARGE(413, Series.CLIENT_ERROR, "Payload Too Large"),
	@Deprecated
	REQUEST_ENTITY_TOO_LARGE(413, Series.CLIENT_ERROR, "Request Entity Too Large"),
	URI_TOO_LONG(414, Series.CLIENT_ERROR, "URI Too Long"),
	@Deprecated
	REQUEST_URI_TOO_LONG(414, Series.CLIENT_ERROR, "Request-URI Too Long"),
	UNSUPPORTED_MEDIA_TYPE(415, Series.CLIENT_ERROR, "Unsupported Media Type"),
	REQUESTED_RANGE_NOT_SATISFIABLE(416, Series.CLIENT_ERROR, "Requested range not satisfiable"),
	EXPECTATION_FAILED(417, Series.CLIENT_ERROR, "Expectation Failed"),
	I_AM_A_TEAPOT(418, Series.CLIENT_ERROR, "I'm a teapot"),
    ...

	// --- 5xx Server Error ---
	INTERNAL_SERVER_ERROR(500, Series.SERVER_ERROR, "Internal Server Error"),
	NOT_IMPLEMENTED(501, Series.SERVER_ERROR, "Not Implemented"),
	BAD_GATEWAY(502, Series.SERVER_ERROR, "Bad Gateway"),
	SERVICE_UNAVAILABLE(503, Series.SERVER_ERROR, "Service Unavailable"),
	GATEWAY_TIMEOUT(504, Series.SERVER_ERROR, "Gateway Timeout"),
	HTTP_VERSION_NOT_SUPPORTED(505, Series.SERVER_ERROR, "HTTP Version not supported"),
	VARIANT_ALSO_NEGOTIATES(506, Series.SERVER_ERROR, "Variant Also Negotiates"),
	INSUFFICIENT_STORAGE(507, Series.SERVER_ERROR, "Insufficient Storage"),
	LOOP_DETECTED(508, Series.SERVER_ERROR, "Loop Detected"),
	BANDWIDTH_LIMIT_EXCEEDED(509, Series.SERVER_ERROR, "Bandwidth Limit Exceeded"),
	NOT_EXTENDED(510, Series.SERVER_ERROR, "Not Extended"),
	NETWORK_AUTHENTICATION_REQUIRED(511, Series.SERVER_ERROR, "Network Authentication Required");

是不是觉得是熟悉啊

来看看它的属性和构造函数

属性
//状态码的值
private final int value;
//序列号
private final Series series;
//错误提示
private final String reasonPhrase;
构造方法
HttpStatus(int value, Series series, String reasonPhrase) {
		this.value = value;
		this.series = series;
		this.reasonPhrase = reasonPhrase;
	}
其他方法
//返回状态码的值
public int value() {return this.value;}
public static HttpStatus valueOf(int statusCode) {...}
//返回状态码的序列号
public Series series() {return this.series;}
//返回错误信息
public String getReasonPhrase() {return this.reasonPhrase;}
//判断是否为1开头的状态码
public boolean is1xxInformational() {
		return (series() == Series.INFORMATIONAL);
	}
//判断是否为2开头的状态码
public boolean is2xxSuccessful() {
		return (series() == Series.SUCCESSFUL);
	}
。。。

接下来看看序列号

序列号

Enumeration of HTTP status series.

HTTP 状态码序列号的枚举,主要分为5类:信息、成功、重定向、客户端异常、服务器异常

public enum Series {

	INFORMATIONAL(1),//临时响应
	SUCCESSFUL(2),//请求成功
	REDIRECTION(3),//重定向
	CLIENT_ERROR(4),//客户端异常
	SERVER_ERROR(5);//服务器异常
    private final int value;

		Series(int value) {
			this.value = value;
		}

		/**返回状态码序列号的值
		 * Return the integer value of this status series. Ranges from 1 to 5.
		 */
		public int value() {
			return this.value;
		}
    。。。
    
}

HttpStatus的内容完了

4、ResponseEntity的其他方法
//返回响应的HTTP状态码。
public HttpStatus getStatusCode() {
		if (this.status instanceof HttpStatus) {
			return (HttpStatus) this.status;
		}
		else {
			return HttpStatus.valueOf((Integer) this.status);
		}
	}

	/**
	 * 返回响应的HTTP状态码的值。该值是一个int值
	 * Return the HTTP status code of the response.
	 * @return the HTTP status as an int value
	 * @since 4.3
	 */
	public int getStatusCodeValue() {
		if (this.status instanceof HttpStatus) {
			return ((HttpStatus) this.status).value();
		}
		else {
			return (Integer) this.status;
		}
	}
5、BodyBuilder和HeadersBuilder介绍

ResponseEntity中有两个接口,BodyBuilder和HeadersBuilder ,前者是给响应实体添加主体的一个构建器,后者定义将头添加到响应实体的构建器。

HeadersBuilder

//Defines a builder that adds headers to the response entity.
//定义一个将头部信息添加到响应体的构建器
public interface HeadersBuilder<B extends HeadersBuilder<B>> {
    
		//Add the given, single header value under the given name.
    	//在给定的名称下添加给定的头部值。
		B header(String headerName, String... headerValues);
		
		//Copy the given headers into the entity's headers map.
		B headers(@Nullable HttpHeaders headers);
    
		B headers(Consumer<HttpHeaders> headersConsumer);

		//Build the response entity with no body. 构建没有主体的响应实体。
		<T> ResponseEntity<T> build();
	}
}

BodyBuilder

/**
 * Defines a builder that adds a body to the response entity.
 * 定义了一个添加body到响应实体的构建器
 * @since 4.1
 */
public interface BodyBuilder extends HeadersBuilder<BodyBuilder> {

   //Set the length of the body in bytes, as specified by the Content-Length header.
   //以字节为单位设置正文的长度,由Content-Length头指定。
   BodyBuilder contentLength(long contentLength);

   //Set the media type of the body, as specified by the Content-Type header.
   //设置主体的媒体类型,由Content-Type标题指定。
   BodyBuilder contentType(MediaType contentType);

    //Set the body of the response entity and returns it.
    //设置响应实体的主体并返回它
   <T> ResponseEntity<T> body(@Nullable T body);
}

我以为已经没有builder了,没想到还有一个BodyBuilder默认的实现类

private static class DefaultBuilder implements BodyBuilder {

		private final Object statusCode;//状态码

		private final HttpHeaders headers = new HttpHeaders(); //头部信息

       //有状态码的构造器
		public DefaultBuilder(Object statusCode) {
			this.statusCode = statusCode;
		}

		@Override
		public BodyBuilder header(String headerName, String... headerValues) {
			for (String headerValue : headerValues) {
				this.headers.add(headerName, headerValue);
			}
			return this;
		}
    。。。。
    //其他的方法都是重写接口里的
6、静态方法
// Static builder methods

	/**
	 * 根据被给定的HttpStatus状态码创建一个构建器
	 * Create a builder with the given status.
	 * @param status the response status
	 * @return the created builder
	 * @since 4.1
	 */
	public static BodyBuilder status(HttpStatus status) {
		Assert.notNull(status, "HttpStatus must not be null");
		return new DefaultBuilder(status);
	}

	/**根据被给定的int类型的状态码创建一个构建器
	 * Create a builder with the given status.
	 * @param status the response status
	 * @return the created builder
	 * @since 4.1
	 */
	public static BodyBuilder status(int status) {
		return new DefaultBuilder(status);
	}

	/**
	 * Create a builder with the status set to {@linkplain HttpStatus#OK OK}.
     * 创建一个状态设置为OK的构建器。
	 * @return the created builder
	 * @since 4.1
	 */
	public static BodyBuilder ok() {
		return status(HttpStatus.OK);
	}

	/** 创建具有给定主体和状态设置为OK的ResponseEntity的快捷方式。
	 * A shortcut for creating a {@code ResponseEntity} with the given body
	 * and the status set to {@linkplain HttpStatus#OK OK}.
	 * @param body the body of the response entity (possibly empty)
	 * @return the created {@code ResponseEntity}
	 * @since 4.1
	 */
	public static <T> ResponseEntity<T> ok(@Nullable T body) {
		return ok().body(body);
	}

	/**
	一个快捷方式,用于创建具有给定主体和OK状态的ResponseEntity,或者在Optional.empty()参数的情况下,创建一个空主体和NOT FOUND状态的ResponseEntity。
	 * A shortcut for creating a {@code ResponseEntity} with the given body
	 * and the {@linkplain HttpStatus#OK OK} status, or an empty body and a
	 * {@linkplain HttpStatus#NOT_FOUND NOT FOUND} status in case of an
	 * {@linkplain Optional#empty()} parameter.
	 * @return the created {@code ResponseEntity}
	 * @since 5.1
	 */
	public static <T> ResponseEntity<T> of(Optional<T> body) {
		Assert.notNull(body, "Body must not be null");
		return body.map(ResponseEntity::ok).orElseGet(() -> notFound().build());
	}

	/**创建一个新的构建器,其状态为CREATED,位置标头设置为给定URI。
	 * Create a new builder with a {@linkplain HttpStatus#CREATED CREATED} status
	 * and a location header set to the given URI.
	 * @param location the location URI
	 * @return the created builder
	 * @since 4.1
	 */
	public static BodyBuilder created(URI location) {
		return status(HttpStatus.CREATED).location(location);
	}

	/**创建一个状态为ACCEPTED的构建器。
	 * Create a builder with an {@linkplain HttpStatus#ACCEPTED ACCEPTED} status.
	 * @return the created builder
	 * @since 4.1
	 */
	public static BodyBuilder accepted() {
		return status(HttpStatus.ACCEPTED);
	}

	/**
	 * Create a builder with a {@linkplain HttpStatus#NO_CONTENT NO_CONTENT} status.
	 * @return the created builder
	 * @since 4.1
	 */
	public static HeadersBuilder<?> noContent() {
		return status(HttpStatus.NO_CONTENT);
	}

	/**
	 * Create a builder with a {@linkplain HttpStatus#BAD_REQUEST BAD_REQUEST} status.
	 * @return the created builder
	 * @since 4.1
	 */
	public static BodyBuilder badRequest() {
		return status(HttpStatus.BAD_REQUEST);
	}

	/**
	 * Create a builder with a {@linkplain HttpStatus#NOT_FOUND NOT_FOUND} status.
	 * @return the created builder
	 * @since 4.1
	 */
	public static HeadersBuilder<?> notFound() {
		return status(HttpStatus.NOT_FOUND);
	}

	/**
	 * Create a builder with an
	 * {@linkplain HttpStatus#UNPROCESSABLE_ENTITY UNPROCESSABLE_ENTITY} status.
	 * @return the created builder
	 * @since 4.1.3
	 */
	public static BodyBuilder unprocessableEntity() {
		return status(HttpStatus.UNPROCESSABLE_ENTITY);
	}

	/**创建一个状态为INTERNAL_SERVER_ERROR 内部服务器错误的构建器
	 * Create a builder with an
	 * {@linkplain HttpStatus#INTERNAL_SERVER_ERROR INTERNAL_SERVER_ERROR} status.
	 * @return the created builder
	 * @since 5.3.8
	 */
	public static BodyBuilder internalServerError() {
		return status(HttpStatus.INTERNAL_SERVER_ERROR);
	}



https://www.xamrdz.com/lan/56c1923068.html

相关文章: