001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.http; 018 019import org.springframework.lang.Nullable; 020import org.springframework.util.MultiValueMap; 021import org.springframework.util.ObjectUtils; 022 023/** 024 * Represents an HTTP request or response entity, consisting of headers and body. 025 * 026 * <p>Typically used in combination with the {@link org.springframework.web.client.RestTemplate}, 027 * like so: 028 * <pre class="code"> 029 * HttpHeaders headers = new HttpHeaders(); 030 * headers.setContentType(MediaType.TEXT_PLAIN); 031 * HttpEntity<String> entity = new HttpEntity<String>(helloWorld, headers); 032 * URI location = template.postForLocation("https://example.com", entity); 033 * </pre> 034 * or 035 * <pre class="code"> 036 * HttpEntity<String> entity = template.getForEntity("https://example.com", String.class); 037 * String body = entity.getBody(); 038 * MediaType contentType = entity.getHeaders().getContentType(); 039 * </pre> 040 * Can also be used in Spring MVC, as a return value from a @Controller method: 041 * <pre class="code"> 042 * @RequestMapping("/handle") 043 * public HttpEntity<String> handle() { 044 * HttpHeaders responseHeaders = new HttpHeaders(); 045 * responseHeaders.set("MyResponseHeader", "MyValue"); 046 * return new HttpEntity<String>("Hello World", responseHeaders); 047 * } 048 * </pre> 049 * 050 * @author Arjen Poutsma 051 * @author Juergen Hoeller 052 * @since 3.0.2 053 * @param <T> the body type 054 * @see org.springframework.web.client.RestTemplate 055 * @see #getBody() 056 * @see #getHeaders() 057 */ 058public class HttpEntity<T> { 059 060 /** 061 * The empty {@code HttpEntity}, with no body or headers. 062 */ 063 public static final HttpEntity<?> EMPTY = new HttpEntity<>(); 064 065 066 private final HttpHeaders headers; 067 068 @Nullable 069 private final T body; 070 071 072 /** 073 * Create a new, empty {@code HttpEntity}. 074 */ 075 protected HttpEntity() { 076 this(null, null); 077 } 078 079 /** 080 * Create a new {@code HttpEntity} with the given body and no headers. 081 * @param body the entity body 082 */ 083 public HttpEntity(T body) { 084 this(body, null); 085 } 086 087 /** 088 * Create a new {@code HttpEntity} with the given headers and no body. 089 * @param headers the entity headers 090 */ 091 public HttpEntity(MultiValueMap<String, String> headers) { 092 this(null, headers); 093 } 094 095 /** 096 * Create a new {@code HttpEntity} with the given body and headers. 097 * @param body the entity body 098 * @param headers the entity headers 099 */ 100 public HttpEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers) { 101 this.body = body; 102 HttpHeaders tempHeaders = new HttpHeaders(); 103 if (headers != null) { 104 tempHeaders.putAll(headers); 105 } 106 this.headers = HttpHeaders.readOnlyHttpHeaders(tempHeaders); 107 } 108 109 110 /** 111 * Returns the headers of this entity. 112 */ 113 public HttpHeaders getHeaders() { 114 return this.headers; 115 } 116 117 /** 118 * Returns the body of this entity. 119 */ 120 @Nullable 121 public T getBody() { 122 return this.body; 123 } 124 125 /** 126 * Indicates whether this entity has a body. 127 */ 128 public boolean hasBody() { 129 return (this.body != null); 130 } 131 132 133 @Override 134 public boolean equals(@Nullable Object other) { 135 if (this == other) { 136 return true; 137 } 138 if (other == null || other.getClass() != getClass()) { 139 return false; 140 } 141 HttpEntity<?> otherEntity = (HttpEntity<?>) other; 142 return (ObjectUtils.nullSafeEquals(this.headers, otherEntity.headers) && 143 ObjectUtils.nullSafeEquals(this.body, otherEntity.body)); 144 } 145 146 @Override 147 public int hashCode() { 148 return (ObjectUtils.nullSafeHashCode(this.headers) * 29 + ObjectUtils.nullSafeHashCode(this.body)); 149 } 150 151 @Override 152 public String toString() { 153 StringBuilder builder = new StringBuilder("<"); 154 if (this.body != null) { 155 builder.append(this.body); 156 builder.append(','); 157 } 158 builder.append(this.headers); 159 builder.append('>'); 160 return builder.toString(); 161 } 162 163}