refactored HTTP support into top-level package "org.springframework.http"; revised RestTemplate facility in package "org.springframework.web.client"
This commit is contained in:
parent
882c195221
commit
760cab8fea
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.springframework.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link MultiValueMap} that wraps a plain {@code Map}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DefaultMultiValueMap<K, V> implements MultiValueMap<K, V> {
|
||||
|
||||
private final Map<K, List<V>> wrappee;
|
||||
|
||||
/**
|
||||
* Constructs a new intance of the {@code DefaultMultiValueMap} wrapping a plain {@link LinkedHashMap}.
|
||||
*/
|
||||
public DefaultMultiValueMap() {
|
||||
this(new LinkedHashMap<K, List<V>>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new intance of the {@code DefaultMultiValueMap} wrapping the given map.
|
||||
*
|
||||
* @param wrappee the map to be wrapped
|
||||
*/
|
||||
public DefaultMultiValueMap(Map<K, List<V>> wrappee) {
|
||||
Assert.notNull(wrappee, "'wrappee' must not be null");
|
||||
this.wrappee = wrappee;
|
||||
}
|
||||
|
||||
/*
|
||||
* MultiValueMap implementation
|
||||
*/
|
||||
|
||||
public void add(K key, V value) {
|
||||
List<V> values = wrappee.get(key);
|
||||
if (values == null) {
|
||||
values = new LinkedList<V>();
|
||||
wrappee.put(key, values);
|
||||
}
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
public V getFirst(K key) {
|
||||
List<V> values = wrappee.get(key);
|
||||
return values != null ? values.get(0) : null;
|
||||
}
|
||||
|
||||
public void set(K key, V value) {
|
||||
List<V> values = new LinkedList<V>();
|
||||
values.add(value);
|
||||
wrappee.put(key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map implementation
|
||||
*/
|
||||
|
||||
public int size() {
|
||||
return wrappee.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return wrappee.isEmpty();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return wrappee.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
return wrappee.containsValue(value);
|
||||
}
|
||||
|
||||
public List<V> get(Object key) {
|
||||
return wrappee.get(key);
|
||||
}
|
||||
|
||||
public List<V> put(K key, List<V> value) {
|
||||
return wrappee.put(key, value);
|
||||
}
|
||||
|
||||
public List<V> remove(Object key) {
|
||||
return wrappee.remove(key);
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends List<V>> m) {
|
||||
wrappee.putAll(m);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
wrappee.clear();
|
||||
}
|
||||
|
||||
public Set<K> keySet() {
|
||||
return wrappee.keySet();
|
||||
}
|
||||
|
||||
public Collection<List<V>> values() {
|
||||
return wrappee.values();
|
||||
}
|
||||
|
||||
public Set<Entry<K, List<V>>> entrySet() {
|
||||
return wrappee.entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return wrappee.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this.wrappee.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return wrappee.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.springframework.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link MultiValueMap} that wraps a plain {@code Map}
|
||||
* (by default a {@link LinkedHashMap}, storing multiple values in a {@link LinkedList}.
|
||||
*
|
||||
* <p>This Map implementation is generally not thread-safe. It is primarily designed
|
||||
* for data structures exposed from request objects, for use in a single thread only.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V> {
|
||||
|
||||
private final Map<K, List<V>> targetMap;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new SimpleMultiValueMap that wraps the given target Map.
|
||||
* @param wrappee the target Map to wrap
|
||||
*/
|
||||
public LinkedMultiValueMap() {
|
||||
this.targetMap = new LinkedHashMap<K, List<V>>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SimpleMultiValueMap that wraps the given target Map.
|
||||
* <p>Note: The given Map will be used as active underlying Map.
|
||||
* Any changes in the underlying map will be reflected in the
|
||||
* MultiValueMap object, and vice versa.
|
||||
* @param targetMap the target Map to wrap
|
||||
*/
|
||||
public LinkedMultiValueMap(Map<K, List<V>> targetMap) {
|
||||
Assert.notNull(targetMap, "'targetMap' must not be null");
|
||||
this.targetMap = targetMap;
|
||||
}
|
||||
|
||||
// MultiValueMap implementation
|
||||
|
||||
public void add(K key, V value) {
|
||||
List<V> values = this.targetMap.get(key);
|
||||
if (values == null) {
|
||||
values = new LinkedList<V>();
|
||||
this.targetMap.put(key, values);
|
||||
}
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
public V getFirst(K key) {
|
||||
List<V> values = this.targetMap.get(key);
|
||||
return (values != null ? values.get(0) : null);
|
||||
}
|
||||
|
||||
public void set(K key, V value) {
|
||||
List<V> values = new LinkedList<V>();
|
||||
values.add(value);
|
||||
this.targetMap.put(key, values);
|
||||
}
|
||||
|
||||
|
||||
// Map implementation
|
||||
|
||||
public int size() {
|
||||
return this.targetMap.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.targetMap.isEmpty();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return this.targetMap.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
return this.targetMap.containsValue(value);
|
||||
}
|
||||
|
||||
public List<V> get(Object key) {
|
||||
return this.targetMap.get(key);
|
||||
}
|
||||
|
||||
public List<V> put(K key, List<V> value) {
|
||||
return this.targetMap.put(key, value);
|
||||
}
|
||||
|
||||
public List<V> remove(Object key) {
|
||||
return this.targetMap.remove(key);
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends List<V>> m) {
|
||||
this.targetMap.putAll(m);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.targetMap.clear();
|
||||
}
|
||||
|
||||
public Set<K> keySet() {
|
||||
return this.targetMap.keySet();
|
||||
}
|
||||
|
||||
public Collection<List<V>> values() {
|
||||
return this.targetMap.values();
|
||||
}
|
||||
|
||||
public Set<Entry<K, List<V>>> entrySet() {
|
||||
return this.targetMap.entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this.targetMap.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.targetMap.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.targetMap.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -28,25 +28,22 @@ import java.util.Map;
|
|||
public interface MultiValueMap<K, V> extends Map<K, List<V>> {
|
||||
|
||||
/**
|
||||
* Adds the given single value to the current list of values for the given key.
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value to be added
|
||||
*/
|
||||
void add(K key, V value);
|
||||
|
||||
/**
|
||||
* Returns the first value for the given key.
|
||||
*
|
||||
* Return the first value for the given key.
|
||||
* @param key the key
|
||||
* @return the first value for the specified key, or <code>null</code>
|
||||
*/
|
||||
V getFirst(K key);
|
||||
|
||||
/**
|
||||
* Sets the given single value under the given key.
|
||||
*
|
||||
* @param key the key
|
||||
* Add the given single value to the current list of values for the given key.
|
||||
* @param key the key
|
||||
* @param value the value to be added
|
||||
*/
|
||||
void add(K key, V value);
|
||||
|
||||
/**
|
||||
* Set the given single value under the given key.
|
||||
* @param key the key
|
||||
* @param value the value to set
|
||||
*/
|
||||
void set(K key, V value);
|
||||
|
|
|
@ -29,13 +29,13 @@ import org.junit.Test;
|
|||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class DefaultMultiValueMapTests {
|
||||
public class LinkedMultiValueMapTests {
|
||||
|
||||
private DefaultMultiValueMap<String, String> map;
|
||||
private LinkedMultiValueMap<String, String> map;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
map = new DefaultMultiValueMap<String, String>();
|
||||
map = new LinkedMultiValueMap<String, String>();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -71,7 +71,7 @@ public class DefaultMultiValueMapTests {
|
|||
public void equals() {
|
||||
map.set("key1", "value1");
|
||||
assertEquals(map, map);
|
||||
MultiValueMap<String, String> o1 = new DefaultMultiValueMap<String, String>();
|
||||
MultiValueMap<String, String> o1 = new LinkedMultiValueMap<String, String>();
|
||||
o1.set("key1", "value1");
|
||||
assertEquals(map, o1);
|
||||
assertEquals(o1, map);
|
||||
|
@ -80,4 +80,5 @@ public class DefaultMultiValueMapTests {
|
|||
assertEquals(map, o2);
|
||||
assertEquals(o2, map);
|
||||
}
|
||||
|
||||
}
|
|
@ -39,7 +39,7 @@ import org.springframework.core.io.ClassPathResource;
|
|||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.servlet.View;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
|
@ -31,7 +31,6 @@ import java.util.Set;
|
|||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
@ -39,16 +38,18 @@ import org.springframework.util.StringUtils;
|
|||
* Represents HTTP request and response headers, mapping string header names to list of string values.
|
||||
*
|
||||
* <p>In addition to the normal methods defined by {@link Map}, this class offers the following convenience methods:
|
||||
* <ul> <li>{@link #getFirst(String)} returns the first value associated with a given header name</li> <li>{@link
|
||||
* #add(String, String)} adds a header value to the list of values for a header name</li> <li>{@link #set(String,
|
||||
* String)} sets the header value to a single string value</li> </ul>
|
||||
* <ul>
|
||||
* <li>{@link #getFirst(String)} returns the first value associated with a given header name</li>
|
||||
* <li>{@link #add(String, String)} adds a header value to the list of values for a header name</li>
|
||||
* <li>{@link #set(String, String)} sets the header value to a single string value</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Inspired by {@link com.sun.net.httpserver.Headers}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
*/
|
||||
public final class HttpHeaders implements MultiValueMap<String, String> {
|
||||
public class HttpHeaders implements MultiValueMap<String, String> {
|
||||
|
||||
private static String ACCEPT = "Accept";
|
||||
|
||||
|
@ -62,23 +63,12 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
|
||||
private static String LOCATION = "Location";
|
||||
|
||||
private Map<String, List<String>> headers = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(5);
|
||||
|
||||
private final Map<String, List<String>> headers = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(5);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of acceptable {@linkplain MediaType media types}, as specified by the <code>Accept</code> header.
|
||||
*
|
||||
* <p>Returns an empty list when the acceptable media types are unspecified.
|
||||
*
|
||||
* @return the acceptable media types
|
||||
*/
|
||||
public List<MediaType> getAccept() {
|
||||
String value = getFirst(ACCEPT);
|
||||
return value != null ? MediaType.parseMediaTypes(value) : Collections.<MediaType>emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of acceptable {@linkplain MediaType media types}, as specified by the <code>Accept</code> header.
|
||||
*
|
||||
* Set the list of acceptable {@linkplain MediaType media types}, as specified by the <code>Accept</code> header.
|
||||
* @param acceptableMediaTypes the acceptable media types
|
||||
*/
|
||||
public void setAccept(List<MediaType> acceptableMediaTypes) {
|
||||
|
@ -86,9 +76,34 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the list of acceptable {@linkplain Charset charsets}, as specified by the <code>Accept-Charset</code>
|
||||
* Return the list of acceptable {@linkplain MediaType media types}, as specified by the <code>Accept</code> header.
|
||||
* <p>Returns an empty list when the acceptable media types are unspecified.
|
||||
* @return the acceptable media types
|
||||
*/
|
||||
public List<MediaType> getAccept() {
|
||||
String value = getFirst(ACCEPT);
|
||||
return (value != null ? MediaType.parseMediaTypes(value) : Collections.<MediaType>emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of acceptable {@linkplain Charset charsets}, as specified by the <code>Accept-Charset</code> header.
|
||||
* @param acceptableCharsets the acceptable charsets
|
||||
*/
|
||||
public void setAcceptCharset(List<Charset> acceptableCharsets) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Iterator<Charset> iterator = acceptableCharsets.iterator(); iterator.hasNext();) {
|
||||
Charset charset = iterator.next();
|
||||
builder.append(charset.name().toLowerCase(Locale.ENGLISH));
|
||||
if (iterator.hasNext()) {
|
||||
builder.append(", ");
|
||||
}
|
||||
}
|
||||
set(ACCEPT_CHARSET, builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of acceptable {@linkplain Charset charsets}, as specified by the <code>Accept-Charset</code>
|
||||
* header.
|
||||
*
|
||||
* @return the acceptable charsets
|
||||
*/
|
||||
public List<Charset> getAcceptCharset() {
|
||||
|
@ -110,29 +125,19 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the list of acceptable {@linkplain Charset charsets}, as specified by the <code>Accept-Charset</code> header.
|
||||
*
|
||||
* @param acceptableCharsets the acceptable charsets
|
||||
* Set the set of allowed {@link HttpMethod HTTP methods}, as specified by the <code>Allow</code> header.
|
||||
* @param allowedMethods the allowed methods
|
||||
*/
|
||||
public void setAcceptCharset(List<Charset> acceptableCharsets) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Iterator<Charset> iterator = acceptableCharsets.iterator(); iterator.hasNext();) {
|
||||
Charset charset = iterator.next();
|
||||
builder.append(charset.name().toLowerCase(Locale.ENGLISH));
|
||||
if (iterator.hasNext()) {
|
||||
builder.append(", ");
|
||||
}
|
||||
}
|
||||
set(ACCEPT_CHARSET, builder.toString());
|
||||
public void setAllow(Set<HttpMethod> allowedMethods) {
|
||||
set(ALLOW, StringUtils.collectionToCommaDelimitedString(allowedMethods));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of allowed {@link HttpMethod HTTP methods}, as specified by the <code>Allow</code> header. <p/>
|
||||
* Returns an empty set when the allowed methods are unspecified.
|
||||
*
|
||||
* Return the set of allowed {@link HttpMethod HTTP methods}, as specified by the <code>Allow</code> header.
|
||||
* <p>Returns an empty set when the allowed methods are unspecified.
|
||||
* @return the allowed methods
|
||||
*/
|
||||
public EnumSet<HttpMethod> getAllow() {
|
||||
public Set<HttpMethod> getAllow() {
|
||||
String value = getFirst(ALLOW);
|
||||
if (value != null) {
|
||||
List<HttpMethod> allowedMethod = new ArrayList<HttpMethod>(5);
|
||||
|
@ -148,28 +153,7 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the set of allowed {@link HttpMethod HTTP methods}, as specified by the <code>Allow</code> header.
|
||||
*
|
||||
* @param allowedMethods the allowed methods
|
||||
*/
|
||||
public void setAllow(EnumSet<HttpMethod> allowedMethods) {
|
||||
set(ALLOW, StringUtils.collectionToCommaDelimitedString(allowedMethods));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the body in bytes, as specified by the <code>Content-Length</code> header. <p/> Returns -1
|
||||
* when the content-length is unknown.
|
||||
*
|
||||
* @return the content length
|
||||
*/
|
||||
public long getContentLength() {
|
||||
String value = getFirst(CONTENT_LENGTH);
|
||||
return value != null ? Long.parseLong(value) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of the body in bytes, as specified by the <code>Content-Length</code> header.
|
||||
*
|
||||
* Set the length of the body in bytes, as specified by the <code>Content-Length</code> header.
|
||||
* @param contentLength the content length
|
||||
*/
|
||||
public void setContentLength(long contentLength) {
|
||||
|
@ -177,19 +161,17 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@linkplain MediaType media type} of the body, as specified by the <code>Content-Type</code> header.
|
||||
* <p/> Returns <code>null</code> when the content-type is unknown.
|
||||
*
|
||||
* @return the content type
|
||||
* Return the length of the body in bytes, as specified by the <code>Content-Length</code> header.
|
||||
* <p>Returns -1 when the content-length is unknown.
|
||||
* @return the content length
|
||||
*/
|
||||
public MediaType getContentType() {
|
||||
String value = getFirst(CONTENT_TYPE);
|
||||
return value != null ? MediaType.parseMediaType(value) : null;
|
||||
public long getContentLength() {
|
||||
String value = getFirst(CONTENT_LENGTH);
|
||||
return (value != null ? Long.parseLong(value) : -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkplain MediaType media type} of the body, as specified by the <code>Content-Type</code> header.
|
||||
*
|
||||
* Set the {@linkplain MediaType media type} of the body, as specified by the <code>Content-Type</code> header.
|
||||
* @param mediaType the media type
|
||||
*/
|
||||
public void setContentType(MediaType mediaType) {
|
||||
|
@ -199,32 +181,38 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the (new) location of a resource, as specified by the <code>Location</code> header. <p/> Returns
|
||||
* <code>null</code> when the location is unknown.
|
||||
*
|
||||
* @return the location
|
||||
* Return the {@linkplain MediaType media type} of the body, as specified by the <code>Content-Type</code> header.
|
||||
* <p>Returns <code>null</code> when the content-type is unknown.
|
||||
* @return the content type
|
||||
*/
|
||||
public URI getLocation() {
|
||||
String value = getFirst(LOCATION);
|
||||
return value != null ? URI.create(value) : null;
|
||||
public MediaType getContentType() {
|
||||
String value = getFirst(CONTENT_TYPE);
|
||||
return (value != null ? MediaType.parseMediaType(value) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the (new) location of a resource, as specified by the <code>Location</code> header.
|
||||
*
|
||||
* Set the (new) location of a resource, as specified by the <code>Location</code> header.
|
||||
* @param location the location
|
||||
*/
|
||||
public void setLocation(URI location) {
|
||||
set(LOCATION, location.toASCIIString());
|
||||
}
|
||||
|
||||
/*
|
||||
* Single string methods
|
||||
/**
|
||||
* Return the (new) location of a resource, as specified by the <code>Location</code> header.
|
||||
* <p>Returns <code>null</code> when the location is unknown.
|
||||
* @return the location
|
||||
*/
|
||||
public URI getLocation() {
|
||||
String value = getFirst(LOCATION);
|
||||
return (value != null ? URI.create(value) : null);
|
||||
}
|
||||
|
||||
|
||||
// Single string methods
|
||||
|
||||
/**
|
||||
* Returns the first header value for the given header name, if any.
|
||||
*
|
||||
* Return the first header value for the given header name, if any.
|
||||
* @param headerName the header name
|
||||
* @return the first header value; or <code>null</code>
|
||||
*/
|
||||
|
@ -234,8 +222,7 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds the given, single header value under the given name.
|
||||
*
|
||||
* Add the given, single header value under the given name.
|
||||
* @param headerName the header name
|
||||
* @param headerValue the header value
|
||||
* @throws UnsupportedOperationException if adding headers is not supported
|
||||
|
@ -246,14 +233,13 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
List<String> headerValues = headers.get(headerName);
|
||||
if (headerValues == null) {
|
||||
headerValues = new LinkedList<String>();
|
||||
headers.put(headerName, headerValues);
|
||||
this.headers.put(headerName, headerValues);
|
||||
}
|
||||
headerValues.add(headerValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given, single header value under the given name.
|
||||
*
|
||||
* Set the given, single header value under the given name.
|
||||
* @param headerName the header name
|
||||
* @param headerValue the header value
|
||||
* @throws UnsupportedOperationException if adding headers is not supported
|
||||
|
@ -266,77 +252,77 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
|||
headers.put(headerName, headerValues);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map implementation
|
||||
*/
|
||||
|
||||
// Map implementation
|
||||
|
||||
public int size() {
|
||||
return headers.size();
|
||||
return this.headers.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return headers.isEmpty();
|
||||
return this.headers.isEmpty();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return headers.containsKey(key);
|
||||
return this.headers.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
return headers.containsValue(value);
|
||||
return this.headers.containsValue(value);
|
||||
}
|
||||
|
||||
public List<String> get(Object key) {
|
||||
return headers.get(key);
|
||||
return this.headers.get(key);
|
||||
}
|
||||
|
||||
public List<String> put(String key, List<String> value) {
|
||||
return headers.put(key, value);
|
||||
return this.headers.put(key, value);
|
||||
}
|
||||
|
||||
public List<String> remove(Object key) {
|
||||
return headers.remove(key);
|
||||
return this.headers.remove(key);
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends String, ? extends List<String>> m) {
|
||||
headers.putAll(m);
|
||||
this.headers.putAll(m);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
headers.clear();
|
||||
this.headers.clear();
|
||||
}
|
||||
|
||||
public Set<String> keySet() {
|
||||
return headers.keySet();
|
||||
return this.headers.keySet();
|
||||
}
|
||||
|
||||
public Collection<List<String>> values() {
|
||||
return headers.values();
|
||||
return this.headers.values();
|
||||
}
|
||||
|
||||
public Set<Entry<String, List<String>>> entrySet() {
|
||||
return headers.entrySet();
|
||||
return this.headers.entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof HttpHeaders)) {
|
||||
return false;
|
||||
}
|
||||
HttpHeaders otherHeaders = (HttpHeaders) other;
|
||||
return this.headers.equals(otherHeaders.headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return headers.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj != null && obj instanceof HttpHeaders) {
|
||||
HttpHeaders other = (HttpHeaders) obj;
|
||||
return this.headers.equals(other.headers);
|
||||
}
|
||||
return false;
|
||||
return this.headers.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return headers.toString();
|
||||
return this.headers.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -14,14 +14,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Represents a HTTP output message, consisting of {@linkplain #getHeaders() headers} and a readable {@linkplain
|
||||
* #getBody() body}. <p/> Typically implemented by a HTTP request on the server-side, or a response on the client-side.
|
||||
* Represents a HTTP output message, consisting of {@linkplain #getHeaders() headers}
|
||||
* and a readable {@linkplain #getBody() body}.
|
||||
*
|
||||
* <p>Typically implemented by a HTTP request on the server-side, or a response on the client-side.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
|
@ -29,8 +31,7 @@ import java.io.InputStream;
|
|||
public interface HttpInputMessage extends HttpMessage {
|
||||
|
||||
/**
|
||||
* Returns the body of the message as an input stream.
|
||||
*
|
||||
* Return the body of the message as an input stream.
|
||||
* @return the input stream body
|
||||
* @throws IOException in case of I/O Errors
|
||||
*/
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
/**
|
||||
* Represents the base interface for HTTP request and response messages. Consists of {@link HttpHeaders}, retrievable
|
||||
|
@ -26,9 +26,9 @@ package org.springframework.web.http;
|
|||
public interface HttpMessage {
|
||||
|
||||
/**
|
||||
* Returns the headers of this message.
|
||||
*
|
||||
* @return the headers
|
||||
* Return the headers of this message.
|
||||
* @return a corresponding HttpHeaders object
|
||||
*/
|
||||
HttpHeaders getHeaders();
|
||||
|
||||
}
|
|
@ -14,13 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
/**
|
||||
* Java 5 enumeration of HTTP request methods.
|
||||
* Java 5 enumeration of HTTP request methods. Intended for use
|
||||
* with {@link org.springframework.http.client.ClientHttpRequest}
|
||||
* and {@link org.springframework.web.client.RestTemplate}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.web.bind.annotation.RequestMapping
|
||||
* @since 3.0
|
||||
*/
|
||||
public enum HttpMethod {
|
|
@ -14,14 +14,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Represents a HTTP output message, consisting of {@linkplain #getHeaders() headers} and a writable {@linkplain
|
||||
* #getBody() body}. <p/> Typically implemented by a HTTP request on the client-side, or a response on the server-side.
|
||||
* Represents a HTTP output message, consisting of {@linkplain #getHeaders() headers}
|
||||
* and a writable {@linkplain #getBody() body}.
|
||||
*
|
||||
* <p>Typically implemented by a HTTP request on the client-side, or a response on the server-side.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
|
@ -29,8 +31,7 @@ import java.io.OutputStream;
|
|||
public interface HttpOutputMessage extends HttpMessage {
|
||||
|
||||
/**
|
||||
* Returns the body of the message as an output stream.
|
||||
*
|
||||
* Return the body of the message as an output stream.
|
||||
* @return the output stream body
|
||||
* @throws IOException in case of I/O Errors
|
||||
*/
|
|
@ -14,10 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
/**
|
||||
* Java 5 enumeration of HTTP status codes. <p/> The HTTP status code series can be retrieved via {@link #series()}.
|
||||
* Java 5 enumeration of HTTP status codes.
|
||||
*
|
||||
* <p>The HTTP status code series can be retrieved via {@link #series()}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see HttpStatus.Series
|
||||
|
@ -79,10 +81,59 @@ public enum HttpStatus {
|
|||
GATEWAY_TIMEOUT(504),
|
||||
HTTP_VERSION_NOT_SUPPORTED(505);
|
||||
|
||||
|
||||
private final int value;
|
||||
|
||||
|
||||
private HttpStatus(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Java 5 enumeration of HTTP status series. <p/> Retrievable via {@link HttpStatus#series()}.
|
||||
* Return the integer value of this status code.
|
||||
*/
|
||||
public enum Series {
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP status series of this status code.
|
||||
* @see HttpStatus.Series
|
||||
*/
|
||||
public Series series() {
|
||||
return Series.valueOf(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this status code.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Integer.toString(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the enum constant of this type with the specified numeric value.
|
||||
* @param statusCode the numeric value of the enum to be returned
|
||||
* @return the enum constant with the specified numeric value
|
||||
* @throws IllegalArgumentException if this enum has no constant for the specified numeric value
|
||||
*/
|
||||
public static HttpStatus valueOf(int statusCode) {
|
||||
for (HttpStatus status : values()) {
|
||||
if (status.value == statusCode) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No matching constant for [" + statusCode + "]");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Java 5 enumeration of HTTP status series.
|
||||
* <p>Retrievable via {@link HttpStatus#series()}.
|
||||
*/
|
||||
public static enum Series {
|
||||
|
||||
INFORMATIONAL(1),
|
||||
SUCCESSFUL(2),
|
||||
|
@ -97,12 +148,10 @@ public enum HttpStatus {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the integer value of this status series. Ranges from 1 to 5.
|
||||
*
|
||||
* @return the integer value
|
||||
* Return the integer value of this status series. Ranges from 1 to 5.
|
||||
*/
|
||||
public int value() {
|
||||
return value;
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static Series valueOf(HttpStatus status) {
|
||||
|
@ -117,55 +166,4 @@ public enum HttpStatus {
|
|||
|
||||
}
|
||||
|
||||
private final int value;
|
||||
|
||||
private HttpStatus(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the integer value of this status code.
|
||||
*
|
||||
* @return the integer value
|
||||
*/
|
||||
public int value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP status series of this status code.
|
||||
*
|
||||
* @return the series
|
||||
* @see HttpStatus.Series
|
||||
*/
|
||||
public Series series() {
|
||||
return Series.valueOf(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the enum constant of this type with the specified numeric value.
|
||||
*
|
||||
* @param statusCode the numeric value of the enum to be returned
|
||||
* @return the enum constant with the specified numeric value
|
||||
* @throws IllegalArgumentException if this enum has no constant for the specified numeric value
|
||||
*/
|
||||
public static HttpStatus valueOf(int statusCode) {
|
||||
for (HttpStatus status : values()) {
|
||||
if (status.value == statusCode) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No matching constant for [" + statusCode + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this status code.
|
||||
*
|
||||
* @return a string representation
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Integer.toString(value);
|
||||
}
|
||||
|
||||
}
|
|
@ -14,10 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.util;
|
||||
package org.springframework.http;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -26,27 +27,32 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Represents an Internet Media Type, as defined in the HTTP specification.
|
||||
*
|
||||
* <p>Consists of a {@linkplain #getType() type} and a {@linkplain #getSubtype() subtype}. Also has functionality to
|
||||
* parse media types from a string using {@link #parseMediaType(String)}, or multiple comma-separated media types using
|
||||
* {@link #parseMediaTypes(String)}.
|
||||
* <p>Consists of a {@linkplain #getType() type} and a {@linkplain #getSubtype() subtype}.
|
||||
* Also has functionality to parse media types from a string using {@link #parseMediaType(String)},
|
||||
* or multiple comma-separated media types using {@link #parseMediaTypes(String)}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7">HTTP 1.1</a>
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7">HTTP 1.1</a>
|
||||
*/
|
||||
public final class MediaType implements Comparable<MediaType> {
|
||||
public class MediaType implements Comparable<MediaType> {
|
||||
|
||||
public static final MediaType ALL = new MediaType();
|
||||
public static final MediaType ALL = new MediaType("*", "*");
|
||||
|
||||
private static final String WILDCARD_TYPE = "*";
|
||||
|
||||
private static final String PARAM_QUALITY_FACTORY = "q";
|
||||
|
||||
private static final String PARAM_CHARSET = "charset";
|
||||
|
||||
private static final String WILDCARD_TYPE = "*";
|
||||
|
||||
private final String type;
|
||||
|
||||
|
@ -54,19 +60,10 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
|
||||
private final Map<String, String> parameters;
|
||||
|
||||
/**
|
||||
* Private constructor that creates a new {@link MediaType} representing <code>*/*</code>.
|
||||
*
|
||||
* @see #ALL
|
||||
*/
|
||||
private MediaType() {
|
||||
this(WILDCARD_TYPE, WILDCARD_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link MediaType} for the given primary type. The {@linkplain #getSubtype() subtype} is set to
|
||||
* <code>*</code>, parameters empty.
|
||||
*
|
||||
* Create a new {@link MediaType} for the given primary type.
|
||||
* <p>The {@linkplain #getSubtype() subtype} is set to <code>*</code>, parameters empty.
|
||||
* @param type the primary type
|
||||
*/
|
||||
public MediaType(String type) {
|
||||
|
@ -74,9 +71,9 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link MediaType} for the given primary type and subtype. The parameters are empty.
|
||||
*
|
||||
* @param type the primary type
|
||||
* Create a new {@link MediaType} for the given primary type and subtype.
|
||||
* <p>The parameters are empty.
|
||||
* @param typethe primary type
|
||||
* @param subtype the subtype
|
||||
*/
|
||||
public MediaType(String type, String subtype) {
|
||||
|
@ -84,9 +81,8 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MediaType} for the given type, subtype, and character set.
|
||||
*
|
||||
* @param type the primary type
|
||||
* Create a new {@link MediaType} for the given type, subtype, and character set.
|
||||
* @param type the primary type
|
||||
* @param subtype the subtype
|
||||
* @param charSet the character set
|
||||
*/
|
||||
|
@ -95,10 +91,9 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MediaType} for the given type, subtype, and parameters.
|
||||
*
|
||||
* @param type the primary type
|
||||
* @param subtype the subtype
|
||||
* Create a new {@link MediaType} for the given type, subtype, and parameters.
|
||||
* @param type the primary type
|
||||
* @param subtype the subtype
|
||||
* @param parameters the parameters, mat be <code>null</code>
|
||||
*/
|
||||
public MediaType(String type, String subtype, Map<String, String> parameters) {
|
||||
|
@ -115,93 +110,30 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given string into a single {@link MediaType}.
|
||||
*
|
||||
* @param mediaType the string to parse
|
||||
* @return the media type
|
||||
* @throws IllegalArgumentException if the string cannot be parsed
|
||||
*/
|
||||
public static MediaType parseMediaType(String mediaType) {
|
||||
Assert.hasLength(mediaType, "'mediaType' must not be empty");
|
||||
String[] parts = StringUtils.tokenizeToStringArray(mediaType, ";");
|
||||
|
||||
Map<String, String> parameters;
|
||||
if (parts.length <= 1) {
|
||||
parameters = null;
|
||||
}
|
||||
else {
|
||||
parameters = new LinkedHashMap<String, String>(parts.length - 1);
|
||||
}
|
||||
for (int i = 1; i < parts.length; i++) {
|
||||
String part = parts[i];
|
||||
int idx = part.indexOf('=');
|
||||
if (idx != -1) {
|
||||
String name = part.substring(0, idx);
|
||||
String value = part.substring(idx + 1, part.length());
|
||||
parameters.put(name, value);
|
||||
}
|
||||
}
|
||||
String fullType = parts[0].trim();
|
||||
|
||||
// java.net.HttpURLConnection returns a *; q=.2 Accept header
|
||||
if (WILDCARD_TYPE.equals(fullType)) {
|
||||
fullType = "*/*";
|
||||
}
|
||||
int idx = fullType.indexOf('/');
|
||||
String type = fullType.substring(0, idx);
|
||||
String subtype = fullType.substring(idx + 1, fullType.length());
|
||||
return new MediaType(type, subtype, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given, comma-seperated string into a list of {@link MediaType} objects. This method can be used to parse
|
||||
* an Accept or Content-Type header.
|
||||
*
|
||||
* @param mediaTypes the string to parse
|
||||
* @return the list of media types
|
||||
* @throws IllegalArgumentException if the string cannot be parsed
|
||||
*/
|
||||
public static List<MediaType> parseMediaTypes(String mediaTypes) {
|
||||
Assert.hasLength(mediaTypes, "'mediaTypes' must not be empty");
|
||||
String[] tokens = mediaTypes.split(",\\s*");
|
||||
List<MediaType> result = new ArrayList<MediaType>(tokens.length);
|
||||
for (String token : tokens) {
|
||||
result.add(parseMediaType(token));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the primary type.
|
||||
*
|
||||
* @return the type
|
||||
* Return the primary type.
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the {@linkplain #getType() type} is the wildcard character <code>*</code> or not.
|
||||
*
|
||||
* @return whether the type is <code>*</code>
|
||||
* Indicate whether the {@linkplain #getType() type} is the wildcard character <code>*</code> or not.
|
||||
*/
|
||||
public boolean isWildcardType() {
|
||||
return WILDCARD_TYPE.equals(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subtype.
|
||||
*
|
||||
* @return the subtype
|
||||
* Return the subtype.
|
||||
*/
|
||||
public String getSubtype() {
|
||||
return subtype;
|
||||
return this.subtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the {@linkplain #getSubtype() subtype} is the wildcard character <code>*</code> or not.
|
||||
*
|
||||
* Indicate whether the {@linkplain #getSubtype() subtype} is the wildcard character <code>*</code> or not.
|
||||
* @return whether the subtype is <code>*</code>
|
||||
*/
|
||||
public boolean isWildcardSubtype() {
|
||||
|
@ -209,39 +141,37 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the character set, as indicated by a <code>charset</code> parameter, if any.
|
||||
*
|
||||
* Return the character set, as indicated by a <code>charset</code> parameter, if any.
|
||||
* @return the character set; or <code>null</code> if not available
|
||||
*/
|
||||
public Charset getCharSet() {
|
||||
String charSet = parameters.get(PARAM_CHARSET);
|
||||
return charSet != null ? Charset.forName(charSet) : null;
|
||||
String charSet = this.parameters.get(PARAM_CHARSET);
|
||||
return (charSet != null ? Charset.forName(charSet) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quality value, as indicated by a <code>q</code> parameter, if any. Defaults to <code>1.0</code>.
|
||||
*
|
||||
* Return the quality value, as indicated by a <code>q</code> parameter, if any. Defaults to <code>1.0</code>.
|
||||
* @return the quality factory
|
||||
*/
|
||||
public double getQualityValue() {
|
||||
String qualityFactory = parameters.get(PARAM_QUALITY_FACTORY);
|
||||
return qualityFactory != null ? Double.parseDouble(qualityFactory) : 1D;
|
||||
String qualityFactory = this.parameters.get(PARAM_QUALITY_FACTORY);
|
||||
return (qualityFactory != null ? Double.parseDouble(qualityFactory) : 1D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a generic parameter value, given a parameter name.
|
||||
*
|
||||
* Return a generic parameter value, given a parameter name.
|
||||
* @param name the parameter name
|
||||
* @return the parameter value; or <code>null</code> if not present
|
||||
*/
|
||||
public String getParameter(String name) {
|
||||
return parameters.get(name);
|
||||
return this.parameters.get(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether this {@link MediaType} includes the given media type. For instance, <code>text/*</code> includes
|
||||
* <code>text/plain</code>, <code>text/html</code>, etc.
|
||||
*
|
||||
* Indicate whether this {@link MediaType} includes the given media type.
|
||||
* <p>For instance, <code>text/*</code> includes <code>text/plain</code>,
|
||||
* <code>text/html</code>, etc.
|
||||
* @param other the reference media type with which to compare
|
||||
* @return <code>true</code> if this media type includes the given media type; <code>false</code> otherwise
|
||||
*/
|
||||
|
@ -258,14 +188,13 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Compares this {@link MediaType} to another. Sorting with this comparator follows the general rule: <blockquote>
|
||||
* Compare this {@link MediaType} to another. Sorting with this comparator follows the general rule: <blockquote>
|
||||
* audio/basic < audio/* < */* </blockquote>. That is, an explicit media type is sorted before an unspecific
|
||||
* media type. Quality parameters are also considered, so that <blockquote> audio/* < audio/*;q=0.7;
|
||||
* audio/*;q=0.3</blockquote>.
|
||||
*
|
||||
* @param other the media type to compare to
|
||||
* @return a negative integer, zero, or a positive integer as this media type is less than, equal to, or greater than
|
||||
* the specified media type
|
||||
* @return a negative integer, zero, or a positive integer as this media type is less than, equal to,
|
||||
* or greater than the specified media type
|
||||
*/
|
||||
public int compareTo(MediaType other) {
|
||||
double qVal1 = this.getQualityValue();
|
||||
|
@ -303,23 +232,23 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (o != null && o instanceof MediaType) {
|
||||
MediaType other = (MediaType) o;
|
||||
return this.type.equals(other.type) && this.subtype.equals(other.subtype) &&
|
||||
this.parameters.equals(other.parameters);
|
||||
if (!(other instanceof MediaType)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
MediaType otherType = (MediaType) other;
|
||||
return (this.type.equals(otherType.type) && this.subtype.equals(otherType.subtype) &&
|
||||
this.parameters.equals(otherType.parameters));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = type.hashCode();
|
||||
result = 31 * result + subtype.hashCode();
|
||||
result = 31 * result + parameters.hashCode();
|
||||
int result = this.type.hashCode();
|
||||
result = 31 * result + this.subtype.hashCode();
|
||||
result = 31 * result + this.parameters.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -330,15 +259,82 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
return builder.toString();
|
||||
}
|
||||
|
||||
private void appendTo(StringBuilder builder) {
|
||||
builder.append(this.type);
|
||||
builder.append('/');
|
||||
builder.append(this.subtype);
|
||||
for (Map.Entry<String, String> entry :this. parameters.entrySet()) {
|
||||
builder.append(';');
|
||||
builder.append(entry.getKey());
|
||||
builder.append('=');
|
||||
builder.append(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of the given list of {@link MediaType} objects. This method can be used to for an
|
||||
* Accept or Content-Type header.
|
||||
*
|
||||
* Parse the given String into a single {@link MediaType}.
|
||||
* @param mediaType the string to parse
|
||||
* @return the media type
|
||||
* @throws IllegalArgumentException if the string cannot be parsed
|
||||
*/
|
||||
public static MediaType parseMediaType(String mediaType) {
|
||||
Assert.hasLength(mediaType, "'mediaType' must not be empty");
|
||||
String[] parts = StringUtils.tokenizeToStringArray(mediaType, ";");
|
||||
|
||||
Map<String, String> parameters;
|
||||
if (parts.length <= 1) {
|
||||
parameters = null;
|
||||
}
|
||||
else {
|
||||
parameters = new LinkedHashMap<String, String>(parts.length - 1);
|
||||
}
|
||||
for (int i = 1; i < parts.length; i++) {
|
||||
String part = parts[i];
|
||||
int idx = part.indexOf('=');
|
||||
if (idx != -1) {
|
||||
String name = part.substring(0, idx);
|
||||
String value = part.substring(idx + 1, part.length());
|
||||
parameters.put(name, value);
|
||||
}
|
||||
}
|
||||
String fullType = parts[0].trim();
|
||||
|
||||
// java.net.HttpURLConnection returns a *; q=.2 Accept header
|
||||
if (WILDCARD_TYPE.equals(fullType)) {
|
||||
fullType = "*/*";
|
||||
}
|
||||
int idx = fullType.indexOf('/');
|
||||
String type = fullType.substring(0, idx);
|
||||
String subtype = fullType.substring(idx + 1, fullType.length());
|
||||
return new MediaType(type, subtype, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given, comma-seperated string into a list of {@link MediaType} objects.
|
||||
* <p>This method can be used to parse an Accept or Content-Type header.
|
||||
* @param mediaTypes the string to parse
|
||||
* @return the list of media types
|
||||
* @throws IllegalArgumentException if the string cannot be parsed
|
||||
*/
|
||||
public static String toString(List<MediaType> mediaTypes) {
|
||||
public static List<MediaType> parseMediaTypes(String mediaTypes) {
|
||||
Assert.hasLength(mediaTypes, "'mediaTypes' must not be empty");
|
||||
String[] tokens = mediaTypes.split(",\\s*");
|
||||
List<MediaType> result = new ArrayList<MediaType>(tokens.length);
|
||||
for (String token : tokens) {
|
||||
result.add(parseMediaType(token));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of the given list of {@link MediaType} objects.
|
||||
* <p>This method can be used to for an Accept or Content-Type header.
|
||||
* @param mediaTypes the string to parse
|
||||
* @return the list of media types
|
||||
* @throws IllegalArgumentException if the String cannot be parsed
|
||||
*/
|
||||
public static String toString(Collection<MediaType> mediaTypes) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Iterator<MediaType> iterator = mediaTypes.iterator(); iterator.hasNext();) {
|
||||
MediaType mediaType = iterator.next();
|
||||
|
@ -350,15 +346,4 @@ public final class MediaType implements Comparable<MediaType> {
|
|||
return builder.toString();
|
||||
}
|
||||
|
||||
private void appendTo(StringBuilder builder) {
|
||||
builder.append(type);
|
||||
builder.append('/');
|
||||
builder.append(subtype);
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
builder.append(';');
|
||||
builder.append(entry.getKey());
|
||||
builder.append('=');
|
||||
builder.append(entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.springframework.http;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link java.beans.PropertyEditor Editor} for {@link MediaType}
|
||||
* descriptors, to automatically convert <code>String</code> specifications
|
||||
* (e.g. <code>"text/html"</code>) to <code>MediaType</code> properties.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see MediaType
|
||||
*/
|
||||
public class MediaTypeEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) {
|
||||
if (StringUtils.hasText(text)) {
|
||||
setValue(MediaType.parseMediaType(text));
|
||||
}
|
||||
else {
|
||||
setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
MediaType mediaType = (MediaType) getValue();
|
||||
return (mediaType != null ? mediaType.toString() : "");
|
||||
}
|
||||
|
||||
}
|
|
@ -14,14 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* Abstract base for {@link ClientHttpRequest} that makes sure that headers and body are not written multiple times.
|
||||
|
@ -37,31 +37,36 @@ public abstract class AbstractClientHttpRequest implements ClientHttpRequest {
|
|||
|
||||
private final ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream();
|
||||
|
||||
|
||||
public final HttpHeaders getHeaders() {
|
||||
checkExecuted();
|
||||
return headers;
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
public final OutputStream getBody() throws IOException {
|
||||
checkExecuted();
|
||||
return bufferedOutput;
|
||||
return this.bufferedOutput;
|
||||
}
|
||||
|
||||
public final ClientHttpResponse execute() throws IOException {
|
||||
checkExecuted();
|
||||
ClientHttpResponse result = executeInternal(headers, bufferedOutput.toByteArray());
|
||||
executed = true;
|
||||
ClientHttpResponse result = executeInternal(this.headers, this.bufferedOutput.toByteArray());
|
||||
this.executed = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkExecuted() {
|
||||
Assert.state(!this.executed, "ClientHttpRequest already executed");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Abstract template method that writes the given headers and content to the HTTP request.
|
||||
* @param headers the HTTP headers
|
||||
* @param bufferedOutput the body content
|
||||
* @return the response object for the executed request
|
||||
*/
|
||||
protected abstract ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput)
|
||||
throws IOException;
|
||||
|
||||
private void checkExecuted() {
|
||||
Assert.state(!executed, "ClientRequest already executed");
|
||||
}
|
||||
|
||||
}
|
|
@ -14,33 +14,33 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.HttpOutputMessage;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
|
||||
/**
|
||||
* Represents a client-side HTTP request. Created via an implementation of the {@link ClientHttpRequestFactory}. <p/> A
|
||||
* <code>HttpRequest</code> can be {@linkplain #execute() executed}, getting a {@link ClientHttpResponse} which can be
|
||||
* read from.
|
||||
* Represents a client-side HTTP request. Created via an implementation of the {@link ClientHttpRequestFactory}.
|
||||
*
|
||||
* <p>A <code>HttpRequest</code> can be {@linkplain #execute() executed}, getting a {@link ClientHttpResponse}
|
||||
* which can be read from.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
* @see ClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
||||
*/
|
||||
public interface ClientHttpRequest extends HttpOutputMessage {
|
||||
|
||||
/**
|
||||
* Returns the HTTP method of the request.
|
||||
*
|
||||
* @return the HTTP method
|
||||
* Return the HTTP method of the request.
|
||||
* @return the HTTP method as an HttpMethod enum value
|
||||
*/
|
||||
HttpMethod getMethod();
|
||||
|
||||
/**
|
||||
* Executes this request, resulting in a {@link ClientHttpResponse} that can be read.
|
||||
*
|
||||
* Execute this request, resulting in a {@link ClientHttpResponse} that can be read.
|
||||
* @return the response result of the execution
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
|
@ -14,16 +14,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* Factory for {@link ClientHttpRequest} objects. Requests are created by the {@link #createRequest(URI, HttpMethod)}
|
||||
* method.
|
||||
* Factory for {@link ClientHttpRequest} objects.
|
||||
* Requests are created by the {@link #createRequest(URI, HttpMethod)} method.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
|
@ -31,10 +31,10 @@ import org.springframework.web.http.HttpMethod;
|
|||
public interface ClientHttpRequestFactory {
|
||||
|
||||
/**
|
||||
* Creates a new {@link ClientHttpRequest} for the specified URI and HTTP method. The returned request can be written
|
||||
* to, and then executed by calling {@link ClientHttpRequest#execute()}.
|
||||
*
|
||||
* @param uri the URI to create a request for
|
||||
* Create a new {@link ClientHttpRequest} for the specified URI and HTTP method.
|
||||
* <p>The returned request can be written to, and then executed by calling
|
||||
* {@link ClientHttpRequest#execute()}.
|
||||
* @param uri the URI to create a request for
|
||||
* @param httpMethod the HTTP method to execute
|
||||
* @return the created request
|
||||
* @throws IOException in case of I/O errors
|
|
@ -14,16 +14,18 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.web.http.HttpInputMessage;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* Represents a client-side HTTP response. Obtained via an calling of the {@link ClientHttpRequest#execute()}. <p/> A
|
||||
* <code>HttpResponse</code> must be {@linkplain #close() closed}, typically in a <code>finally</code> block.
|
||||
* Represents a client-side HTTP response. Obtained via an calling of the {@link ClientHttpRequest#execute()}.
|
||||
*
|
||||
* <p>A <code>ClientHttpResponse</code> must be {@linkplain #close() closed}, typically in a
|
||||
* <code>finally</code> block.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
|
@ -31,16 +33,14 @@ import org.springframework.web.http.HttpStatus;
|
|||
public interface ClientHttpResponse extends HttpInputMessage {
|
||||
|
||||
/**
|
||||
* Returns the HTTP status code of the response.
|
||||
*
|
||||
* @return the HTTP status
|
||||
* Return the HTTP status code of the response.
|
||||
* @return the HTTP status as an HttpStatus enum value
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
HttpStatus getStatusCode() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the HTTP status text of the response.
|
||||
*
|
||||
* Return the HTTP status text of the response.
|
||||
* @return the HTTP status text
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client.commons;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
@ -26,16 +26,19 @@ import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
|
|||
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
|
||||
import org.apache.commons.httpclient.methods.RequestEntity;
|
||||
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.client.AbstractClientHttpRequest;
|
||||
import org.springframework.web.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.AbstractClientHttpRequest;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.web.http.client.ClientHttpRequest} implementation that uses Commons Http Client to execute
|
||||
* requests. Created via the {@link CommonsClientHttpRequestFactory}.
|
||||
* {@link org.springframework.http.client.ClientHttpRequest} implementation that uses
|
||||
* Apache Commons HttpClient to execute requests.
|
||||
*
|
||||
* <p>Created via the {@link CommonsClientHttpRequestFactory}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
* @see CommonsClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
||||
*/
|
||||
final class CommonsClientHttpRequest extends AbstractClientHttpRequest {
|
||||
|
@ -44,7 +47,8 @@ final class CommonsClientHttpRequest extends AbstractClientHttpRequest {
|
|||
|
||||
private final HttpMethodBase httpMethod;
|
||||
|
||||
CommonsClientHttpRequest(HttpClient httpClient, HttpMethodBase httpMethod) {
|
||||
|
||||
public CommonsClientHttpRequest(HttpClient httpClient, HttpMethodBase httpMethod) {
|
||||
this.httpClient = httpClient;
|
||||
this.httpMethod = httpMethod;
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client.commons;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -33,17 +33,18 @@ import org.apache.commons.httpclient.methods.TraceMethod;
|
|||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.client.ClientHttpRequest;
|
||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.web.http.client.ClientHttpRequestFactory} implementation that uses <a
|
||||
* href="http://jakarta.apache.org/commons/httpclient">Jakarta Commons HttpClient</a> to create requests. <p/> Allows to
|
||||
* use a pre-configured {@link HttpClient} instance, potentially with authentication, HTTP connection pooling, etc.
|
||||
* {@link org.springframework.http.client.ClientHttpRequestFactory} implementation that uses
|
||||
* <a href="http://jakarta.apache.org/commons/httpclient">Jakarta Commons HttpClient</a> to create requests.
|
||||
*
|
||||
* <p>Allows to use a pre-configured {@link HttpClient} instance -
|
||||
* potentially with authentication, HTTP connection pooling, etc.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.web.http.client.SimpleClientHttpRequestFactory
|
||||
* @since 3.0
|
||||
* @see org.springframework.http.client.SimpleClientHttpRequestFactory
|
||||
*/
|
||||
public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean {
|
||||
|
||||
|
@ -51,9 +52,10 @@ public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory
|
|||
|
||||
private HttpClient httpClient;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the <code>CommonsHttpRequestFactory</code> with a default {@link HttpClient} that uses a
|
||||
* default {@link MultiThreadedHttpConnectionManager}.
|
||||
* Create a new instance of the <code>CommonsHttpRequestFactory</code> with a default
|
||||
* {@link HttpClient} that uses a default {@link MultiThreadedHttpConnectionManager}.
|
||||
*/
|
||||
public CommonsClientHttpRequestFactory() {
|
||||
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
|
||||
|
@ -61,32 +63,32 @@ public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the <code>CommonsHttpRequestFactory</code> with the given {@link HttpClient} instance.
|
||||
*
|
||||
* @param httpClient the HttpClient instance to use for this sender
|
||||
* Create a new instance of the <code>CommonsHttpRequestFactory</code> with the given
|
||||
* {@link HttpClient} instance.
|
||||
* @param httpClient the HttpClient instance to use for this factory
|
||||
*/
|
||||
public CommonsClientHttpRequestFactory(HttpClient httpClient) {
|
||||
Assert.notNull(httpClient, "httpClient must not be null");
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>HttpClient</code> used by this message sender.
|
||||
*/
|
||||
public HttpClient getHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the <code>HttpClient</code> used by this message sender.
|
||||
* Set the <code>HttpClient</code> used by this factory.
|
||||
*/
|
||||
public void setHttpClient(HttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the <code>HttpClient</code> used by this factory.
|
||||
*/
|
||||
public HttpClient getHttpClient() {
|
||||
return this.httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the socket read timeout for the underlying HttpClient. A value of 0 means <em>never</em> timeout.
|
||||
*
|
||||
* @param timeout the timeout value in milliseconds
|
||||
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)
|
||||
*/
|
||||
|
@ -97,52 +99,59 @@ public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory
|
|||
this.httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout);
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
|
||||
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
||||
HttpMethodBase commonsHttpMethod = createCommonsHttpMethod(httpMethod, uri.toString());
|
||||
postProcessCommonsHttpMethod(commonsHttpMethod);
|
||||
return new CommonsClientHttpRequest(getHttpClient(), commonsHttpMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Commons HttpMethodBase object for the given HTTP method
|
||||
* and URI specification.
|
||||
* @param httpMethod the HTTP method
|
||||
* @param uri the URI
|
||||
* @return the Commons HttpMethodBase object
|
||||
*/
|
||||
protected HttpMethodBase createCommonsHttpMethod(HttpMethod httpMethod, String uri) {
|
||||
switch (httpMethod) {
|
||||
case GET:
|
||||
return new GetMethod(uri);
|
||||
case DELETE:
|
||||
return new DeleteMethod(uri);
|
||||
case HEAD:
|
||||
return new HeadMethod(uri);
|
||||
case OPTIONS:
|
||||
return new OptionsMethod(uri);
|
||||
case POST:
|
||||
return new PostMethod(uri);
|
||||
case PUT:
|
||||
return new PutMethod(uri);
|
||||
case TRACE:
|
||||
return new TraceMethod(uri);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid HTTP method: " + httpMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method that allows for manipulating the {@link org.apache.commons.httpclient.HttpMethodBase}
|
||||
* before it is returned as part of a {@link CommonsClientHttpRequest}.
|
||||
* <p>The default implementation is empty.
|
||||
* @param httpMethod the Commons HTTP method object to process
|
||||
*/
|
||||
protected void postProcessCommonsHttpMethod(HttpMethodBase httpMethod) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown hook that closes the underlying {@link HttpConnectionManager}'s
|
||||
* connection pool, if any.
|
||||
*/
|
||||
public void destroy() {
|
||||
HttpConnectionManager connectionManager = getHttpClient().getHttpConnectionManager();
|
||||
if (connectionManager instanceof MultiThreadedHttpConnectionManager) {
|
||||
((MultiThreadedHttpConnectionManager) connectionManager).shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
||||
String uriString = uri.toString();
|
||||
HttpMethodBase httpMethodBase;
|
||||
switch (httpMethod) {
|
||||
case GET:
|
||||
httpMethodBase = new GetMethod(uriString);
|
||||
break;
|
||||
case DELETE:
|
||||
httpMethodBase = new DeleteMethod(uriString);
|
||||
break;
|
||||
case HEAD:
|
||||
httpMethodBase = new HeadMethod(uriString);
|
||||
break;
|
||||
case OPTIONS:
|
||||
httpMethodBase = new OptionsMethod(uriString);
|
||||
break;
|
||||
case POST:
|
||||
httpMethodBase = new PostMethod(uriString);
|
||||
break;
|
||||
case PUT:
|
||||
httpMethodBase = new PutMethod(uriString);
|
||||
break;
|
||||
case TRACE:
|
||||
httpMethodBase = new TraceMethod(uriString);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid method: " + httpMethod);
|
||||
}
|
||||
process(httpMethodBase);
|
||||
|
||||
return new CommonsClientHttpRequest(getHttpClient(), httpMethodBase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method that allows for manipulating the {@link org.apache.commons.httpclient.HttpMethodBase} before it is
|
||||
* returned as part of a {@link CommonsClientHttpRequest}. <p/> Default implementation is empty.
|
||||
*
|
||||
* @param httpMethod the Commons HTTP method to process
|
||||
*/
|
||||
protected void process(HttpMethodBase httpMethod) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client.commons;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -22,15 +22,18 @@ import java.io.InputStream;
|
|||
import org.apache.commons.httpclient.Header;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.web.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.web.http.client.ClientHttpResponse} implementation that uses Commons Http Client to
|
||||
* execute requests. Created via the {@link CommonsClientHttpRequest}.
|
||||
* {@link org.springframework.http.client.ClientHttpResponse} implementation that uses
|
||||
* Apache Commons HttpClient to execute requests.
|
||||
*
|
||||
* <p>Created via the {@link CommonsClientHttpRequest}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
* @see CommonsClientHttpRequest#execute()
|
||||
*/
|
||||
final class CommonsClientHttpResponse implements ClientHttpResponse {
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
|
@ -22,27 +22,29 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* {@link ClientHttpRequest} implementation that uses standard J2SE facilities to execute requests. Created via the
|
||||
* {@link SimpleClientHttpRequestFactory}.
|
||||
* {@link ClientHttpRequest} implementation that uses standard J2SE facilities to execute requests.
|
||||
* Created via the {@link SimpleClientHttpRequestFactory}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see SimpleClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
||||
* @since 3.0
|
||||
* @see SimpleClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
||||
*/
|
||||
final class SimpleClientHttpRequest extends AbstractClientHttpRequest {
|
||||
|
||||
private final HttpURLConnection connection;
|
||||
|
||||
SimpleClientHttpRequest(HttpURLConnection connection) {
|
||||
|
||||
public SimpleClientHttpRequest(HttpURLConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
|
||||
public HttpMethod getMethod() {
|
||||
return HttpMethod.valueOf(connection.getRequestMethod());
|
||||
return HttpMethod.valueOf(this.connection.getRequestMethod());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,12 +52,12 @@ final class SimpleClientHttpRequest extends AbstractClientHttpRequest {
|
|||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
for (String headerValue : entry.getValue()) {
|
||||
connection.addRequestProperty(headerName, headerValue);
|
||||
this.connection.addRequestProperty(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
connection.connect();
|
||||
FileCopyUtils.copy(bufferedOutput, connection.getOutputStream());
|
||||
return new SimpleClientHttpResponse(connection);
|
||||
this.connection.connect();
|
||||
FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
|
||||
return new SimpleClientHttpResponse(this.connection);
|
||||
}
|
||||
|
||||
}
|
|
@ -14,30 +14,28 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* {@link ClientHttpRequestFactory} implementation that uses standard J2SE facilities.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see java.net.HttpURLConnection
|
||||
* @see org.springframework.web.http.client.commons.CommonsClientHttpRequestFactory
|
||||
* @since 3.0
|
||||
* @see java.net.HttpURLConnection
|
||||
* @see CommonsClientHttpRequestFactory
|
||||
*/
|
||||
public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory {
|
||||
|
||||
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
||||
URL url = uri.toURL();
|
||||
URLConnection urlConnection = url.openConnection();
|
||||
URLConnection urlConnection = uri.toURL().openConnection();
|
||||
Assert.isInstanceOf(HttpURLConnection.class, urlConnection);
|
||||
HttpURLConnection connection = (HttpURLConnection) urlConnection;
|
||||
prepareConnection(connection, httpMethod.name());
|
||||
|
@ -46,9 +44,7 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory
|
|||
|
||||
/**
|
||||
* Template method for preparing the given {@link HttpURLConnection}.
|
||||
*
|
||||
* <p>Default implementation prepares the connection for input and output, and sets the HTTP method.
|
||||
*
|
||||
* <p>The default implementation prepares the connection for input and output, and sets the HTTP method.
|
||||
* @param connection the connection to prepare
|
||||
* @param httpMethod the HTTP request method ({@code GET}, {@code POST}, etc.)
|
||||
* @throws IOException in case of I/O errors
|
|
@ -14,19 +14,19 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* {@link ClientHttpResponse} implementation that uses standard J2SE facilities. Obtained via the {@link
|
||||
* SimpleClientHttpRequest#execute()}.
|
||||
* {@link ClientHttpResponse} implementation that uses standard J2SE facilities.
|
||||
* Obtained via the {@link SimpleClientHttpRequest#execute()}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
|
@ -37,45 +37,44 @@ final class SimpleClientHttpResponse implements ClientHttpResponse {
|
|||
|
||||
private HttpHeaders headers;
|
||||
|
||||
SimpleClientHttpResponse(HttpURLConnection connection) {
|
||||
|
||||
public SimpleClientHttpResponse(HttpURLConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
|
||||
public HttpStatus getStatusCode() throws IOException {
|
||||
return HttpStatus.valueOf(connection.getResponseCode());
|
||||
return HttpStatus.valueOf(this.connection.getResponseCode());
|
||||
}
|
||||
|
||||
public String getStatusText() throws IOException {
|
||||
return connection.getResponseMessage();
|
||||
return this.connection.getResponseMessage();
|
||||
}
|
||||
|
||||
public HttpHeaders getHeaders() {
|
||||
if (headers == null) {
|
||||
headers = new HttpHeaders();
|
||||
if (this.headers == null) {
|
||||
this.headers = new HttpHeaders();
|
||||
// Header field 0 is the status line, so we start at 1
|
||||
int i = 1;
|
||||
while (true) {
|
||||
String name = connection.getHeaderFieldKey(i);
|
||||
String name = this.connection.getHeaderFieldKey(i);
|
||||
if (!StringUtils.hasLength(name)) {
|
||||
break;
|
||||
}
|
||||
headers.add(name, connection.getHeaderField(i));
|
||||
this.headers.add(name, this.connection.getHeaderField(i));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
public InputStream getBody() throws IOException {
|
||||
if (connection.getErrorStream() == null) {
|
||||
return connection.getInputStream();
|
||||
}
|
||||
else {
|
||||
return connection.getErrorStream();
|
||||
}
|
||||
InputStream errorStream = this.connection.getErrorStream();
|
||||
return (errorStream != null ? errorStream : this.connection.getInputStream());
|
||||
}
|
||||
|
||||
public void close() {
|
||||
connection.disconnect();
|
||||
this.connection.disconnect();
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.support;
|
||||
package org.springframework.http.client.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -23,19 +23,21 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.client.ClientHttpRequest;
|
||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.web.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
|
||||
/**
|
||||
* Base class for {@link org.springframework.web.client.core.RestTemplate} and other HTTP accessing gateway helpers, defining
|
||||
* common properties such as the {@link ClientHttpRequestFactory} to operate on.
|
||||
* <p/>
|
||||
* Not intended to be used directly. See {@link org.springframework.web.client.core.RestTemplate}.
|
||||
* Base class for {@link org.springframework.web.client.RestTemplate}
|
||||
* and other HTTP accessing gateway helpers, defining common properties
|
||||
* such as the {@link ClientHttpRequestFactory} to operate on.
|
||||
*
|
||||
* <p>Not intended to be used directly. See {@link org.springframework.web.client.RestTemplate}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.web.client.core.RestTemplate
|
||||
* @since 3.0
|
||||
* @see org.springframework.web.client.RestTemplate
|
||||
*/
|
||||
public abstract class HttpAccessor {
|
||||
|
||||
|
@ -46,15 +48,9 @@ public abstract class HttpAccessor {
|
|||
|
||||
private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||
|
||||
/**
|
||||
* Returns the request factory that this accessor uses for obtaining {@link ClientHttpRequest HttpRequests}
|
||||
*/
|
||||
public ClientHttpRequestFactory getRequestFactory() {
|
||||
return requestFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request factory that this accessor uses for obtaining {@link ClientHttpRequest HttpRequests}
|
||||
* Set the request factory that this accessor uses for obtaining {@link ClientHttpRequest HttpRequests}.
|
||||
*/
|
||||
public void setRequestFactory(ClientHttpRequestFactory requestFactory) {
|
||||
Assert.notNull(requestFactory, "'requestFactory' must not be null");
|
||||
|
@ -62,9 +58,16 @@ public abstract class HttpAccessor {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ClientHttpRequest} via this template's {@link ClientHttpRequestFactory}.
|
||||
*
|
||||
* @param url the URL to connect to
|
||||
* Return the request factory that this accessor uses for obtaining {@link ClientHttpRequest HttpRequests}.
|
||||
*/
|
||||
public ClientHttpRequestFactory getRequestFactory() {
|
||||
return this.requestFactory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link ClientHttpRequest} via this template's {@link ClientHttpRequestFactory}.
|
||||
* @param url the URL to connect to
|
||||
* @param method the HTTP method to exectute (GET, POST, etc.)
|
||||
* @return the created request
|
||||
* @throws IOException in case of I/O errors
|
||||
|
@ -76,4 +79,5 @@ public abstract class HttpAccessor {
|
|||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
This package provides generic HTTP support classes,
|
||||
to be used by higher-level classes like RestTemplate.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.converter;
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -26,69 +26,66 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpOutputMessage;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* Abstract base class for most {@link HttpMessageConverter} implementations.
|
||||
*
|
||||
* <p>This base class adds support for setting supported {@code MediaTypes}, through the {@link
|
||||
* #setSupportedMediaTypes(List) supportedMediaTypes} bean property. It also adds support for {@code Content-Type} and
|
||||
* {@code Content-Length} when writing to output messages.
|
||||
* #setSupportedMediaTypes(List) supportedMediaTypes} bean property. It also adds support for
|
||||
* {@code Content-Type} and {@code Content-Length} when writing to output messages.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConverter<T> {
|
||||
|
||||
/**
|
||||
* Logger available to subclasses.
|
||||
*/
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private List<MediaType> supportedMediaTypes = Collections.emptyList();
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an {@code AbstractHttpMessageConverter} with no supported media types.
|
||||
*
|
||||
* @see #setSupportedMediaTypes(List)
|
||||
* Construct an {@code AbstractHttpMessageConverter} with no supported media types.
|
||||
* @see #setSupportedMediaTypes
|
||||
*/
|
||||
protected AbstractHttpMessageConverter() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code AbstractHttpMessageConverter} with one supported media type.
|
||||
* Construct an {@code AbstractHttpMessageConverter} with one supported media type.
|
||||
*/
|
||||
protected AbstractHttpMessageConverter(MediaType supportedMediaType) {
|
||||
setSupportedMediaTypes(Collections.singletonList(supportedMediaType));
|
||||
this.supportedMediaTypes = Collections.singletonList(supportedMediaType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code AbstractHttpMessageConverter} with multiple supported media type.
|
||||
* Construct an {@code AbstractHttpMessageConverter} with multiple supported media type.
|
||||
*/
|
||||
protected AbstractHttpMessageConverter(MediaType... supportedMediaTypes) {
|
||||
setSupportedMediaTypes(Arrays.asList(supportedMediaTypes));
|
||||
this.supportedMediaTypes = Arrays.asList(supportedMediaTypes);
|
||||
}
|
||||
|
||||
public List<MediaType> getSupportedMediaTypes() {
|
||||
return Collections.unmodifiableList(supportedMediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of {@link MediaType} objects supported by this converter.
|
||||
* Set the list of {@link MediaType} objects supported by this converter.
|
||||
*/
|
||||
public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes) {
|
||||
Assert.notEmpty(supportedMediaTypes, "'supportedMediaTypes' must not be empty");
|
||||
this.supportedMediaTypes = new ArrayList<MediaType>(supportedMediaTypes);
|
||||
}
|
||||
|
||||
public List<MediaType> getSupportedMediaTypes() {
|
||||
return Collections.unmodifiableList(this.supportedMediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation delegates to {@link #getContentType(Object)} and {@link #getContentLength(Object)}, and sets
|
||||
* the corresponding headers on the output message. It then calls {@link #writeToInternal(Object, HttpOutputMessage)}.
|
||||
*
|
||||
* <p>This implementation delegates to {@link #getContentType(Object)} and {@link #getContentLength(Object)},
|
||||
* and sets the corresponding headers on the output message. It then calls
|
||||
* {@link #writeToInternal(Object, HttpOutputMessage)}.
|
||||
* @throws HttpMessageConversionException in case of conversion errors
|
||||
*/
|
||||
public final void write(T t, HttpOutputMessage outputMessage) throws IOException {
|
||||
|
@ -107,23 +104,19 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
|
|||
|
||||
/**
|
||||
* Returns the content type for the given type.
|
||||
*
|
||||
* <p>By default, this returns the first element of the {@link #setSupportedMediaTypes(List) supportedMediaTypes}
|
||||
* property, if any. Can be overriden in subclasses.
|
||||
*
|
||||
* @param t the type to return the content type for
|
||||
* @return the content type, or <code>null</code> if not known
|
||||
*/
|
||||
protected MediaType getContentType(T t) {
|
||||
List<MediaType> mediaTypes = getSupportedMediaTypes();
|
||||
return !mediaTypes.isEmpty() ? mediaTypes.get(0) : null;
|
||||
return (!mediaTypes.isEmpty() ? mediaTypes.get(0) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content length for the given type.
|
||||
*
|
||||
* <p>By default, this returns <code>null</code>. Can be overriden in subclasses.
|
||||
*
|
||||
* @param t the type to return the content length for
|
||||
* @return the content length, or <code>null</code> if not known
|
||||
*/
|
||||
|
@ -133,10 +126,9 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
|
|||
|
||||
/**
|
||||
* Abstract template method that writes the actualy body. Invoked from {@link #write(Object, HttpOutputMessage)}.
|
||||
*
|
||||
* @param t the object to write to the output message
|
||||
* @param t the object to write to the output message
|
||||
* @param outputMessage the message to write to
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws HttpMessageConversionException in case of conversion errors
|
||||
*/
|
||||
protected abstract void writeToInternal(T t, HttpOutputMessage outputMessage) throws IOException;
|
|
@ -14,15 +14,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.converter;
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.http.HttpInputMessage;
|
||||
import org.springframework.web.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
|
||||
/**
|
||||
* Implementation of {@link HttpMessageConverter} that can read and write byte arrays.
|
||||
|
@ -45,7 +45,7 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<
|
|||
}
|
||||
|
||||
public boolean supports(Class<? extends byte[]> clazz) {
|
||||
return byte[].class == clazz;
|
||||
return byte[].class.equals(clazz);
|
||||
}
|
||||
|
||||
public byte[] read(Class<byte[]> clazz, HttpInputMessage inputMessage) throws IOException {
|
||||
|
@ -75,5 +75,4 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<
|
|||
FileCopyUtils.copy(bytes, outputMessage.getBody());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.converter;
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
|
@ -28,7 +28,6 @@ public class HttpMessageConversionException extends NestedRuntimeException {
|
|||
|
||||
/**
|
||||
* Create a new MessageConversionException.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public HttpMessageConversionException(String msg) {
|
||||
|
@ -37,11 +36,11 @@ public class HttpMessageConversionException extends NestedRuntimeException {
|
|||
|
||||
/**
|
||||
* Create a new MessageConversionException.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause (if any)
|
||||
*/
|
||||
public HttpMessageConversionException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -14,17 +14,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.converter;
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.http.HttpInputMessage;
|
||||
import org.springframework.web.http.HttpOutputMessage;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* Strategy interface that specifies a converter can convert from and to HTTP request and responses.
|
||||
* Strategy interface that specifies a converter can convert from and to HTTP requests and responses.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
|
@ -32,39 +32,34 @@ import org.springframework.web.http.HttpOutputMessage;
|
|||
public interface HttpMessageConverter<T> {
|
||||
|
||||
/**
|
||||
* Indicates whether the given class is supported by this converter.
|
||||
*
|
||||
* <p>Typically implemented using an {@code instanceof} check.
|
||||
*
|
||||
* Indicate whether the given class is supported by this converter.
|
||||
* @param clazz the class to test for support
|
||||
* @return <code>true</code> if supported; <code>false</code> otherwise
|
||||
*/
|
||||
boolean supports(Class<? extends T> clazz);
|
||||
|
||||
/**
|
||||
* Returns the list of {@link MediaType} objects supported by this converter.
|
||||
* Return the list of {@link MediaType} objects supported by this converter.
|
||||
*/
|
||||
List<MediaType> getSupportedMediaTypes();
|
||||
|
||||
/**
|
||||
* Reads an object of the given type form the given input message, and returns it.
|
||||
*
|
||||
* @param clazz the type of object to return
|
||||
* Read an object of the given type form the given input message, and returns it.
|
||||
* @param clazz the type of object to return
|
||||
* @param inputMessage the HTTP input message to read from
|
||||
* @return the converted object
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws HttpMessageConversionException in case of conversion errors
|
||||
*/
|
||||
T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes an given object to the given output message.
|
||||
*
|
||||
* @param t the object to write to the output message
|
||||
* Write an given object to the given output message.
|
||||
* @param t the object to write to the output message
|
||||
* @param outputMessage the message to write to
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws HttpMessageConversionException in case of conversion errors
|
||||
*/
|
||||
void write(T t, HttpOutputMessage outputMessage) throws IOException;
|
||||
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.converter;
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
@ -25,9 +25,9 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.http.HttpInputMessage;
|
||||
import org.springframework.web.http.HttpOutputMessage;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* Implementation of {@link HttpMessageConverter} that can read and write strings.
|
||||
|
@ -45,11 +45,13 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
|
|||
|
||||
private final List<Charset> availableCharsets;
|
||||
|
||||
|
||||
public StringHttpMessageConverter() {
|
||||
super(new MediaType("text", "plain", DEFAULT_CHARSET), new MediaType("text", "*"));
|
||||
availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
|
||||
this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
|
||||
}
|
||||
|
||||
|
||||
public boolean supports(Class<? extends String> clazz) {
|
||||
return String.class.equals(clazz);
|
||||
}
|
||||
|
@ -86,14 +88,12 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the list of supported {@link Charset}.
|
||||
*
|
||||
* Return the list of supported {@link Charset}.
|
||||
* <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses.
|
||||
*
|
||||
* @return the list of accepted charsets
|
||||
*/
|
||||
protected List<Charset> getAcceptedCharsets() {
|
||||
return availableCharsets;
|
||||
return this.availableCharsets;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Contains a basic abstraction over client/server-side HTTP. This package contains
|
||||
the <code>HttpInputMessage</code> and <code>HttpOutputMessage</code> interfaces.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -14,10 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.server;
|
||||
package org.springframework.http.server;
|
||||
|
||||
import org.springframework.web.http.HttpInputMessage;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* Represents a server-side HTTP request.
|
||||
|
@ -28,9 +28,8 @@ import org.springframework.web.http.HttpMethod;
|
|||
public interface ServerHttpRequest extends HttpInputMessage {
|
||||
|
||||
/**
|
||||
* Returns the HTTP method of the request.
|
||||
*
|
||||
* @return the http method
|
||||
* Return the HTTP method of the request.
|
||||
* @return the HTTP method as an HttpMethod enum value
|
||||
*/
|
||||
HttpMethod getMethod();
|
||||
|
|
@ -14,10 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.server;
|
||||
package org.springframework.http.server;
|
||||
|
||||
import org.springframework.web.http.HttpOutputMessage;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* Represents a server-side HTTP response.
|
||||
|
@ -28,14 +28,13 @@ import org.springframework.web.http.HttpStatus;
|
|||
public interface ServerHttpResponse extends HttpOutputMessage {
|
||||
|
||||
/**
|
||||
* Sets the HTTP status code of the response.
|
||||
*
|
||||
* @param status the HTTP status
|
||||
* Set the HTTP status code of the response.
|
||||
* @param status the HTTP status as an HttpStatus enum value
|
||||
*/
|
||||
void setStatusCode(HttpStatus status);
|
||||
|
||||
/**
|
||||
* Closes this response, freeing any resources created.
|
||||
* Close this response, freeing any resources created.
|
||||
*/
|
||||
void close();
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.server;
|
||||
package org.springframework.http.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -22,8 +22,8 @@ import java.util.Enumeration;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* {@link ServerHttpRequest} implementation that is based on a {@link HttpServletRequest}.
|
||||
|
@ -37,36 +37,37 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
|
|||
|
||||
private HttpHeaders headers;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>ServletHttpRequest</code> based on the given {@link HttpServletRequest}
|
||||
*
|
||||
* @param servletRequest the HTTP Servlet request
|
||||
* Construct a new instance of the ServletServerHttpRequest based on the given {@link HttpServletRequest}
|
||||
* @param servletRequest the HttpServletRequest
|
||||
*/
|
||||
public ServletServerHttpRequest(HttpServletRequest servletRequest) {
|
||||
Assert.notNull(servletRequest, "'servletRequest' must not be null");
|
||||
this.servletRequest = servletRequest;
|
||||
}
|
||||
|
||||
|
||||
public HttpMethod getMethod() {
|
||||
return HttpMethod.valueOf(servletRequest.getMethod());
|
||||
return HttpMethod.valueOf(this.servletRequest.getMethod());
|
||||
}
|
||||
|
||||
public HttpHeaders getHeaders() {
|
||||
if (headers == null) {
|
||||
headers = new HttpHeaders();
|
||||
for (Enumeration headerNames = servletRequest.getHeaderNames(); headerNames.hasMoreElements();) {
|
||||
if (this.headers == null) {
|
||||
this.headers = new HttpHeaders();
|
||||
for (Enumeration headerNames = this.servletRequest.getHeaderNames(); headerNames.hasMoreElements();) {
|
||||
String headerName = (String) headerNames.nextElement();
|
||||
for (Enumeration headerValues = servletRequest.getHeaders(headerName);
|
||||
headerValues.hasMoreElements();) {
|
||||
for (Enumeration headerValues = this.servletRequest.getHeaders(headerName); headerValues.hasMoreElements();) {
|
||||
String headerValue = (String) headerValues.nextElement();
|
||||
headers.add(headerName, headerValue);
|
||||
this.headers.add(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
public InputStream getBody() throws IOException {
|
||||
return servletRequest.getInputStream();
|
||||
return this.servletRequest.getInputStream();
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.server;
|
||||
package org.springframework.http.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
@ -23,8 +23,8 @@ import java.util.Map;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* {@link ServerHttpResponse} implementation that is based on a {@link HttpServletResponse}.
|
||||
|
@ -40,9 +40,9 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
|||
|
||||
private boolean headersWritten = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <code>ServletHttpResponse</code> based on the given {@link HttpServletResponse}
|
||||
*
|
||||
* Construct a new instance of the ServletServerHttpResponse based on the given {@link HttpServletResponse}.
|
||||
* @param servletResponse the HTTP Servlet response
|
||||
*/
|
||||
public ServletServerHttpResponse(HttpServletResponse servletResponse) {
|
||||
|
@ -50,32 +50,34 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
|||
this.servletResponse = servletResponse;
|
||||
}
|
||||
|
||||
|
||||
public void setStatusCode(HttpStatus status) {
|
||||
servletResponse.setStatus(status.value());
|
||||
this.servletResponse.setStatus(status.value());
|
||||
}
|
||||
|
||||
public HttpHeaders getHeaders() {
|
||||
return headers;
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
public OutputStream getBody() throws IOException {
|
||||
writeHeaders();
|
||||
return servletResponse.getOutputStream();
|
||||
}
|
||||
|
||||
private void writeHeaders() {
|
||||
if (!headersWritten) {
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
for (String headerValue : entry.getValue()) {
|
||||
servletResponse.addHeader(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
headersWritten = true;
|
||||
}
|
||||
return this.servletResponse.getOutputStream();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
writeHeaders();
|
||||
}
|
||||
|
||||
private void writeHeaders() {
|
||||
if (!this.headersWritten) {
|
||||
for (Map.Entry<String, List<String>> entry : this.headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
for (String headerValue : entry.getValue()) {
|
||||
this.servletResponse.addHeader(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
this.headersWritten = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -14,28 +14,28 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.core;
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.HttpClientException;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.web.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link HttpErrorHandler} interface.
|
||||
* Default implementation of the {@link ResponseErrorHandler} interface.
|
||||
*
|
||||
* <p>This error handler checks for the status code on the {@link ClientHttpResponse}: any code with series
|
||||
* {@link HttpStatus.Series#CLIENT_ERROR} or {@link HttpStatus.Series#SERVER_ERROR} is considered to be an error.
|
||||
* This behavior can be changed by overriding the {@link #hasError(HttpStatus)} method.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see RestTemplate#setErrorHandler(HttpErrorHandler)
|
||||
* @since 3.0
|
||||
* @see RestTemplate#setErrorHandler
|
||||
*/
|
||||
public class SimpleHttpErrorHandler implements HttpErrorHandler {
|
||||
public class DefaultResponseErrorHandler implements ResponseErrorHandler {
|
||||
|
||||
/**
|
||||
* Delegates to {@link #hasError(HttpStatus)} with the response status code.
|
||||
|
@ -46,18 +46,16 @@ public class SimpleHttpErrorHandler implements HttpErrorHandler {
|
|||
|
||||
/**
|
||||
* Template method called from {@link #hasError(ClientHttpResponse)}.
|
||||
*
|
||||
* <p>Default implementation checks if the given status code is {@link HttpStatus.Series#CLIENT_ERROR} or {@link
|
||||
* HttpStatus.Series#SERVER_ERROR}. Can be overridden in subclasses.
|
||||
*
|
||||
* <p>The default implementation checks if the given status code is {@link HttpStatus.Series#CLIENT_ERROR}
|
||||
* or {@link HttpStatus.Series#SERVER_ERROR}. Can be overridden in subclasses.
|
||||
* @param statusCode the HTTP status code
|
||||
* @return <code>true</code> if the response has an error; <code>false</code> otherwise
|
||||
* @see HttpStatus.Series#CLIENT_ERROR
|
||||
* @see HttpStatus.Series#SERVER_ERROR
|
||||
*/
|
||||
protected boolean hasError(HttpStatus statusCode) {
|
||||
return statusCode.series() == HttpStatus.Series.CLIENT_ERROR ||
|
||||
statusCode.series() == HttpStatus.Series.SERVER_ERROR;
|
||||
return (statusCode.series() == HttpStatus.Series.CLIENT_ERROR ||
|
||||
statusCode.series() == HttpStatus.Series.SERVER_ERROR);
|
||||
}
|
||||
|
||||
public void handleError(ClientHttpResponse response) throws IOException {
|
||||
|
@ -68,7 +66,8 @@ public class SimpleHttpErrorHandler implements HttpErrorHandler {
|
|||
case SERVER_ERROR:
|
||||
throw new HttpServerErrorException(statusCode, response.getStatusText());
|
||||
default:
|
||||
throw new HttpClientException("Unknown status code [" + statusCode + "]");
|
||||
throw new RestClientException("Unknown status code [" + statusCode + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,20 +16,19 @@
|
|||
|
||||
package org.springframework.web.client;
|
||||
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* Exception thrown when a HTTP 4xx is received.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.web.client.core.SimpleHttpErrorHandler
|
||||
* @since 3.0
|
||||
* @see DefaultResponseErrorHandler
|
||||
*/
|
||||
public class HttpClientErrorException extends HttpStatusCodeException {
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus}.
|
||||
*
|
||||
* Construct a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus}.
|
||||
* @param statusCode the status code
|
||||
*/
|
||||
public HttpClientErrorException(HttpStatus statusCode) {
|
||||
|
@ -37,12 +36,12 @@ public class HttpClientErrorException extends HttpStatusCodeException {
|
|||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus} and status text.
|
||||
*
|
||||
* Construct a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus} and status text.
|
||||
* @param statusCode the status code
|
||||
* @param statusText the status text
|
||||
*/
|
||||
public HttpClientErrorException(HttpStatus statusCode, String statusText) {
|
||||
super(statusCode, statusText);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,20 +16,19 @@
|
|||
|
||||
package org.springframework.web.client;
|
||||
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* Exception thrown when a HTTP 5xx is received.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.web.client.core.SimpleHttpErrorHandler
|
||||
* @since 3.0
|
||||
* @see DefaultResponseErrorHandler
|
||||
*/
|
||||
public class HttpServerErrorException extends HttpStatusCodeException {
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus}.
|
||||
*
|
||||
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus}.
|
||||
* @param statusCode the status code
|
||||
*/
|
||||
public HttpServerErrorException(HttpStatus statusCode) {
|
||||
|
@ -37,8 +36,7 @@ public class HttpServerErrorException extends HttpStatusCodeException {
|
|||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus} and status text.
|
||||
*
|
||||
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus} and status text.
|
||||
* @param statusCode the status code
|
||||
* @param statusText the status text
|
||||
*/
|
||||
|
|
|
@ -16,23 +16,23 @@
|
|||
|
||||
package org.springframework.web.client;
|
||||
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* Abstract base class for exceptions based on a {@link HttpStatus}.
|
||||
* Abstract base class for exceptions based on an {@link HttpStatus}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class HttpStatusCodeException extends HttpClientException {
|
||||
public abstract class HttpStatusCodeException extends RestClientException {
|
||||
|
||||
private final HttpStatus statusCode;
|
||||
|
||||
private final String statusText;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus}.
|
||||
*
|
||||
* Construct a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus}.
|
||||
* @param statusCode the status code
|
||||
*/
|
||||
protected HttpStatusCodeException(HttpStatus statusCode) {
|
||||
|
@ -42,8 +42,7 @@ public abstract class HttpStatusCodeException extends HttpClientException {
|
|||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus} and status text.
|
||||
*
|
||||
* Construct a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus} and status text.
|
||||
* @param statusCode the status code
|
||||
* @param statusText the status text
|
||||
*/
|
||||
|
@ -53,17 +52,19 @@ public abstract class HttpStatusCodeException extends HttpClientException {
|
|||
this.statusText = statusText;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the HTTP status code.
|
||||
*/
|
||||
public HttpStatus getStatusCode() {
|
||||
return statusCode;
|
||||
return this.statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP status text.
|
||||
*/
|
||||
public String getStatusText() {
|
||||
return statusText;
|
||||
return this.statusText;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.core;
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.web.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
|
||||
/**
|
||||
* Callback interface for code that operates on a {@link ClientHttpRequest}. Allows to manipulate the request
|
||||
|
@ -30,13 +30,12 @@ import org.springframework.web.http.client.ClientHttpRequest;
|
|||
* @see RestTemplate#execute
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface HttpRequestCallback {
|
||||
public interface RequestCallback {
|
||||
|
||||
/**
|
||||
* Gets called by {@link RestTemplate#execute} with an opened {@code ClientHttpRequest}. Does not need to care about
|
||||
* closing the request, handling I/O errors, or about handling errors: this will all be handled by the {@code
|
||||
* RestTemplate}.
|
||||
*
|
||||
* Gets called by {@link RestTemplate#execute} with an opened {@code ClientHttpRequest}.
|
||||
* Does not need to care about closing the request or about handling errors:
|
||||
* this will all be handled by the {@code RestTemplate}.
|
||||
* @param request the active HTTP request
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
|
@ -19,29 +19,27 @@ package org.springframework.web.client;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Exception thrown when a I/O error occurs.
|
||||
* Exception thrown when an I/O error occurs.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
*/
|
||||
public class HttpIOException extends HttpClientException {
|
||||
public class ResourceAccessException extends RestClientException {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HttpIOException} with the given message.
|
||||
*
|
||||
* Construct a new {@code HttpIOException} with the given message.
|
||||
* @param msg the message
|
||||
*/
|
||||
public HttpIOException(String msg) {
|
||||
public ResourceAccessException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HttpIOException} with the given message and {@link IOException}.
|
||||
*
|
||||
* Construct a new {@code HttpIOException} with the given message and {@link IOException}.
|
||||
* @param msg the message
|
||||
* @param ex the {@code IOException}
|
||||
* @param ex the {@code IOException}
|
||||
*/
|
||||
public HttpIOException(String msg, IOException ex) {
|
||||
public ResourceAccessException(String msg, IOException ex) {
|
||||
super(msg, ex);
|
||||
}
|
||||
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.core;
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.web.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
/**
|
||||
* Strategy interface used by the {@link RestTemplate} to determine whether a particular response has an error or not.
|
||||
|
@ -26,13 +26,12 @@ import org.springframework.web.http.client.ClientHttpResponse;
|
|||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface HttpErrorHandler {
|
||||
public interface ResponseErrorHandler {
|
||||
|
||||
/**
|
||||
* Indicates whether the given response has any errors.
|
||||
*
|
||||
* Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response.
|
||||
*
|
||||
* Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus}
|
||||
* of the response.
|
||||
* @param response the response to inspect
|
||||
* @return <code>true</code> if the response has an error; <code>false</code> otherwise
|
||||
* @throws IOException in case of I/O errors
|
||||
|
@ -41,13 +40,9 @@ public interface HttpErrorHandler {
|
|||
|
||||
/**
|
||||
* Handles the error in the given response.
|
||||
*
|
||||
* This method is only called when {@link #hasError(ClientHttpResponse)} has returned <code>true</code>.
|
||||
*
|
||||
* @param response the response with the error
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws org.springframework.web.client.HttpClientException
|
||||
* typically thrown by implementations of this interface
|
||||
*/
|
||||
void handleError(ClientHttpResponse response) throws IOException;
|
||||
}
|
|
@ -14,28 +14,28 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.core;
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.web.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
/**
|
||||
* Generic callback interface used by {@link RestTemplate}'s retrieval methods. Implementations of this interface
|
||||
* perform the actual work of extracting data from a {@link ClientHttpResponse}, but don't need to worry about exception
|
||||
* Generic callback interface used by {@link RestTemplate}'s retrieval methods
|
||||
* Implementations of this interface perform the actual work of extracting data
|
||||
* from a {@link ClientHttpResponse}, but don't need to worry about exception
|
||||
* handling or closing resources.
|
||||
*
|
||||
* <p>Used internally by the {@link RestTemplate}, but also useful for application code.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see RestTemplate#execute
|
||||
* @since 3.0
|
||||
* @see RestTemplate#execute
|
||||
*/
|
||||
public interface HttpResponseExtractor<T> {
|
||||
public interface ResponseExtractor<T> {
|
||||
|
||||
/**
|
||||
* Extracts data from the given {@code ClientHttpResponse} and returns it.
|
||||
*
|
||||
* Extract data from the given {@code ClientHttpResponse} and return it.
|
||||
* @param response the HTTP response
|
||||
* @return the extracted data
|
||||
* @throws IOException in case of I/O errors
|
|
@ -19,29 +19,28 @@ package org.springframework.web.client;
|
|||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
/**
|
||||
* Base class for exceptions thrown by the framework whenever it encounters client-side HTTP errors.
|
||||
* Base class for exceptions thrown by {@link RestTemplate} whenever it encounters client-side HTTP errors.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
*/
|
||||
public class HttpClientException extends NestedRuntimeException {
|
||||
public class RestClientException extends NestedRuntimeException {
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HttpClientException} with the given message.
|
||||
*
|
||||
* Construct a new instance of {@code HttpClientException} with the given message.
|
||||
* @param msg the message
|
||||
*/
|
||||
public HttpClientException(String msg) {
|
||||
public RestClientException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HttpClientException} with the given message and exception.
|
||||
*
|
||||
* Construct a new instance of {@code HttpClientException} with the given message and exception.
|
||||
* @param msg the message
|
||||
* @param ex the exception
|
||||
* @param ex the exception
|
||||
*/
|
||||
public HttpClientException(String msg, Throwable ex) {
|
||||
public RestClientException(String msg, Throwable ex) {
|
||||
super(msg, ex);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.springframework.web.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* Interface specifying a basic set of RESTful operations.
|
||||
* Implemented by {@link RestTemplate}. Not often used directly, but a useful
|
||||
* option to enhance testability, as it can easily be mocked or stubbed.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
* @see RestTemplate
|
||||
*/
|
||||
public interface RestOperations {
|
||||
|
||||
// GET
|
||||
|
||||
/**
|
||||
* Retrieve a representation by doing a GET on the specified URL.
|
||||
* <p>URI Template variables are expanded using the given URI variables, if any.
|
||||
* @param uri the URI
|
||||
* @param responseType the type of the return value
|
||||
* @param uriVariables the variables to expand the template
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T getForObject(String uri, Class<T> responseType, String... uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
/**
|
||||
* Retrieve a representation by doing a GET on the URI template.
|
||||
* <p>URI Template variables are expanded using the given map.
|
||||
* @param uri the URI
|
||||
* @param responseType the type of the return value
|
||||
* @param uriVariables the map containing variables for the URI template
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T getForObject(String uri, Class<T> responseType, Map<String, String> uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
|
||||
// HEAD
|
||||
|
||||
/**
|
||||
* Retrieve all headers of the resource specified by the URI template.
|
||||
* <p>URI Template variables are expanded using the given URI variables, if any.
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand the template
|
||||
* @return all HTTP headers of that resource
|
||||
*/
|
||||
HttpHeaders headForHeaders(String uri, String... uriVariables) throws RestClientException;
|
||||
|
||||
/**
|
||||
* Retrieve all headers of the resource specified by the URI template.
|
||||
* <p>URI Template variables are expanded using the given map.
|
||||
* @param uri the URI
|
||||
* @param uriVariables the map containing variables for the URI template
|
||||
* @return all HTTP headers of that resource
|
||||
*/
|
||||
HttpHeaders headForHeaders(String uri, Map<String, String> uriVariables) throws RestClientException;
|
||||
|
||||
|
||||
// POST
|
||||
|
||||
/**
|
||||
* Create a new resource by POSTing the given object to the URI template. The value of the <code>Location</code>,
|
||||
* indicating where the new resource is stored, is returned.
|
||||
* <p>URI Template variables are expanded using the given URI variables, if any.
|
||||
* @param uri the URI
|
||||
* @param request the Object to be POSTED
|
||||
* @return the value for the <code>Location</code> header
|
||||
*/
|
||||
URI postForLocation(String uri, Object request, String... uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
/**
|
||||
* Create a new resource by POSTing the given object to URI template. The value of the <code>Location</code>,
|
||||
* indicating where the new resource is stored, is returned.
|
||||
* <p>URI Template variables are expanded using the given map.
|
||||
* @param uri the URI
|
||||
* @param request the Object to be POSTed
|
||||
* @param uriVariables the variables to expand the template
|
||||
* @return the value for the <code>Location</code> header
|
||||
*/
|
||||
URI postForLocation(String uri, Object request, Map<String, String> uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
|
||||
// PUT
|
||||
|
||||
/**
|
||||
* Create or update a resource by PUTting the given object to the URI.
|
||||
* <p>URI Template variables are expanded using the given URI variables, if any.
|
||||
* @param uri the URI
|
||||
* @param request the Object to be POSTed
|
||||
* @param uriVariables the variables to expand the template
|
||||
*/
|
||||
void put(String uri, Object request, String... uriVariables) throws RestClientException;
|
||||
|
||||
/**
|
||||
* Creates a new resource by PUTting the given object to URI template.
|
||||
* <p>URI Template variables are expanded using the given map.
|
||||
* @param uri the URI
|
||||
* @param request the Object to be POSTed
|
||||
* @param uriVariables the variables to expand the template
|
||||
*/
|
||||
void put(String uri, Object request, Map<String, String> uriVariables) throws RestClientException;
|
||||
|
||||
|
||||
// DELETE
|
||||
|
||||
/**
|
||||
* Delete the resources at the specified URI.
|
||||
* <p>URI Template variables are expanded using the given URI variables, if any.
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand in the template
|
||||
*/
|
||||
void delete(String uri, String... uriVariables) throws RestClientException;
|
||||
|
||||
/**
|
||||
* Delete the resources at the specified URI.
|
||||
* <p>URI Template variables are expanded using the given map.
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand the template
|
||||
*/
|
||||
void delete(String uri, Map<String, String> uriVariables) throws RestClientException;
|
||||
|
||||
|
||||
// OPTIONS
|
||||
|
||||
/**
|
||||
* Return the value of the Allow header for the given URI.
|
||||
* <p>URI Template variables are expanded using the given URI variables, if any.
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand in the template
|
||||
* @return the value of the allow header
|
||||
*/
|
||||
Set<HttpMethod> optionsForAllow(String uri, String... uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
/**
|
||||
* Return the value of the Allow header for the given URI.
|
||||
* <p>URI Template variables are expanded using the given map.
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand in the template
|
||||
* @return the value of the allow header
|
||||
*/
|
||||
Set<HttpMethod> optionsForAllow(String uri, Map<String, String> uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
|
||||
// general execution
|
||||
|
||||
/**
|
||||
* Execute the HTTP methods to the given URI, preparing the request with the {@link RequestCallback},
|
||||
* and reading the response with a {@link ResponseExtractor}.
|
||||
* <p>URI Template variables are expanded using the given URI variables, if any.
|
||||
* @param uri the URI
|
||||
* @param method the HTTP method (GET, POST, etc)
|
||||
* @param requestCallback object that prepares the request
|
||||
* @param responseExtractor object that extracts the return value from the response
|
||||
* @param uriVariables the variables to expand in the template
|
||||
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
|
||||
*/
|
||||
<T> T execute(String uri, HttpMethod method, RequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor, String... uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
/**
|
||||
* Execute the HTTP methods to the given URI, preparing the request with the {@link RequestCallback},
|
||||
* and reading the response with a {@link ResponseExtractor}.
|
||||
* <p>URI Template variables are expanded using the given URI variables map.
|
||||
* @param uri the URI
|
||||
* @param method the HTTP method (GET, POST, etc)
|
||||
* @param requestCallback object that prepares the request
|
||||
* @param responseExtractor object that extracts the return value from the response
|
||||
* @param uriVariablesthe variables to expand in the template
|
||||
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
|
||||
*/
|
||||
<T> T execute(String uri, HttpMethod method, RequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor, Map<String, String> uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
}
|
|
@ -14,29 +14,27 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.core;
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.support.HttpAccessor;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.client.HttpClientException;
|
||||
import org.springframework.web.client.HttpIOException;
|
||||
import org.springframework.web.client.support.HttpAccessor;
|
||||
import org.springframework.web.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.web.converter.HttpMessageConverter;
|
||||
import org.springframework.web.converter.StringHttpMessageConverter;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.client.ClientHttpRequest;
|
||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.web.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
/**
|
||||
|
@ -76,72 +74,67 @@ import org.springframework.web.util.UriTemplate;
|
|||
* your own converter and register it via the {@link #setMessageConverters(HttpMessageConverter[]) messageConverters}
|
||||
* bean property.
|
||||
*
|
||||
* <p>This template uses a {@link org.springframework.web.http.client.SimpleClientHttpRequestFactory} and a {@link
|
||||
* SimpleHttpErrorHandler} as default strategies for for creating HTTP connections or handling HTTP errors, respectively.
|
||||
* <p>This template uses a {@link org.springframework.http.client.SimpleClientHttpRequestFactory} and a {@link
|
||||
* DefaultResponseErrorHandler} as default strategies for for creating HTTP connections or handling HTTP errors, respectively.
|
||||
* These defaults can be overridden through the {@link #setRequestFactory(ClientHttpRequestFactory) requestFactory} and
|
||||
* {@link #setErrorHandler(HttpErrorHandler) errorHandler} bean properties.
|
||||
* {@link #setErrorHandler(ResponseErrorHandler) errorHandler} bean properties.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see HttpMessageConverter
|
||||
* @see HttpRequestCallback
|
||||
* @see HttpResponseExtractor
|
||||
* @see HttpErrorHandler
|
||||
* @since 3.0
|
||||
* @see HttpMessageConverter
|
||||
* @see RequestCallback
|
||||
* @see ResponseExtractor
|
||||
* @see ResponseErrorHandler
|
||||
*/
|
||||
public class RestTemplate extends HttpAccessor implements RestOperations {
|
||||
|
||||
private final HttpResponseExtractor<HttpHeaders> headersExtractor = new HeadersExtractor();
|
||||
private final ResponseExtractor<HttpHeaders> headersExtractor = new HeadersExtractor();
|
||||
|
||||
private HttpMessageConverter<?>[] messageConverters;
|
||||
private HttpMessageConverter<?>[] messageConverters =
|
||||
new HttpMessageConverter[] {new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter()};
|
||||
|
||||
private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();
|
||||
|
||||
private HttpErrorHandler errorHandler;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link RestTemplate} using default settings.
|
||||
*
|
||||
* Create a new instance of the {@link RestTemplate} using default settings.
|
||||
* @see #initDefaultStrategies()
|
||||
*/
|
||||
public RestTemplate() {
|
||||
initDefaultStrategies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link RestTemplate} based on the given {@link ClientHttpRequestFactory}.
|
||||
*
|
||||
* Create a new instance of the {@link RestTemplate} based on the given {@link ClientHttpRequestFactory}.
|
||||
* @param requestFactory HTTP request factory to use
|
||||
* @see org.springframework.web.http.client.SimpleClientHttpRequestFactory
|
||||
* @see org.springframework.web.http.client.commons.CommonsClientHttpRequestFactory
|
||||
* @see org.springframework.http.client.SimpleClientHttpRequestFactory
|
||||
* @see org.springframework.http.client.CommonsClientHttpRequestFactory
|
||||
*/
|
||||
public RestTemplate(ClientHttpRequestFactory requestFactory) {
|
||||
initDefaultStrategies();
|
||||
setRequestFactory(requestFactory);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the default stragegies for this template.
|
||||
*
|
||||
* <p>Default implementation sets up the {@link SimpleHttpErrorHandler} and the {@link ByteArrayHttpMessageConverter} and
|
||||
* {@link StringHttpMessageConverter}.
|
||||
* Set the message body converters to use. These converters are used to convert
|
||||
* from and to HTTP requests and responses.
|
||||
*/
|
||||
protected void initDefaultStrategies() {
|
||||
errorHandler = new SimpleHttpErrorHandler();
|
||||
messageConverters =
|
||||
new HttpMessageConverter[]{new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter()};
|
||||
public void setMessageConverters(HttpMessageConverter<?>[] messageConverters) {
|
||||
Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
|
||||
this.messageConverters = messageConverters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of message body converters. These converters are used to covert from and to HTTP requests and
|
||||
* responses.
|
||||
* Returnsthe message body converters. These converters are used to convert
|
||||
* from and to HTTP requests and responses.
|
||||
*/
|
||||
public HttpMessageConverter<?>[] getMessageConverters() {
|
||||
return messageConverters;
|
||||
return this.messageConverters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of message body converters that support a particular type.
|
||||
*
|
||||
* Returns the message body converters that support a particular type.
|
||||
* @param type the type to return converters for
|
||||
* @return converts that support the given type
|
||||
* @return converters that support the given type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> List<HttpMessageConverter<T>> getSupportedMessageConverters(Class<T> type) {
|
||||
|
@ -156,122 +149,128 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the array of message body converters to use. These converters are used to covert from and to HTTP requests and
|
||||
* responses.
|
||||
*
|
||||
* <strong>Note</strong> that setting this property overrides the {@linkplain #initDefaultStrategies() default strategies}.
|
||||
* Set the error handler.
|
||||
*/
|
||||
public void setMessageConverters(HttpMessageConverter<?>[] messageConverters) {
|
||||
Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
|
||||
this.messageConverters = messageConverters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error handler. By default, this is the {@link SimpleHttpErrorHandler}.
|
||||
*/
|
||||
public HttpErrorHandler getErrorHandler() {
|
||||
return errorHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the error handler.
|
||||
*/
|
||||
public void setErrorHandler(HttpErrorHandler errorHandler) {
|
||||
public void setErrorHandler(ResponseErrorHandler errorHandler) {
|
||||
Assert.notNull(errorHandler, "'errorHandler' must not be null");
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the error handler. By default, this is the {@link DefaultResponseErrorHandler}.
|
||||
*/
|
||||
public ResponseErrorHandler getErrorHandler() {
|
||||
return this.errorHandler;
|
||||
}
|
||||
|
||||
|
||||
// GET
|
||||
|
||||
public <T> T getForObject(String url, Class<T> responseType, String... urlVariables) {
|
||||
checkForSupportedEntityConverter(responseType);
|
||||
public <T> T getForObject(String url, Class<T> responseType, String... urlVariables)
|
||||
throws RestClientException {
|
||||
|
||||
checkForSupportedMessageConverter(responseType);
|
||||
return execute(url, HttpMethod.GET, new GetCallback<T>(responseType),
|
||||
new HttpMessageConverterExtractor<T>(responseType), urlVariables);
|
||||
}
|
||||
|
||||
public <T> T getForObject(String url, Class<T> responseType, Map<String, String> urlVariables) {
|
||||
checkForSupportedEntityConverter(responseType);
|
||||
public <T> T getForObject(String url, Class<T> responseType, Map<String, String> urlVariables)
|
||||
throws RestClientException {
|
||||
|
||||
checkForSupportedMessageConverter(responseType);
|
||||
return execute(url, HttpMethod.GET, new GetCallback<T>(responseType),
|
||||
new HttpMessageConverterExtractor<T>(responseType), urlVariables);
|
||||
}
|
||||
|
||||
// POST
|
||||
|
||||
public URI postForLocation(String url, Object request, String... urlVariables) {
|
||||
checkForSupportedEntityConverter(request.getClass());
|
||||
HttpHeaders headers =
|
||||
execute(url, HttpMethod.POST, new PostPutCallback(request), headersExtractor, urlVariables);
|
||||
return headers.getLocation();
|
||||
}
|
||||
|
||||
public URI postForLocation(String url, Object request, Map<String, String> urlVariables) {
|
||||
checkForSupportedEntityConverter(request.getClass());
|
||||
HttpHeaders headers =
|
||||
execute(url, HttpMethod.POST, new PostPutCallback(request), headersExtractor, urlVariables);
|
||||
return headers.getLocation();
|
||||
}
|
||||
|
||||
// PUT
|
||||
|
||||
public void put(String url, Object request, String... urlVariables) {
|
||||
checkForSupportedEntityConverter(request.getClass());
|
||||
execute(url, HttpMethod.PUT, new PostPutCallback(request), null, urlVariables);
|
||||
}
|
||||
|
||||
public void put(String url, Object request, Map<String, String> urlVariables) {
|
||||
checkForSupportedEntityConverter(request.getClass());
|
||||
execute(url, HttpMethod.PUT, new PostPutCallback(request), null, urlVariables);
|
||||
}
|
||||
|
||||
// HEAD
|
||||
|
||||
public HttpHeaders headForHeaders(String url, String... urlVariables) {
|
||||
return execute(url, HttpMethod.HEAD, null, headersExtractor, urlVariables);
|
||||
public HttpHeaders headForHeaders(String url, String... urlVariables) throws RestClientException {
|
||||
return execute(url, HttpMethod.HEAD, null, this.headersExtractor, urlVariables);
|
||||
}
|
||||
|
||||
public HttpHeaders headForHeaders(String url, Map<String, String> urlVariables) {
|
||||
return execute(url, HttpMethod.HEAD, null, headersExtractor, urlVariables);
|
||||
public HttpHeaders headForHeaders(String url, Map<String, String> urlVariables) throws RestClientException {
|
||||
return execute(url, HttpMethod.HEAD, null, this.headersExtractor, urlVariables);
|
||||
}
|
||||
|
||||
|
||||
// POST
|
||||
|
||||
public URI postForLocation(String url, Object request, String... urlVariables)
|
||||
throws RestClientException {
|
||||
|
||||
checkForSupportedMessageConverter(request.getClass());
|
||||
HttpHeaders headers =
|
||||
execute(url, HttpMethod.POST, new PostPutCallback(request), this.headersExtractor, urlVariables);
|
||||
return headers.getLocation();
|
||||
}
|
||||
|
||||
public URI postForLocation(String url, Object request, Map<String, String> urlVariables)
|
||||
throws RestClientException {
|
||||
|
||||
checkForSupportedMessageConverter(request.getClass());
|
||||
HttpHeaders headers =
|
||||
execute(url, HttpMethod.POST, new PostPutCallback(request), this.headersExtractor, urlVariables);
|
||||
return headers.getLocation();
|
||||
}
|
||||
|
||||
|
||||
// PUT
|
||||
|
||||
public void put(String url, Object request, String... urlVariables) throws RestClientException {
|
||||
checkForSupportedMessageConverter(request.getClass());
|
||||
execute(url, HttpMethod.PUT, new PostPutCallback(request), null, urlVariables);
|
||||
}
|
||||
|
||||
public void put(String url, Object request, Map<String, String> urlVariables) throws RestClientException {
|
||||
checkForSupportedMessageConverter(request.getClass());
|
||||
execute(url, HttpMethod.PUT, new PostPutCallback(request), null, urlVariables);
|
||||
}
|
||||
|
||||
|
||||
// DELETE
|
||||
|
||||
public void delete(String url, String... urlVariables) {
|
||||
public void delete(String url, String... urlVariables) throws RestClientException {
|
||||
execute(url, HttpMethod.DELETE, null, null, urlVariables);
|
||||
}
|
||||
|
||||
public void delete(String url, Map<String, String> urlVariables) {
|
||||
public void delete(String url, Map<String, String> urlVariables) throws RestClientException {
|
||||
execute(url, HttpMethod.DELETE, null, null, urlVariables);
|
||||
}
|
||||
|
||||
|
||||
// OPTIONS
|
||||
|
||||
public EnumSet<HttpMethod> optionsForAllow(String url, String... urlVariables) {
|
||||
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, headersExtractor, urlVariables);
|
||||
public Set<HttpMethod> optionsForAllow(String url, String... urlVariables)
|
||||
throws RestClientException {
|
||||
|
||||
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, this.headersExtractor, urlVariables);
|
||||
return headers.getAllow();
|
||||
}
|
||||
|
||||
public EnumSet<HttpMethod> optionsForAllow(String url, Map<String, String> urlVariables) {
|
||||
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, headersExtractor, urlVariables);
|
||||
public Set<HttpMethod> optionsForAllow(String url, Map<String, String> urlVariables)
|
||||
throws RestClientException {
|
||||
|
||||
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, this.headersExtractor, urlVariables);
|
||||
return headers.getAllow();
|
||||
}
|
||||
|
||||
// execute
|
||||
|
||||
public <T> T execute(String url,
|
||||
HttpMethod method,
|
||||
HttpRequestCallback requestCallback,
|
||||
HttpResponseExtractor<T> responseExtractor,
|
||||
String... urlVariables) {
|
||||
// general execution
|
||||
|
||||
public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor, String... urlVariables)
|
||||
throws RestClientException {
|
||||
|
||||
UriTemplate uriTemplate = new UriTemplate(url);
|
||||
URI expanded = uriTemplate.expand(urlVariables);
|
||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||
}
|
||||
|
||||
public <T> T execute(String url,
|
||||
HttpMethod method,
|
||||
HttpRequestCallback requestCallback,
|
||||
HttpResponseExtractor<T> responseExtractor,
|
||||
Map<String, String> urlVariables) {
|
||||
public <T> T execute(String url,HttpMethod method, RequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor, Map<String, String> urlVariables)
|
||||
throws RestClientException {
|
||||
|
||||
UriTemplate uriTemplate = new UriTemplate(url);
|
||||
URI expanded = uriTemplate.expand(urlVariables);
|
||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||
|
@ -279,18 +278,16 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
|
||||
/**
|
||||
* Execute the given method on the provided URI. The {@link ClientHttpRequest} is processed using the {@link
|
||||
* HttpRequestCallback}; the response with the {@link HttpResponseExtractor}.
|
||||
*
|
||||
* @param url the fully-expanded URL to connect to
|
||||
* @param method the HTTP method to execute (GET, POST, etc.)
|
||||
* @param requestCallback object that prepares the request. Can be <code>null</code>.
|
||||
* @param responseExtractor object that extracts the return value from the response. Can be <code>null</code>.
|
||||
* @return an arbitrary object, as returned by the {@link HttpResponseExtractor}
|
||||
* RequestCallback}; the response with the {@link ResponseExtractor}.
|
||||
* @param url the fully-expanded URL to connect to
|
||||
* @param method the HTTP method to execute (GET, POST, etc.)
|
||||
* @param requestCallback object that prepares the request (can be <code>null</code>)
|
||||
* @param responseExtractor object that extracts the return value from the response (can be <code>null</code>)
|
||||
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
|
||||
*/
|
||||
protected <T> T doExecute(URI url,
|
||||
HttpMethod method,
|
||||
HttpRequestCallback requestCallback,
|
||||
HttpResponseExtractor<T> responseExtractor) {
|
||||
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor) throws RestClientException {
|
||||
|
||||
Assert.notNull(url, "'url' must not be null");
|
||||
Assert.notNull(method, "'method' must not be null");
|
||||
ClientHttpResponse response = null;
|
||||
|
@ -311,7 +308,7 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new HttpIOException("I/O error: " + ex.getMessage(), ex);
|
||||
throw new ResourceAccessException("I/O error: " + ex.getMessage(), ex);
|
||||
}
|
||||
finally {
|
||||
if (response != null) {
|
||||
|
@ -321,14 +318,13 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks whether any of the registered {@linkplain #setMessageConverters(HttpMessageConverter[]) message body
|
||||
* Check whether any of the registered {@linkplain #setMessageConverters(HttpMessageConverter[]) message body
|
||||
* converters} can convert the given type.
|
||||
*
|
||||
* @param type the type to check for
|
||||
* @throws IllegalArgumentException if no supported entity converter can be found
|
||||
* @see HttpMessageConverter#supports(Class)
|
||||
*/
|
||||
private void checkForSupportedEntityConverter(Class type) {
|
||||
private void checkForSupportedMessageConverter(Class type) {
|
||||
for (HttpMessageConverter<?> entityConverter : getMessageConverters()) {
|
||||
if (entityConverter.supports(type)) {
|
||||
return;
|
||||
|
@ -337,30 +333,11 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
throw new IllegalArgumentException("Could not resolve HttpMessageConverter for [" + type.getName() + "]");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Request callback implementation that sets the <code>Accept</code> header based on the registered {@linkplain
|
||||
* HttpMessageConverter entity converters}.
|
||||
* Request callback implementation that prepares the request's accept headers.
|
||||
*/
|
||||
private class AcceptHeaderCallback implements HttpRequestCallback {
|
||||
|
||||
public void doWithRequest(ClientHttpRequest request) throws IOException {
|
||||
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
|
||||
for (HttpMessageConverter<?> entityConverter : getMessageConverters()) {
|
||||
List<MediaType> supportedMediaTypes = entityConverter.getSupportedMediaTypes();
|
||||
for (MediaType supportedMediaType : supportedMediaTypes) {
|
||||
if (supportedMediaType.getCharSet() != null) {
|
||||
supportedMediaType =
|
||||
new MediaType(supportedMediaType.getType(), supportedMediaType.getSubtype());
|
||||
}
|
||||
allSupportedMediaTypes.add(supportedMediaType);
|
||||
}
|
||||
}
|
||||
Collections.sort(allSupportedMediaTypes);
|
||||
request.getHeaders().setAccept(allSupportedMediaTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private class GetCallback<T> implements HttpRequestCallback {
|
||||
private class GetCallback<T> implements RequestCallback {
|
||||
|
||||
private final Class<T> responseType;
|
||||
|
||||
|
@ -370,7 +347,7 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
|
||||
public void doWithRequest(ClientHttpRequest request) throws IOException {
|
||||
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
|
||||
for (HttpMessageConverter<?> entityConverter : getSupportedMessageConverters(responseType)) {
|
||||
for (HttpMessageConverter<?> entityConverter : getSupportedMessageConverters(this.responseType)) {
|
||||
List<MediaType> supportedMediaTypes = entityConverter.getSupportedMediaTypes();
|
||||
for (MediaType supportedMediaType : supportedMediaTypes) {
|
||||
if (supportedMediaType.getCharSet() != null) {
|
||||
|
@ -385,10 +362,11 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extension of {@link AcceptHeaderCallback} that writes the given object to the request stream.
|
||||
* Request callback implementation that writes the given object to the request stream.
|
||||
*/
|
||||
private class PostPutCallback implements HttpRequestCallback {
|
||||
private class PostPutCallback implements RequestCallback {
|
||||
|
||||
private final Object request;
|
||||
|
||||
|
@ -398,19 +376,17 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doWithRequest(ClientHttpRequest httpRequest) throws IOException {
|
||||
for (HttpMessageConverter entityConverter : getSupportedMessageConverters(request.getClass())) {
|
||||
entityConverter.write(request, httpRequest);
|
||||
break;
|
||||
}
|
||||
HttpMessageConverter entityConverter = getSupportedMessageConverters(this.request.getClass()).get(0);
|
||||
entityConverter.write(this.request, httpRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Response extractor that uses the registered {@linkplain HttpMessageConverter entity converters} to convert the
|
||||
* response into a type <code>T</code>.
|
||||
* Response extractor that uses the registered {@linkplain HttpMessageConverter entity converters}
|
||||
* to convert the response into a type <code>T</code>.
|
||||
*/
|
||||
private class HttpMessageConverterExtractor<T> implements HttpResponseExtractor<T> {
|
||||
private class HttpMessageConverterExtractor<T> implements ResponseExtractor<T> {
|
||||
|
||||
private final Class<T> responseType;
|
||||
|
||||
|
@ -421,29 +397,31 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
|||
public T extractData(ClientHttpResponse response) throws IOException {
|
||||
MediaType contentType = response.getHeaders().getContentType();
|
||||
if (contentType == null) {
|
||||
throw new HttpClientException("Cannot extract response: no Content-Type found");
|
||||
throw new RestClientException("Cannot extract response: no Content-Type found");
|
||||
}
|
||||
for (HttpMessageConverter<T> messageConverter : getSupportedMessageConverters(responseType)) {
|
||||
for (HttpMessageConverter<T> messageConverter : getSupportedMessageConverters(this.responseType)) {
|
||||
for (MediaType supportedMediaType : messageConverter.getSupportedMediaTypes()) {
|
||||
if (supportedMediaType.includes(contentType)) {
|
||||
return messageConverter.read(responseType, response);
|
||||
return messageConverter.read(this.responseType, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new HttpClientException(
|
||||
throw new RestClientException(
|
||||
"Could not extract response: no suitable HttpMessageConverter found for " + "response type [" +
|
||||
responseType.getName() + "] and content type [" + contentType + "]");
|
||||
this.responseType.getName() + "] and content type [" + contentType + "]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Response extractor that extracts the response {@link HttpHeaders}.
|
||||
*/
|
||||
private static class HeadersExtractor implements HttpResponseExtractor<HttpHeaders> {
|
||||
private static class HeadersExtractor implements ResponseExtractor<HttpHeaders> {
|
||||
|
||||
public HttpHeaders extractData(ClientHttpResponse response) throws IOException {
|
||||
return response.getHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,206 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* 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.springframework.web.client.core;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* Interface specifying a basic set of RESTful operations. Implemented by {@link RestTemplate}. Not often used directly,
|
||||
* but a useful option to enhance testability, as it can easily be mocked or stubbed.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see RestTemplate
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface RestOperations {
|
||||
|
||||
// GET
|
||||
|
||||
/**
|
||||
* Retrieves a representation by doing a GET on the specified URL. URI Template variables are expanded using the
|
||||
* given URI variables, if any.
|
||||
*
|
||||
* @param uri the URI to GET
|
||||
* @param responseType the type of the return value
|
||||
* @param uriVariables the variables to expand the template
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T getForObject(String uri, Class<T> responseType, String... uriVariables);
|
||||
|
||||
/**
|
||||
* Retrieves a representation by doing a GET on the URI template. URI Template variables are expanded using the
|
||||
* given map.
|
||||
*
|
||||
* @param uri the URI to GET
|
||||
* @param responseType the type of the return value
|
||||
* @param uriVariables the map containing variables for the URI template
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T getForObject(String uri, Class<T> responseType, Map<String, String> uriVariables);
|
||||
|
||||
// HEAD
|
||||
|
||||
/**
|
||||
* Retrieves all headers of the resource specified by the URI template. URI Template variables are expanded using
|
||||
* the given URI variables, if any.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand the template
|
||||
* @return all HTTP headers of that resource
|
||||
*/
|
||||
HttpHeaders headForHeaders(String uri, String... uriVariables);
|
||||
|
||||
/**
|
||||
* Retrieves all headers of the resource specified by the URI template. URI Template variables are expanded using
|
||||
* the given map.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param uriVariables the map containing variables for the URI template
|
||||
* @return all HTTP headers of that resource
|
||||
*/
|
||||
HttpHeaders headForHeaders(String uri, Map<String, String> uriVariables);
|
||||
|
||||
// POST
|
||||
|
||||
/**
|
||||
* Creates a new resource by POSTing the given object to the URI template. The value of the <code>Location</code>,
|
||||
* indicating where the new resource is stored, is returned. URI Template variables are expanded using the given URI
|
||||
* variables, if any.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param request the Object to be POSTED
|
||||
* @return the value for the <code>Location</code> header
|
||||
*/
|
||||
URI postForLocation(String uri, Object request, String... uriVariables);
|
||||
|
||||
/**
|
||||
* Creates a new resource by POSTing the given object to URI template. The value of the <code>Location</code>,
|
||||
* indicating where the new resource is stored, is returned. URI Template variables are expanded using the given
|
||||
* map.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param request the Object to be POSTed
|
||||
* @param uriVariables the variables to expand the template
|
||||
* @return the value for the <code>Location</code> header
|
||||
*/
|
||||
URI postForLocation(String uri, Object request, Map<String, String> uriVariables);
|
||||
|
||||
// PUT
|
||||
|
||||
/**
|
||||
* Creates or updates a resource by PUTting the given object to the URI. URI Template variables are expanded using
|
||||
* the given URI variables, if any.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param request the Object to be POSTed
|
||||
* @param uriVariables the variables to expand the template
|
||||
*/
|
||||
void put(String uri, Object request, String... uriVariables);
|
||||
|
||||
/**
|
||||
* Creates a new resource by PUTting the given object to URI template. URI Template variables are expanded using the
|
||||
* given map.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param request the Object to be POSTed
|
||||
* @param uriVariables the variables to expand the template
|
||||
*/
|
||||
void put(String uri, Object request, Map<String, String> uriVariables);
|
||||
|
||||
// DELETE
|
||||
|
||||
/**
|
||||
* Deletes the resources at the specified URI. URI Template variables are expanded using the given URI variables, if
|
||||
* any.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand in the template
|
||||
*/
|
||||
void delete(String uri, String... uriVariables);
|
||||
|
||||
/**
|
||||
* Deletes the resources at the specified URI. URI Template variables are expanded using the given map.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand the template
|
||||
*/
|
||||
void delete(String uri, Map<String, String> uriVariables);
|
||||
|
||||
//OPTIONS
|
||||
|
||||
/**
|
||||
* Returns value of the Allow header for the given URI. URI Template variables are expanded using the given URI
|
||||
* variables, if any.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand in the template
|
||||
* @return the value of the allow header
|
||||
*/
|
||||
EnumSet<HttpMethod> optionsForAllow(String uri, String... uriVariables);
|
||||
|
||||
/**
|
||||
* Returns value of the Allow header for the given URI. URI Template variables are expanded using the given map.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param uriVariables the variables to expand in the template
|
||||
* @return the value of the allow header
|
||||
*/
|
||||
EnumSet<HttpMethod> optionsForAllow(String uri, Map<String, String> uriVariables);
|
||||
|
||||
/**
|
||||
* Executes the HTTP methods to the given URI, preparing the request with the {@link HttpRequestCallback}, and
|
||||
* reading the response with a {@link HttpResponseExtractor}. URI Template variables are expanded using the
|
||||
* given URI variables, if any.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param method the HTTP method (GET, POST, etc)
|
||||
* @param requestCallback object that prepares the request
|
||||
* @param responseExtractor object that extracts the return value from the response
|
||||
* @param uriVariables the variables to expand in the template
|
||||
* @return an arbitrary object, as returned by the {@link HttpResponseExtractor}
|
||||
*/
|
||||
<T> T execute(String uri,
|
||||
HttpMethod method,
|
||||
HttpRequestCallback requestCallback,
|
||||
HttpResponseExtractor<T> responseExtractor,
|
||||
String... uriVariables);
|
||||
|
||||
/**
|
||||
* Executes the HTTP methods to the given URI, preparing the request with the {@link HttpRequestCallback}, and
|
||||
* reading the response with a {@link HttpResponseExtractor}. URI Template variables are expanded using the
|
||||
* given URI variables map.
|
||||
*
|
||||
* @param uri the URI
|
||||
* @param method the HTTP method (GET, POST, etc)
|
||||
* @param requestCallback object that prepares the request
|
||||
* @param responseExtractor object that extracts the return value from the response
|
||||
* @param uriVariables the variables to expand in the template
|
||||
* @return an arbitrary object, as returned by the {@link HttpResponseExtractor}
|
||||
*/
|
||||
<T> T execute(String uri,
|
||||
HttpMethod method,
|
||||
HttpRequestCallback requestCallback,
|
||||
HttpResponseExtractor<T> responseExtractor,
|
||||
Map<String, String> uriVariables);
|
||||
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Core package of the client-side HTTP support.
|
||||
Provides a RestTemplate class and various callback interfaces.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,8 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Classes supporting the org.springframework.web.client.core package.
|
||||
Contains a base class for RestTemplate usage.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,8 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
This package contains integration classes for client-side access of HTTP services.
|
||||
Core package of the client-side web support.
|
||||
Provides a RestTemplate class and various callback interfaces.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -14,48 +14,42 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.core.support;
|
||||
package org.springframework.web.client.support;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.client.core.RestTemplate;
|
||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
|
||||
/**
|
||||
* Convenient super class for application classes that need REST access.
|
||||
*
|
||||
* <p>Requires a {@link ClientHttpRequestFactory} or a {@link RestTemplate} instance to be set. It will create its own
|
||||
* JmsTemplate if a ConnectionFactory is passed in. A custom JmsTemplate instance can be created for a given
|
||||
* ConnectionFactory through overriding the <code>createJmsTemplate</code> method.
|
||||
* <p>Requires a {@link ClientHttpRequestFactory} or a {@link RestTemplate} instance to be set.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see #setRestTemplate(RestTemplate)
|
||||
* @see RestTemplate
|
||||
* @since 3.0
|
||||
* @see #setRestTemplate
|
||||
* @see org.springframework.web.client.RestTemplate
|
||||
*/
|
||||
public class RestGatewaySupport {
|
||||
|
||||
/**
|
||||
* Logger available to subclasses.
|
||||
*/
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the {@link RestGatewaySupport}, with default parameters.
|
||||
*
|
||||
* @see RestTemplate#RestTemplate()
|
||||
* Construct a new instance of the {@link RestGatewaySupport}, with default parameters.
|
||||
*/
|
||||
public RestGatewaySupport() {
|
||||
restTemplate = new RestTemplate();
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the {@link RestGatewaySupport}, with the given {@link ClientHttpRequestFactory}.
|
||||
*
|
||||
* Construct a new instance of the {@link RestGatewaySupport}, with the given {@link ClientHttpRequestFactory}.
|
||||
* @see RestTemplate#RestTemplate(ClientHttpRequestFactory
|
||||
*/
|
||||
public RestGatewaySupport(ClientHttpRequestFactory requestFactory) {
|
||||
|
@ -63,12 +57,6 @@ public class RestGatewaySupport {
|
|||
this.restTemplate = new RestTemplate(requestFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link RestTemplate} for the gateway.
|
||||
*/
|
||||
public RestTemplate getRestTemplate() {
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link RestTemplate} for the gateway.
|
||||
|
@ -78,4 +66,11 @@ public class RestGatewaySupport {
|
|||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link RestTemplate} for the gateway.
|
||||
*/
|
||||
public RestTemplate getRestTemplate() {
|
||||
return this.restTemplate;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
This package provides generic HTTP support classes,
|
||||
to be used by higher-level classes like RestTemplate.
|
||||
Classes supporting the <code>org.springframework.web.client</code> package.
|
||||
Contains a base class for RestTemplate usage.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Contains an implementation of the <code>ClientHttpRequest</code> and
|
||||
<code>ClientHttpResponse</code> based on Commons HTTP Client.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,8 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Contains a basic abstraction over client/server-side HTTP. This package
|
||||
contains the <code>HttpInputMessage</code> and <code>HttpOutputMessage</code>.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
@ -27,7 +27,7 @@ import static org.junit.Assert.*;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.util;
|
||||
package org.springframework.http;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -26,7 +26,7 @@ import org.junit.Test;
|
|||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class MediaTypeTest {
|
||||
public class MediaTypeTests {
|
||||
|
||||
@Test
|
||||
public void includes() throws Exception {
|
||||
|
@ -118,4 +118,5 @@ public class MediaTypeTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http;
|
||||
package org.springframework.http;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -38,8 +38,8 @@ import org.mortbay.jetty.servlet.Context;
|
|||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
public abstract class AbstractHttpRequestFactoryTestCase {
|
||||
|
|
@ -14,15 +14,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client.commons;
|
||||
package org.springframework.http.client;
|
||||
|
||||
import org.springframework.web.http.client.AbstractHttpRequestFactoryTestCase;
|
||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.AbstractHttpRequestFactoryTestCase;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.CommonsClientHttpRequestFactory;
|
||||
|
||||
public class CommonsHttpRequestFactoryTest extends AbstractHttpRequestFactoryTestCase {
|
||||
public class CommonsHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase {
|
||||
|
||||
@Override
|
||||
protected ClientHttpRequestFactory createRequestFactory() {
|
||||
return new CommonsClientHttpRequestFactory();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.client;
|
||||
package org.springframework.http.client;
|
||||
|
||||
public class SimpleHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase {
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.converter;
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -22,9 +22,9 @@ import static org.junit.Assert.*;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.http.MockHttpInputMessage;
|
||||
import org.springframework.web.http.MockHttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.MockHttpInputMessage;
|
||||
import org.springframework.http.MockHttpOutputMessage;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.converter;
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
@ -24,9 +24,9 @@ import static org.junit.Assert.*;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.http.MockHttpInputMessage;
|
||||
import org.springframework.web.http.MockHttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.MockHttpInputMessage;
|
||||
import org.springframework.http.MockHttpOutputMessage;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.server;
|
||||
package org.springframework.http.server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -24,8 +24,8 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.http.server;
|
||||
package org.springframework.http.server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -24,8 +24,8 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
|
@ -14,12 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.core;
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import javax.servlet.GenericServlet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
|
@ -37,11 +38,9 @@ import org.mortbay.jetty.Server;
|
|||
import org.mortbay.jetty.servlet.Context;
|
||||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.client.CommonsClientHttpRequestFactory;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.client.commons.CommonsClientHttpRequestFactory;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
@ -103,11 +102,12 @@ public class RestTemplateIntegrationTests {
|
|||
|
||||
@Test
|
||||
public void optionsForAllow() {
|
||||
EnumSet<HttpMethod> allowed = template.optionsForAllow("http://localhost:8889/get");
|
||||
Set<HttpMethod> allowed = template.optionsForAllow("http://localhost:8889/get");
|
||||
assertEquals("Invalid response",
|
||||
EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE), allowed);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Servlet that returns and error message for a given status code.
|
||||
*/
|
||||
|
@ -125,6 +125,7 @@ public class RestTemplateIntegrationTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class GetServlet extends HttpServlet {
|
||||
|
||||
private final byte[] buf;
|
||||
|
@ -145,6 +146,7 @@ public class RestTemplateIntegrationTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PostServlet extends HttpServlet {
|
||||
|
||||
private final String s;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.client.core;
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -22,31 +22,29 @@ import java.util.Collections;
|
|||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.easymock.EasyMock.*;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.client.HttpClientException;
|
||||
import org.springframework.web.client.HttpIOException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.web.converter.HttpMessageConverter;
|
||||
import org.springframework.web.converter.StringHttpMessageConverter;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.web.http.client.ClientHttpRequest;
|
||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.web.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class RestTemplateTest {
|
||||
public class RestTemplateTests {
|
||||
|
||||
private RestTemplate template;
|
||||
|
||||
|
@ -56,7 +54,7 @@ public class RestTemplateTest {
|
|||
|
||||
private ClientHttpResponse response;
|
||||
|
||||
private HttpErrorHandler errorHandler;
|
||||
private ResponseErrorHandler errorHandler;
|
||||
|
||||
private HttpMessageConverter converter;
|
||||
|
||||
|
@ -65,7 +63,7 @@ public class RestTemplateTest {
|
|||
requestFactory = createMock(ClientHttpRequestFactory.class);
|
||||
request = createMock(ClientHttpRequest.class);
|
||||
response = createMock(ClientHttpResponse.class);
|
||||
errorHandler = createMock(HttpErrorHandler.class);
|
||||
errorHandler = createMock(ResponseErrorHandler.class);
|
||||
converter = createMock(HttpMessageConverter.class);
|
||||
template = new RestTemplate(requestFactory);
|
||||
template.setErrorHandler(errorHandler);
|
||||
|
@ -200,7 +198,7 @@ public class RestTemplateTest {
|
|||
template.getForObject("http://example.com/{p}", String.class, "resource");
|
||||
fail("UnsupportedMediaTypeException expected");
|
||||
}
|
||||
catch (HttpClientException ex) {
|
||||
catch (RestClientException ex) {
|
||||
// expected
|
||||
}
|
||||
verifyMocks();
|
||||
|
@ -309,7 +307,7 @@ public class RestTemplateTest {
|
|||
|
||||
replayMocks();
|
||||
|
||||
EnumSet<HttpMethod> result = template.optionsForAllow("http://example.com");
|
||||
Set<HttpMethod> result = template.optionsForAllow("http://example.com");
|
||||
assertEquals("Invalid OPTIONS result", expected, result);
|
||||
|
||||
verifyMocks();
|
||||
|
@ -330,7 +328,7 @@ public class RestTemplateTest {
|
|||
template.getForObject("http://example.com/resource", String.class);
|
||||
fail("RestClientException expected");
|
||||
}
|
||||
catch (HttpIOException ex) {
|
||||
catch (ResourceAccessException ex) {
|
||||
// expected
|
||||
}
|
||||
|
Loading…
Reference in New Issue