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>> {
|
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.
|
* Return the first value 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.
|
|
||||||
*
|
|
||||||
* @param key the key
|
* @param key the key
|
||||||
* @return the first value for the specified key, or <code>null</code>
|
* @return the first value for the specified key, or <code>null</code>
|
||||||
*/
|
*/
|
||||||
V getFirst(K key);
|
V getFirst(K key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the given single value under the given key.
|
* Add the given single value to the current list of values for the given key.
|
||||||
*
|
* @param key the 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
|
* @param value the value to set
|
||||||
*/
|
*/
|
||||||
void set(K key, V value);
|
void set(K key, V value);
|
||||||
|
|
|
@ -29,13 +29,13 @@ import org.junit.Test;
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
*/
|
*/
|
||||||
public class DefaultMultiValueMapTests {
|
public class LinkedMultiValueMapTests {
|
||||||
|
|
||||||
private DefaultMultiValueMap<String, String> map;
|
private LinkedMultiValueMap<String, String> map;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
map = new DefaultMultiValueMap<String, String>();
|
map = new LinkedMultiValueMap<String, String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -71,7 +71,7 @@ public class DefaultMultiValueMapTests {
|
||||||
public void equals() {
|
public void equals() {
|
||||||
map.set("key1", "value1");
|
map.set("key1", "value1");
|
||||||
assertEquals(map, map);
|
assertEquals(map, map);
|
||||||
MultiValueMap<String, String> o1 = new DefaultMultiValueMap<String, String>();
|
MultiValueMap<String, String> o1 = new LinkedMultiValueMap<String, String>();
|
||||||
o1.set("key1", "value1");
|
o1.set("key1", "value1");
|
||||||
assertEquals(map, o1);
|
assertEquals(map, o1);
|
||||||
assertEquals(o1, map);
|
assertEquals(o1, map);
|
||||||
|
@ -80,4 +80,5 @@ public class DefaultMultiValueMapTests {
|
||||||
assertEquals(map, o2);
|
assertEquals(map, o2);
|
||||||
assertEquals(o2, map);
|
assertEquals(o2, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,7 +39,7 @@ import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.context.request.RequestAttributes;
|
import org.springframework.web.context.request.RequestAttributes;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
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.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
import org.springframework.web.servlet.View;
|
import org.springframework.web.servlet.View;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http;
|
package org.springframework.http;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
@ -31,7 +31,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.core.CollectionFactory;
|
import org.springframework.core.CollectionFactory;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.MediaType;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.util.StringUtils;
|
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.
|
* 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:
|
* <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
|
* <ul>
|
||||||
* #add(String, String)} adds a header value to the list of values for a header name</li> <li>{@link #set(String,
|
* <li>{@link #getFirst(String)} returns the first value associated with a given header name</li>
|
||||||
* String)} sets the header value to a single string value</li> </ul>
|
* <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}.
|
* <p>Inspired by {@link com.sun.net.httpserver.Headers}.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public final class HttpHeaders implements MultiValueMap<String, String> {
|
public class HttpHeaders implements MultiValueMap<String, String> {
|
||||||
|
|
||||||
private static String ACCEPT = "Accept";
|
private static String ACCEPT = "Accept";
|
||||||
|
|
||||||
|
@ -62,23 +63,12 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
||||||
|
|
||||||
private static String LOCATION = "Location";
|
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.
|
* Set 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.
|
|
||||||
*
|
|
||||||
* @param acceptableMediaTypes the acceptable media types
|
* @param acceptableMediaTypes the acceptable media types
|
||||||
*/
|
*/
|
||||||
public void setAccept(List<MediaType> acceptableMediaTypes) {
|
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.
|
* header.
|
||||||
*
|
|
||||||
* @return the acceptable charsets
|
* @return the acceptable charsets
|
||||||
*/
|
*/
|
||||||
public List<Charset> getAcceptCharset() {
|
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.
|
* Set the set of allowed {@link HttpMethod HTTP methods}, as specified by the <code>Allow</code> header.
|
||||||
*
|
* @param allowedMethods the allowed methods
|
||||||
* @param acceptableCharsets the acceptable charsets
|
|
||||||
*/
|
*/
|
||||||
public void setAcceptCharset(List<Charset> acceptableCharsets) {
|
public void setAllow(Set<HttpMethod> allowedMethods) {
|
||||||
StringBuilder builder = new StringBuilder();
|
set(ALLOW, StringUtils.collectionToCommaDelimitedString(allowedMethods));
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the set of allowed {@link HttpMethod HTTP methods}, as specified by the <code>Allow</code> header. <p/>
|
* Return the set of allowed {@link HttpMethod HTTP methods}, as specified by the <code>Allow</code> header.
|
||||||
* Returns an empty set when the allowed methods are unspecified.
|
* <p>Returns an empty set when the allowed methods are unspecified.
|
||||||
*
|
|
||||||
* @return the allowed methods
|
* @return the allowed methods
|
||||||
*/
|
*/
|
||||||
public EnumSet<HttpMethod> getAllow() {
|
public Set<HttpMethod> getAllow() {
|
||||||
String value = getFirst(ALLOW);
|
String value = getFirst(ALLOW);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
List<HttpMethod> allowedMethod = new ArrayList<HttpMethod>(5);
|
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.
|
* Set the length of the body in bytes, as specified by the <code>Content-Length</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.
|
|
||||||
*
|
|
||||||
* @param contentLength the content length
|
* @param contentLength the content length
|
||||||
*/
|
*/
|
||||||
public void setContentLength(long contentLength) {
|
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.
|
* Return the length of the body in bytes, as specified by the <code>Content-Length</code> header.
|
||||||
* <p/> Returns <code>null</code> when the content-type is unknown.
|
* <p>Returns -1 when the content-length is unknown.
|
||||||
*
|
* @return the content length
|
||||||
* @return the content type
|
|
||||||
*/
|
*/
|
||||||
public MediaType getContentType() {
|
public long getContentLength() {
|
||||||
String value = getFirst(CONTENT_TYPE);
|
String value = getFirst(CONTENT_LENGTH);
|
||||||
return value != null ? MediaType.parseMediaType(value) : null;
|
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
|
* @param mediaType the media type
|
||||||
*/
|
*/
|
||||||
public void setContentType(MediaType mediaType) {
|
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
|
* Return the {@linkplain MediaType media type} of the body, as specified by the <code>Content-Type</code> header.
|
||||||
* <code>null</code> when the location is unknown.
|
* <p>Returns <code>null</code> when the content-type is unknown.
|
||||||
*
|
* @return the content type
|
||||||
* @return the location
|
|
||||||
*/
|
*/
|
||||||
public URI getLocation() {
|
public MediaType getContentType() {
|
||||||
String value = getFirst(LOCATION);
|
String value = getFirst(CONTENT_TYPE);
|
||||||
return value != null ? URI.create(value) : null;
|
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
|
* @param location the location
|
||||||
*/
|
*/
|
||||||
public void setLocation(URI location) {
|
public void setLocation(URI location) {
|
||||||
set(LOCATION, location.toASCIIString());
|
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
|
* @param headerName the header name
|
||||||
* @return the first header value; or <code>null</code>
|
* @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 headerName the header name
|
||||||
* @param headerValue the header value
|
* @param headerValue the header value
|
||||||
* @throws UnsupportedOperationException if adding headers is not supported
|
* @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);
|
List<String> headerValues = headers.get(headerName);
|
||||||
if (headerValues == null) {
|
if (headerValues == null) {
|
||||||
headerValues = new LinkedList<String>();
|
headerValues = new LinkedList<String>();
|
||||||
headers.put(headerName, headerValues);
|
this.headers.put(headerName, headerValues);
|
||||||
}
|
}
|
||||||
headerValues.add(headerValue);
|
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 headerName the header name
|
||||||
* @param headerValue the header value
|
* @param headerValue the header value
|
||||||
* @throws UnsupportedOperationException if adding headers is not supported
|
* @throws UnsupportedOperationException if adding headers is not supported
|
||||||
|
@ -266,77 +252,77 @@ public final class HttpHeaders implements MultiValueMap<String, String> {
|
||||||
headers.put(headerName, headerValues);
|
headers.put(headerName, headerValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Map implementation
|
// Map implementation
|
||||||
*/
|
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return headers.size();
|
return this.headers.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return headers.isEmpty();
|
return this.headers.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(Object key) {
|
public boolean containsKey(Object key) {
|
||||||
return headers.containsKey(key);
|
return this.headers.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsValue(Object value) {
|
public boolean containsValue(Object value) {
|
||||||
return headers.containsValue(value);
|
return this.headers.containsValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> get(Object key) {
|
public List<String> get(Object key) {
|
||||||
return headers.get(key);
|
return this.headers.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> put(String key, List<String> value) {
|
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) {
|
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) {
|
public void putAll(Map<? extends String, ? extends List<String>> m) {
|
||||||
headers.putAll(m);
|
this.headers.putAll(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
headers.clear();
|
this.headers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> keySet() {
|
public Set<String> keySet() {
|
||||||
return headers.keySet();
|
return this.headers.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<List<String>> values() {
|
public Collection<List<String>> values() {
|
||||||
return headers.values();
|
return this.headers.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Entry<String, List<String>>> entrySet() {
|
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
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return headers.hashCode();
|
return this.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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return headers.toString();
|
return this.headers.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,14 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http;
|
package org.springframework.http;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a HTTP output message, consisting of {@linkplain #getHeaders() headers} and a readable {@linkplain
|
* Represents a HTTP output message, consisting of {@linkplain #getHeaders() headers}
|
||||||
* #getBody() body}. <p/> Typically implemented by a HTTP request on the server-side, or a response on the client-side.
|
* 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
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -29,8 +31,7 @@ import java.io.InputStream;
|
||||||
public interface HttpInputMessage extends HttpMessage {
|
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
|
* @return the input stream body
|
||||||
* @throws IOException in case of I/O Errors
|
* @throws IOException in case of I/O Errors
|
||||||
*/
|
*/
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* 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
|
* 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 {
|
public interface HttpMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the headers of this message.
|
* Return the headers of this message.
|
||||||
*
|
* @return a corresponding HttpHeaders object
|
||||||
* @return the headers
|
|
||||||
*/
|
*/
|
||||||
HttpHeaders getHeaders();
|
HttpHeaders getHeaders();
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,13 +14,14 @@
|
||||||
* limitations under the License.
|
* 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
|
* @author Arjen Poutsma
|
||||||
* @see org.springframework.web.bind.annotation.RequestMapping
|
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public enum HttpMethod {
|
public enum HttpMethod {
|
|
@ -14,14 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http;
|
package org.springframework.http;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a HTTP output message, consisting of {@linkplain #getHeaders() headers} and a writable {@linkplain
|
* Represents a HTTP output message, consisting of {@linkplain #getHeaders() headers}
|
||||||
* #getBody() body}. <p/> Typically implemented by a HTTP request on the client-side, or a response on the server-side.
|
* 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
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -29,8 +31,7 @@ import java.io.OutputStream;
|
||||||
public interface HttpOutputMessage extends HttpMessage {
|
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
|
* @return the output stream body
|
||||||
* @throws IOException in case of I/O Errors
|
* @throws IOException in case of I/O Errors
|
||||||
*/
|
*/
|
|
@ -14,10 +14,12 @@
|
||||||
* limitations under the License.
|
* 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
|
* @author Arjen Poutsma
|
||||||
* @see HttpStatus.Series
|
* @see HttpStatus.Series
|
||||||
|
@ -79,10 +81,59 @@ public enum HttpStatus {
|
||||||
GATEWAY_TIMEOUT(504),
|
GATEWAY_TIMEOUT(504),
|
||||||
HTTP_VERSION_NOT_SUPPORTED(505);
|
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),
|
INFORMATIONAL(1),
|
||||||
SUCCESSFUL(2),
|
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 of this status series. Ranges from 1 to 5.
|
||||||
*
|
|
||||||
* @return the integer value
|
|
||||||
*/
|
*/
|
||||||
public int value() {
|
public int value() {
|
||||||
return value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Series valueOf(HttpStatus status) {
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.util;
|
package org.springframework.http;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -26,27 +27,32 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.core.CollectionFactory;
|
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.
|
* 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
|
* <p>Consists of a {@linkplain #getType() type} and a {@linkplain #getSubtype() subtype}.
|
||||||
* parse media types from a string using {@link #parseMediaType(String)}, or multiple comma-separated media types using
|
* Also has functionality to parse media types from a string using {@link #parseMediaType(String)},
|
||||||
* {@link #parseMediaTypes(String)}.
|
* or multiple comma-separated media types using {@link #parseMediaTypes(String)}.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @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
|
* @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_QUALITY_FACTORY = "q";
|
||||||
|
|
||||||
private static final String PARAM_CHARSET = "charset";
|
private static final String PARAM_CHARSET = "charset";
|
||||||
|
|
||||||
private static final String WILDCARD_TYPE = "*";
|
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
|
||||||
|
@ -54,19 +60,10 @@ public final class MediaType implements Comparable<MediaType> {
|
||||||
|
|
||||||
private final Map<String, String> parameters;
|
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
|
* Create a new {@link MediaType} for the given primary type.
|
||||||
* <code>*</code>, parameters empty.
|
* <p>The {@linkplain #getSubtype() subtype} is set to <code>*</code>, parameters empty.
|
||||||
*
|
|
||||||
* @param type the primary type
|
* @param type the primary type
|
||||||
*/
|
*/
|
||||||
public MediaType(String 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.
|
* Create a new {@link MediaType} for the given primary type and subtype.
|
||||||
*
|
* <p>The parameters are empty.
|
||||||
* @param type the primary type
|
* @param typethe primary type
|
||||||
* @param subtype the subtype
|
* @param subtype the subtype
|
||||||
*/
|
*/
|
||||||
public MediaType(String type, String 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.
|
* Create a new {@link MediaType} for the given type, subtype, and character set.
|
||||||
*
|
* @param type the primary type
|
||||||
* @param type the primary type
|
|
||||||
* @param subtype the subtype
|
* @param subtype the subtype
|
||||||
* @param charSet the character set
|
* @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.
|
* Create a new {@link MediaType} for the given type, subtype, and parameters.
|
||||||
*
|
* @param type the primary type
|
||||||
* @param type the primary type
|
* @param subtype the subtype
|
||||||
* @param subtype the subtype
|
|
||||||
* @param parameters the parameters, mat be <code>null</code>
|
* @param parameters the parameters, mat be <code>null</code>
|
||||||
*/
|
*/
|
||||||
public MediaType(String type, String subtype, Map<String, String> parameters) {
|
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
|
* Return the primary type.
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the {@linkplain #getType() type} is the wildcard character <code>*</code> or not.
|
* Indicate whether the {@linkplain #getType() type} is the wildcard character <code>*</code> or not.
|
||||||
*
|
|
||||||
* @return whether the type is <code>*</code>
|
|
||||||
*/
|
*/
|
||||||
public boolean isWildcardType() {
|
public boolean isWildcardType() {
|
||||||
return WILDCARD_TYPE.equals(type);
|
return WILDCARD_TYPE.equals(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the subtype.
|
* Return the subtype.
|
||||||
*
|
|
||||||
* @return the subtype
|
|
||||||
*/
|
*/
|
||||||
public String getSubtype() {
|
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>
|
* @return whether the subtype is <code>*</code>
|
||||||
*/
|
*/
|
||||||
public boolean isWildcardSubtype() {
|
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
|
* @return the character set; or <code>null</code> if not available
|
||||||
*/
|
*/
|
||||||
public Charset getCharSet() {
|
public Charset getCharSet() {
|
||||||
String charSet = parameters.get(PARAM_CHARSET);
|
String charSet = this.parameters.get(PARAM_CHARSET);
|
||||||
return charSet != null ? Charset.forName(charSet) : null;
|
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
|
* @return the quality factory
|
||||||
*/
|
*/
|
||||||
public double getQualityValue() {
|
public double getQualityValue() {
|
||||||
String qualityFactory = parameters.get(PARAM_QUALITY_FACTORY);
|
String qualityFactory = this.parameters.get(PARAM_QUALITY_FACTORY);
|
||||||
return qualityFactory != null ? Double.parseDouble(qualityFactory) : 1D;
|
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
|
* @param name the parameter name
|
||||||
* @return the parameter value; or <code>null</code> if not present
|
* @return the parameter value; or <code>null</code> if not present
|
||||||
*/
|
*/
|
||||||
public String getParameter(String name) {
|
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
|
* Indicate whether this {@link MediaType} includes the given media type.
|
||||||
* <code>text/plain</code>, <code>text/html</code>, etc.
|
* <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
|
* @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
|
* @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
|
* 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;
|
* media type. Quality parameters are also considered, so that <blockquote> audio/* < audio/*;q=0.7;
|
||||||
* audio/*;q=0.3</blockquote>.
|
* audio/*;q=0.3</blockquote>.
|
||||||
*
|
|
||||||
* @param other the media type to compare to
|
* @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
|
* @return a negative integer, zero, or a positive integer as this media type is less than, equal to,
|
||||||
* the specified media type
|
* or greater than the specified media type
|
||||||
*/
|
*/
|
||||||
public int compareTo(MediaType other) {
|
public int compareTo(MediaType other) {
|
||||||
double qVal1 = this.getQualityValue();
|
double qVal1 = this.getQualityValue();
|
||||||
|
@ -303,23 +232,23 @@ public final class MediaType implements Comparable<MediaType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object other) {
|
||||||
if (this == o) {
|
if (this == other) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (o != null && o instanceof MediaType) {
|
if (!(other instanceof MediaType)) {
|
||||||
MediaType other = (MediaType) o;
|
return false;
|
||||||
return this.type.equals(other.type) && this.subtype.equals(other.subtype) &&
|
|
||||||
this.parameters.equals(other.parameters);
|
|
||||||
}
|
}
|
||||||
return false;
|
MediaType otherType = (MediaType) other;
|
||||||
|
return (this.type.equals(otherType.type) && this.subtype.equals(otherType.subtype) &&
|
||||||
|
this.parameters.equals(otherType.parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = type.hashCode();
|
int result = this.type.hashCode();
|
||||||
result = 31 * result + subtype.hashCode();
|
result = 31 * result + this.subtype.hashCode();
|
||||||
result = 31 * result + parameters.hashCode();
|
result = 31 * result + this.parameters.hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,15 +259,82 @@ public final class MediaType implements Comparable<MediaType> {
|
||||||
return builder.toString();
|
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
|
* Parse the given String into a single {@link MediaType}.
|
||||||
* Accept or Content-Type header.
|
* @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
|
* @param mediaTypes the string to parse
|
||||||
* @return the list of media types
|
* @return the list of media types
|
||||||
* @throws IllegalArgumentException if the string cannot be parsed
|
* @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();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (Iterator<MediaType> iterator = mediaTypes.iterator(); iterator.hasNext();) {
|
for (Iterator<MediaType> iterator = mediaTypes.iterator(); iterator.hasNext();) {
|
||||||
MediaType mediaType = iterator.next();
|
MediaType mediaType = iterator.next();
|
||||||
|
@ -350,15 +346,4 @@ public final class MediaType implements Comparable<MediaType> {
|
||||||
return builder.toString();
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
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.
|
* 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();
|
private final ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
|
||||||
public final HttpHeaders getHeaders() {
|
public final HttpHeaders getHeaders() {
|
||||||
checkExecuted();
|
checkExecuted();
|
||||||
return headers;
|
return this.headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final OutputStream getBody() throws IOException {
|
public final OutputStream getBody() throws IOException {
|
||||||
checkExecuted();
|
checkExecuted();
|
||||||
return bufferedOutput;
|
return this.bufferedOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ClientHttpResponse execute() throws IOException {
|
public final ClientHttpResponse execute() throws IOException {
|
||||||
checkExecuted();
|
checkExecuted();
|
||||||
ClientHttpResponse result = executeInternal(headers, bufferedOutput.toByteArray());
|
ClientHttpResponse result = executeInternal(this.headers, this.bufferedOutput.toByteArray());
|
||||||
executed = true;
|
this.executed = true;
|
||||||
return result;
|
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.
|
* 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)
|
protected abstract ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
private void checkExecuted() {
|
|
||||||
Assert.state(!executed, "ClientRequest already executed");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,33 +14,33 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.web.http.HttpOutputMessage;
|
import org.springframework.http.HttpOutputMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a client-side HTTP request. Created via an implementation of the {@link ClientHttpRequestFactory}. <p/> A
|
* Represents a client-side HTTP request. Created via an implementation of the {@link ClientHttpRequestFactory}.
|
||||||
* <code>HttpRequest</code> can be {@linkplain #execute() executed}, getting a {@link ClientHttpResponse} which can be
|
*
|
||||||
* read from.
|
* <p>A <code>HttpRequest</code> can be {@linkplain #execute() executed}, getting a {@link ClientHttpResponse}
|
||||||
|
* which can be read from.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
* @since 3.0
|
||||||
* @see ClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
* @see ClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
||||||
*/
|
*/
|
||||||
public interface ClientHttpRequest extends HttpOutputMessage {
|
public interface ClientHttpRequest extends HttpOutputMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HTTP method of the request.
|
* Return the HTTP method of the request.
|
||||||
*
|
* @return the HTTP method as an HttpMethod enum value
|
||||||
* @return the HTTP method
|
|
||||||
*/
|
*/
|
||||||
HttpMethod getMethod();
|
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
|
* @return the response result of the execution
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
*/
|
*/
|
|
@ -14,16 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
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)}
|
* Factory for {@link ClientHttpRequest} objects.
|
||||||
* method.
|
* Requests are created by the {@link #createRequest(URI, HttpMethod)} method.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -31,10 +31,10 @@ import org.springframework.web.http.HttpMethod;
|
||||||
public interface ClientHttpRequestFactory {
|
public interface ClientHttpRequestFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link ClientHttpRequest} for the specified URI and HTTP method. The returned request can be written
|
* Create a new {@link ClientHttpRequest} for the specified URI and HTTP method.
|
||||||
* to, and then executed by calling {@link ClientHttpRequest#execute()}.
|
* <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 uri the URI to create a request for
|
||||||
* @param httpMethod the HTTP method to execute
|
* @param httpMethod the HTTP method to execute
|
||||||
* @return the created request
|
* @return the created request
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
|
@ -14,16 +14,18 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.springframework.web.http.HttpInputMessage;
|
import org.springframework.http.HttpInputMessage;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a client-side HTTP response. Obtained via an calling of the {@link ClientHttpRequest#execute()}. <p/> A
|
* Represents a client-side HTTP response. Obtained via an calling of the {@link ClientHttpRequest#execute()}.
|
||||||
* <code>HttpResponse</code> must be {@linkplain #close() closed}, typically in a <code>finally</code> block.
|
*
|
||||||
|
* <p>A <code>ClientHttpResponse</code> must be {@linkplain #close() closed}, typically in a
|
||||||
|
* <code>finally</code> block.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -31,16 +33,14 @@ import org.springframework.web.http.HttpStatus;
|
||||||
public interface ClientHttpResponse extends HttpInputMessage {
|
public interface ClientHttpResponse extends HttpInputMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HTTP status code of the response.
|
* Return the HTTP status code of the response.
|
||||||
*
|
* @return the HTTP status as an HttpStatus enum value
|
||||||
* @return the HTTP status
|
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
*/
|
*/
|
||||||
HttpStatus getStatusCode() throws IOException;
|
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
|
* @return the HTTP status text
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
*/
|
*/
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client.commons;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
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.EntityEnclosingMethod;
|
||||||
import org.apache.commons.httpclient.methods.RequestEntity;
|
import org.apache.commons.httpclient.methods.RequestEntity;
|
||||||
|
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.web.http.client.AbstractClientHttpRequest;
|
import org.springframework.http.client.AbstractClientHttpRequest;
|
||||||
import org.springframework.web.http.client.ClientHttpResponse;
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.web.http.client.ClientHttpRequest} implementation that uses Commons Http Client to execute
|
* {@link org.springframework.http.client.ClientHttpRequest} implementation that uses
|
||||||
* requests. Created via the {@link CommonsClientHttpRequestFactory}.
|
* Apache Commons HttpClient to execute requests.
|
||||||
|
*
|
||||||
|
* <p>Created via the {@link CommonsClientHttpRequestFactory}.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
* @since 3.0
|
||||||
* @see CommonsClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
* @see CommonsClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
||||||
*/
|
*/
|
||||||
final class CommonsClientHttpRequest extends AbstractClientHttpRequest {
|
final class CommonsClientHttpRequest extends AbstractClientHttpRequest {
|
||||||
|
@ -44,7 +47,8 @@ final class CommonsClientHttpRequest extends AbstractClientHttpRequest {
|
||||||
|
|
||||||
private final HttpMethodBase httpMethod;
|
private final HttpMethodBase httpMethod;
|
||||||
|
|
||||||
CommonsClientHttpRequest(HttpClient httpClient, HttpMethodBase httpMethod) {
|
|
||||||
|
public CommonsClientHttpRequest(HttpClient httpClient, HttpMethodBase httpMethod) {
|
||||||
this.httpClient = httpClient;
|
this.httpClient = httpClient;
|
||||||
this.httpMethod = httpMethod;
|
this.httpMethod = httpMethod;
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client.commons;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -33,17 +33,18 @@ import org.apache.commons.httpclient.methods.TraceMethod;
|
||||||
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.web.http.client.ClientHttpRequest;
|
|
||||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.web.http.client.ClientHttpRequestFactory} implementation that uses <a
|
* {@link org.springframework.http.client.ClientHttpRequestFactory} implementation that uses
|
||||||
* href="http://jakarta.apache.org/commons/httpclient">Jakarta Commons HttpClient</a> to create requests. <p/> Allows to
|
* <a href="http://jakarta.apache.org/commons/httpclient">Jakarta Commons HttpClient</a> to create requests.
|
||||||
* use a pre-configured {@link HttpClient} instance, potentially with authentication, HTTP connection pooling, etc.
|
*
|
||||||
|
* <p>Allows to use a pre-configured {@link HttpClient} instance -
|
||||||
|
* potentially with authentication, HTTP connection pooling, etc.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @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 {
|
public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean {
|
||||||
|
|
||||||
|
@ -51,9 +52,10 @@ public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory
|
||||||
|
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of the <code>CommonsHttpRequestFactory</code> with a default {@link HttpClient} that uses a
|
* Create a new instance of the <code>CommonsHttpRequestFactory</code> with a default
|
||||||
* default {@link MultiThreadedHttpConnectionManager}.
|
* {@link HttpClient} that uses a default {@link MultiThreadedHttpConnectionManager}.
|
||||||
*/
|
*/
|
||||||
public CommonsClientHttpRequestFactory() {
|
public CommonsClientHttpRequestFactory() {
|
||||||
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
|
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.
|
* 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
|
* @param httpClient the HttpClient instance to use for this factory
|
||||||
*/
|
*/
|
||||||
public CommonsClientHttpRequestFactory(HttpClient httpClient) {
|
public CommonsClientHttpRequestFactory(HttpClient httpClient) {
|
||||||
Assert.notNull(httpClient, "httpClient must not be null");
|
Assert.notNull(httpClient, "httpClient must not be null");
|
||||||
this.httpClient = httpClient;
|
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) {
|
public void setHttpClient(HttpClient httpClient) {
|
||||||
this.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.
|
* 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
|
* @param timeout the timeout value in milliseconds
|
||||||
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)
|
* @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)
|
||||||
*/
|
*/
|
||||||
|
@ -97,52 +99,59 @@ public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory
|
||||||
this.httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout);
|
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();
|
HttpConnectionManager connectionManager = getHttpClient().getHttpConnectionManager();
|
||||||
if (connectionManager instanceof MultiThreadedHttpConnectionManager) {
|
if (connectionManager instanceof MultiThreadedHttpConnectionManager) {
|
||||||
((MultiThreadedHttpConnectionManager) connectionManager).shutdown();
|
((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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client.commons;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -22,15 +22,18 @@ import java.io.InputStream;
|
||||||
import org.apache.commons.httpclient.Header;
|
import org.apache.commons.httpclient.Header;
|
||||||
import org.apache.commons.httpclient.HttpMethod;
|
import org.apache.commons.httpclient.HttpMethod;
|
||||||
|
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.http.client.ClientHttpResponse;
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.web.http.client.ClientHttpResponse} implementation that uses Commons Http Client to
|
* {@link org.springframework.http.client.ClientHttpResponse} implementation that uses
|
||||||
* execute requests. Created via the {@link CommonsClientHttpRequest}.
|
* Apache Commons HttpClient to execute requests.
|
||||||
|
*
|
||||||
|
* <p>Created via the {@link CommonsClientHttpRequest}.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
* @since 3.0
|
||||||
* @see CommonsClientHttpRequest#execute()
|
* @see CommonsClientHttpRequest#execute()
|
||||||
*/
|
*/
|
||||||
final class CommonsClientHttpResponse implements ClientHttpResponse {
|
final class CommonsClientHttpResponse implements ClientHttpResponse {
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
@ -22,27 +22,29 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ClientHttpRequest} implementation that uses standard J2SE facilities to execute requests. Created via the
|
* {@link ClientHttpRequest} implementation that uses standard J2SE facilities to execute requests.
|
||||||
* {@link SimpleClientHttpRequestFactory}.
|
* Created via the {@link SimpleClientHttpRequestFactory}.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see SimpleClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
* @see SimpleClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
||||||
*/
|
*/
|
||||||
final class SimpleClientHttpRequest extends AbstractClientHttpRequest {
|
final class SimpleClientHttpRequest extends AbstractClientHttpRequest {
|
||||||
|
|
||||||
private final HttpURLConnection connection;
|
private final HttpURLConnection connection;
|
||||||
|
|
||||||
SimpleClientHttpRequest(HttpURLConnection connection) {
|
|
||||||
|
public SimpleClientHttpRequest(HttpURLConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public HttpMethod getMethod() {
|
public HttpMethod getMethod() {
|
||||||
return HttpMethod.valueOf(connection.getRequestMethod());
|
return HttpMethod.valueOf(this.connection.getRequestMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,12 +52,12 @@ final class SimpleClientHttpRequest extends AbstractClientHttpRequest {
|
||||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||||
String headerName = entry.getKey();
|
String headerName = entry.getKey();
|
||||||
for (String headerValue : entry.getValue()) {
|
for (String headerValue : entry.getValue()) {
|
||||||
connection.addRequestProperty(headerName, headerValue);
|
this.connection.addRequestProperty(headerName, headerValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connection.connect();
|
this.connection.connect();
|
||||||
FileCopyUtils.copy(bufferedOutput, connection.getOutputStream());
|
FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
|
||||||
return new SimpleClientHttpResponse(connection);
|
return new SimpleClientHttpResponse(this.connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,30 +14,28 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ClientHttpRequestFactory} implementation that uses standard J2SE facilities.
|
* {@link ClientHttpRequestFactory} implementation that uses standard J2SE facilities.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see java.net.HttpURLConnection
|
|
||||||
* @see org.springframework.web.http.client.commons.CommonsClientHttpRequestFactory
|
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
* @see java.net.HttpURLConnection
|
||||||
|
* @see CommonsClientHttpRequestFactory
|
||||||
*/
|
*/
|
||||||
public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory {
|
public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory {
|
||||||
|
|
||||||
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
||||||
URL url = uri.toURL();
|
URLConnection urlConnection = uri.toURL().openConnection();
|
||||||
URLConnection urlConnection = url.openConnection();
|
|
||||||
Assert.isInstanceOf(HttpURLConnection.class, urlConnection);
|
Assert.isInstanceOf(HttpURLConnection.class, urlConnection);
|
||||||
HttpURLConnection connection = (HttpURLConnection) urlConnection;
|
HttpURLConnection connection = (HttpURLConnection) urlConnection;
|
||||||
prepareConnection(connection, httpMethod.name());
|
prepareConnection(connection, httpMethod.name());
|
||||||
|
@ -46,9 +44,7 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template method for preparing the given {@link HttpURLConnection}.
|
* Template method for preparing the given {@link HttpURLConnection}.
|
||||||
*
|
* <p>The default implementation prepares the connection for input and output, and sets the HTTP method.
|
||||||
* <p>Default implementation prepares the connection for input and output, and sets the HTTP method.
|
|
||||||
*
|
|
||||||
* @param connection the connection to prepare
|
* @param connection the connection to prepare
|
||||||
* @param httpMethod the HTTP request method ({@code GET}, {@code POST}, etc.)
|
* @param httpMethod the HTTP request method ({@code GET}, {@code POST}, etc.)
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
|
@ -14,19 +14,19 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ClientHttpResponse} implementation that uses standard J2SE facilities. Obtained via the {@link
|
* {@link ClientHttpResponse} implementation that uses standard J2SE facilities.
|
||||||
* SimpleClientHttpRequest#execute()}.
|
* Obtained via the {@link SimpleClientHttpRequest#execute()}.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -37,45 +37,44 @@ final class SimpleClientHttpResponse implements ClientHttpResponse {
|
||||||
|
|
||||||
private HttpHeaders headers;
|
private HttpHeaders headers;
|
||||||
|
|
||||||
SimpleClientHttpResponse(HttpURLConnection connection) {
|
|
||||||
|
public SimpleClientHttpResponse(HttpURLConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public HttpStatus getStatusCode() throws IOException {
|
public HttpStatus getStatusCode() throws IOException {
|
||||||
return HttpStatus.valueOf(connection.getResponseCode());
|
return HttpStatus.valueOf(this.connection.getResponseCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStatusText() throws IOException {
|
public String getStatusText() throws IOException {
|
||||||
return connection.getResponseMessage();
|
return this.connection.getResponseMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpHeaders getHeaders() {
|
public HttpHeaders getHeaders() {
|
||||||
if (headers == null) {
|
if (this.headers == null) {
|
||||||
headers = new HttpHeaders();
|
this.headers = new HttpHeaders();
|
||||||
// Header field 0 is the status line, so we start at 1
|
// Header field 0 is the status line, so we start at 1
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while (true) {
|
while (true) {
|
||||||
String name = connection.getHeaderFieldKey(i);
|
String name = this.connection.getHeaderFieldKey(i);
|
||||||
if (!StringUtils.hasLength(name)) {
|
if (!StringUtils.hasLength(name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
headers.add(name, connection.getHeaderField(i));
|
this.headers.add(name, this.connection.getHeaderField(i));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return headers;
|
return this.headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getBody() throws IOException {
|
public InputStream getBody() throws IOException {
|
||||||
if (connection.getErrorStream() == null) {
|
InputStream errorStream = this.connection.getErrorStream();
|
||||||
return connection.getInputStream();
|
return (errorStream != null ? errorStream : this.connection.getInputStream());
|
||||||
}
|
|
||||||
else {
|
|
||||||
return connection.getErrorStream();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
connection.disconnect();
|
this.connection.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.client.support;
|
package org.springframework.http.client.support;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -23,19 +23,21 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.web.http.client.ClientHttpRequest;
|
import org.springframework.http.client.ClientHttpRequest;
|
||||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
import org.springframework.web.http.client.SimpleClientHttpRequestFactory;
|
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for {@link org.springframework.web.client.core.RestTemplate} and other HTTP accessing gateway helpers, defining
|
* Base class for {@link org.springframework.web.client.RestTemplate}
|
||||||
* common properties such as the {@link ClientHttpRequestFactory} to operate on.
|
* and other HTTP accessing gateway helpers, defining common properties
|
||||||
* <p/>
|
* such as the {@link ClientHttpRequestFactory} to operate on.
|
||||||
* Not intended to be used directly. See {@link org.springframework.web.client.core.RestTemplate}.
|
*
|
||||||
|
* <p>Not intended to be used directly. See {@link org.springframework.web.client.RestTemplate}.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see org.springframework.web.client.core.RestTemplate
|
* @since 3.0
|
||||||
|
* @see org.springframework.web.client.RestTemplate
|
||||||
*/
|
*/
|
||||||
public abstract class HttpAccessor {
|
public abstract class HttpAccessor {
|
||||||
|
|
||||||
|
@ -46,15 +48,9 @@ public abstract class HttpAccessor {
|
||||||
|
|
||||||
private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
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) {
|
public void setRequestFactory(ClientHttpRequestFactory requestFactory) {
|
||||||
Assert.notNull(requestFactory, "'requestFactory' must not be null");
|
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}.
|
* Return the request factory that this accessor uses for obtaining {@link ClientHttpRequest HttpRequests}.
|
||||||
*
|
*/
|
||||||
* @param url the URL to connect to
|
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.)
|
* @param method the HTTP method to exectute (GET, POST, etc.)
|
||||||
* @return the created request
|
* @return the created request
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
|
@ -76,4 +79,5 @@ public abstract class HttpAccessor {
|
||||||
}
|
}
|
||||||
return request;
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.converter;
|
package org.springframework.http.converter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -26,69 +26,66 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpOutputMessage;
|
||||||
import org.springframework.web.http.HttpOutputMessage;
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for most {@link HttpMessageConverter} implementations.
|
* Abstract base class for most {@link HttpMessageConverter} implementations.
|
||||||
*
|
*
|
||||||
* <p>This base class adds support for setting supported {@code MediaTypes}, through the {@link
|
* <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
|
* #setSupportedMediaTypes(List) supportedMediaTypes} bean property. It also adds support for
|
||||||
* {@code Content-Length} when writing to output messages.
|
* {@code Content-Type} and {@code Content-Length} when writing to output messages.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConverter<T> {
|
public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConverter<T> {
|
||||||
|
|
||||||
/**
|
/** Logger available to subclasses */
|
||||||
* Logger available to subclasses.
|
|
||||||
*/
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private List<MediaType> supportedMediaTypes = Collections.emptyList();
|
private List<MediaType> supportedMediaTypes = Collections.emptyList();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an {@code AbstractHttpMessageConverter} with no supported media types.
|
* Construct an {@code AbstractHttpMessageConverter} with no supported media types.
|
||||||
*
|
* @see #setSupportedMediaTypes
|
||||||
* @see #setSupportedMediaTypes(List)
|
|
||||||
*/
|
*/
|
||||||
protected AbstractHttpMessageConverter() {
|
protected AbstractHttpMessageConverter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an {@code AbstractHttpMessageConverter} with one supported media type.
|
* Construct an {@code AbstractHttpMessageConverter} with one supported media type.
|
||||||
*/
|
*/
|
||||||
protected AbstractHttpMessageConverter(MediaType supportedMediaType) {
|
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) {
|
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) {
|
public void setSupportedMediaTypes(List<MediaType> supportedMediaTypes) {
|
||||||
Assert.notEmpty(supportedMediaTypes, "'supportedMediaTypes' must not be empty");
|
Assert.notEmpty(supportedMediaTypes, "'supportedMediaTypes' must not be empty");
|
||||||
this.supportedMediaTypes = new ArrayList<MediaType>(supportedMediaTypes);
|
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
|
||||||
* <p>This implementation delegates to {@link #getContentType(Object)} and {@link #getContentLength(Object)}, and sets
|
* {@link #writeToInternal(Object, HttpOutputMessage)}.
|
||||||
* the corresponding headers on the output message. It then calls {@link #writeToInternal(Object, HttpOutputMessage)}.
|
|
||||||
*
|
|
||||||
* @throws HttpMessageConversionException in case of conversion errors
|
* @throws HttpMessageConversionException in case of conversion errors
|
||||||
*/
|
*/
|
||||||
public final void write(T t, HttpOutputMessage outputMessage) throws IOException {
|
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.
|
* Returns the content type for the given type.
|
||||||
*
|
|
||||||
* <p>By default, this returns the first element of the {@link #setSupportedMediaTypes(List) supportedMediaTypes}
|
* <p>By default, this returns the first element of the {@link #setSupportedMediaTypes(List) supportedMediaTypes}
|
||||||
* property, if any. Can be overriden in subclasses.
|
* property, if any. Can be overriden in subclasses.
|
||||||
*
|
|
||||||
* @param t the type to return the content type for
|
* @param t the type to return the content type for
|
||||||
* @return the content type, or <code>null</code> if not known
|
* @return the content type, or <code>null</code> if not known
|
||||||
*/
|
*/
|
||||||
protected MediaType getContentType(T t) {
|
protected MediaType getContentType(T t) {
|
||||||
List<MediaType> mediaTypes = getSupportedMediaTypes();
|
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.
|
* Returns the content length for the given type.
|
||||||
*
|
|
||||||
* <p>By default, this returns <code>null</code>. Can be overriden in subclasses.
|
* <p>By default, this returns <code>null</code>. Can be overriden in subclasses.
|
||||||
*
|
|
||||||
* @param t the type to return the content length for
|
* @param t the type to return the content length for
|
||||||
* @return the content length, or <code>null</code> if not known
|
* @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)}.
|
* 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
|
* @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
|
* @throws HttpMessageConversionException in case of conversion errors
|
||||||
*/
|
*/
|
||||||
protected abstract void writeToInternal(T t, HttpOutputMessage outputMessage) throws IOException;
|
protected abstract void writeToInternal(T t, HttpOutputMessage outputMessage) throws IOException;
|
|
@ -14,15 +14,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.converter;
|
package org.springframework.http.converter;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.http.HttpInputMessage;
|
import org.springframework.http.HttpInputMessage;
|
||||||
import org.springframework.web.http.HttpOutputMessage;
|
import org.springframework.http.HttpOutputMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link HttpMessageConverter} that can read and write byte arrays.
|
* 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) {
|
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 {
|
public byte[] read(Class<byte[]> clazz, HttpInputMessage inputMessage) throws IOException {
|
||||||
|
@ -75,5 +75,4 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<
|
||||||
FileCopyUtils.copy(bytes, outputMessage.getBody());
|
FileCopyUtils.copy(bytes, outputMessage.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.converter;
|
package org.springframework.http.converter;
|
||||||
|
|
||||||
import org.springframework.core.NestedRuntimeException;
|
import org.springframework.core.NestedRuntimeException;
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ public class HttpMessageConversionException extends NestedRuntimeException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new MessageConversionException.
|
* Create a new MessageConversionException.
|
||||||
*
|
|
||||||
* @param msg the detail message
|
* @param msg the detail message
|
||||||
*/
|
*/
|
||||||
public HttpMessageConversionException(String msg) {
|
public HttpMessageConversionException(String msg) {
|
||||||
|
@ -37,11 +36,11 @@ public class HttpMessageConversionException extends NestedRuntimeException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new MessageConversionException.
|
* Create a new MessageConversionException.
|
||||||
*
|
* @param msg the detail message
|
||||||
* @param msg the detail message
|
|
||||||
* @param cause the root cause (if any)
|
* @param cause the root cause (if any)
|
||||||
*/
|
*/
|
||||||
public HttpMessageConversionException(String msg, Throwable cause) {
|
public HttpMessageConversionException(String msg, Throwable cause) {
|
||||||
super(msg, cause);
|
super(msg, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,17 +14,17 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.converter;
|
package org.springframework.http.converter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.HttpInputMessage;
|
||||||
import org.springframework.web.http.HttpInputMessage;
|
import org.springframework.http.HttpOutputMessage;
|
||||||
import org.springframework.web.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
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -32,37 +32,32 @@ import org.springframework.web.http.HttpOutputMessage;
|
||||||
public interface HttpMessageConverter<T> {
|
public interface HttpMessageConverter<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the given class is supported by this converter.
|
* Indicate whether the given class is supported by this converter.
|
||||||
*
|
|
||||||
* <p>Typically implemented using an {@code instanceof} check.
|
|
||||||
*
|
|
||||||
* @param clazz the class to test for support
|
* @param clazz the class to test for support
|
||||||
* @return <code>true</code> if supported; <code>false</code> otherwise
|
* @return <code>true</code> if supported; <code>false</code> otherwise
|
||||||
*/
|
*/
|
||||||
boolean supports(Class<? extends T> clazz);
|
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();
|
List<MediaType> getSupportedMediaTypes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads an object of the given type form the given input message, and returns it.
|
* Read an object of the given type form the given input message, and returns it.
|
||||||
*
|
* @param clazz the type of object to return
|
||||||
* @param clazz the type of object to return
|
|
||||||
* @param inputMessage the HTTP input message to read from
|
* @param inputMessage the HTTP input message to read from
|
||||||
* @return the converted object
|
* @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
|
* @throws HttpMessageConversionException in case of conversion errors
|
||||||
*/
|
*/
|
||||||
T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException;
|
T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes an given object to the given output message.
|
* Write an given object to the given output message.
|
||||||
*
|
* @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
|
* @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
|
* @throws HttpMessageConversionException in case of conversion errors
|
||||||
*/
|
*/
|
||||||
void write(T t, HttpOutputMessage outputMessage) throws IOException;
|
void write(T t, HttpOutputMessage outputMessage) throws IOException;
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.converter;
|
package org.springframework.http.converter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
@ -25,9 +25,9 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.HttpInputMessage;
|
||||||
import org.springframework.web.http.HttpInputMessage;
|
import org.springframework.http.HttpOutputMessage;
|
||||||
import org.springframework.web.http.HttpOutputMessage;
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link HttpMessageConverter} that can read and write strings.
|
* 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;
|
private final List<Charset> availableCharsets;
|
||||||
|
|
||||||
|
|
||||||
public StringHttpMessageConverter() {
|
public StringHttpMessageConverter() {
|
||||||
super(new MediaType("text", "plain", DEFAULT_CHARSET), new MediaType("text", "*"));
|
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) {
|
public boolean supports(Class<? extends String> clazz) {
|
||||||
return String.class.equals(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.
|
* <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses.
|
||||||
*
|
|
||||||
* @return the list of accepted charsets
|
* @return the list of accepted charsets
|
||||||
*/
|
*/
|
||||||
protected List<Charset> getAcceptedCharsets() {
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.server;
|
package org.springframework.http.server;
|
||||||
|
|
||||||
import org.springframework.web.http.HttpInputMessage;
|
import org.springframework.http.HttpInputMessage;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a server-side HTTP request.
|
* Represents a server-side HTTP request.
|
||||||
|
@ -28,9 +28,8 @@ import org.springframework.web.http.HttpMethod;
|
||||||
public interface ServerHttpRequest extends HttpInputMessage {
|
public interface ServerHttpRequest extends HttpInputMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HTTP method of the request.
|
* Return the HTTP method of the request.
|
||||||
*
|
* @return the HTTP method as an HttpMethod enum value
|
||||||
* @return the http method
|
|
||||||
*/
|
*/
|
||||||
HttpMethod getMethod();
|
HttpMethod getMethod();
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.server;
|
package org.springframework.http.server;
|
||||||
|
|
||||||
import org.springframework.web.http.HttpOutputMessage;
|
import org.springframework.http.HttpOutputMessage;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a server-side HTTP response.
|
* Represents a server-side HTTP response.
|
||||||
|
@ -28,14 +28,13 @@ import org.springframework.web.http.HttpStatus;
|
||||||
public interface ServerHttpResponse extends HttpOutputMessage {
|
public interface ServerHttpResponse extends HttpOutputMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the HTTP status code of the response.
|
* Set the HTTP status code of the response.
|
||||||
*
|
* @param status the HTTP status as an HttpStatus enum value
|
||||||
* @param status the HTTP status
|
|
||||||
*/
|
*/
|
||||||
void setStatusCode(HttpStatus status);
|
void setStatusCode(HttpStatus status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes this response, freeing any resources created.
|
* Close this response, freeing any resources created.
|
||||||
*/
|
*/
|
||||||
void close();
|
void close();
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.server;
|
package org.springframework.http.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -22,8 +22,8 @@ import java.util.Enumeration;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ServerHttpRequest} implementation that is based on a {@link HttpServletRequest}.
|
* {@link ServerHttpRequest} implementation that is based on a {@link HttpServletRequest}.
|
||||||
|
@ -37,36 +37,37 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
|
||||||
|
|
||||||
private HttpHeaders headers;
|
private HttpHeaders headers;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new instance of the <code>ServletHttpRequest</code> based on the given {@link HttpServletRequest}
|
* Construct a new instance of the ServletServerHttpRequest based on the given {@link HttpServletRequest}
|
||||||
*
|
* @param servletRequest the HttpServletRequest
|
||||||
* @param servletRequest the HTTP Servlet request
|
|
||||||
*/
|
*/
|
||||||
public ServletServerHttpRequest(HttpServletRequest servletRequest) {
|
public ServletServerHttpRequest(HttpServletRequest servletRequest) {
|
||||||
Assert.notNull(servletRequest, "'servletRequest' must not be null");
|
Assert.notNull(servletRequest, "'servletRequest' must not be null");
|
||||||
this.servletRequest = servletRequest;
|
this.servletRequest = servletRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public HttpMethod getMethod() {
|
public HttpMethod getMethod() {
|
||||||
return HttpMethod.valueOf(servletRequest.getMethod());
|
return HttpMethod.valueOf(this.servletRequest.getMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpHeaders getHeaders() {
|
public HttpHeaders getHeaders() {
|
||||||
if (headers == null) {
|
if (this.headers == null) {
|
||||||
headers = new HttpHeaders();
|
this.headers = new HttpHeaders();
|
||||||
for (Enumeration headerNames = servletRequest.getHeaderNames(); headerNames.hasMoreElements();) {
|
for (Enumeration headerNames = this.servletRequest.getHeaderNames(); headerNames.hasMoreElements();) {
|
||||||
String headerName = (String) headerNames.nextElement();
|
String headerName = (String) headerNames.nextElement();
|
||||||
for (Enumeration headerValues = servletRequest.getHeaders(headerName);
|
for (Enumeration headerValues = this.servletRequest.getHeaders(headerName); headerValues.hasMoreElements();) {
|
||||||
headerValues.hasMoreElements();) {
|
|
||||||
String headerValue = (String) headerValues.nextElement();
|
String headerValue = (String) headerValues.nextElement();
|
||||||
headers.add(headerName, headerValue);
|
this.headers.add(headerName, headerValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return headers;
|
return this.headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getBody() throws IOException {
|
public InputStream getBody() throws IOException {
|
||||||
return servletRequest.getInputStream();
|
return this.servletRequest.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.server;
|
package org.springframework.http.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -23,8 +23,8 @@ import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ServerHttpResponse} implementation that is based on a {@link HttpServletResponse}.
|
* {@link ServerHttpResponse} implementation that is based on a {@link HttpServletResponse}.
|
||||||
|
@ -40,9 +40,9 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
||||||
|
|
||||||
private boolean headersWritten = false;
|
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
|
* @param servletResponse the HTTP Servlet response
|
||||||
*/
|
*/
|
||||||
public ServletServerHttpResponse(HttpServletResponse servletResponse) {
|
public ServletServerHttpResponse(HttpServletResponse servletResponse) {
|
||||||
|
@ -50,32 +50,34 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
|
||||||
this.servletResponse = servletResponse;
|
this.servletResponse = servletResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setStatusCode(HttpStatus status) {
|
public void setStatusCode(HttpStatus status) {
|
||||||
servletResponse.setStatus(status.value());
|
this.servletResponse.setStatus(status.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpHeaders getHeaders() {
|
public HttpHeaders getHeaders() {
|
||||||
return headers;
|
return this.headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputStream getBody() throws IOException {
|
public OutputStream getBody() throws IOException {
|
||||||
writeHeaders();
|
writeHeaders();
|
||||||
return servletResponse.getOutputStream();
|
return this.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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
writeHeaders();
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.client.core;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.springframework.web.client.HttpClientErrorException;
|
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.client.HttpServerErrorException;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.http.client.ClientHttpResponse;
|
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
|
* <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.
|
* {@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.
|
* This behavior can be changed by overriding the {@link #hasError(HttpStatus)} method.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see RestTemplate#setErrorHandler(HttpErrorHandler)
|
|
||||||
* @since 3.0
|
* @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.
|
* 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)}.
|
* Template method called from {@link #hasError(ClientHttpResponse)}.
|
||||||
*
|
* <p>The default implementation checks if the given status code is {@link HttpStatus.Series#CLIENT_ERROR}
|
||||||
* <p>Default implementation checks if the given status code is {@link HttpStatus.Series#CLIENT_ERROR} or {@link
|
* or {@link HttpStatus.Series#SERVER_ERROR}. Can be overridden in subclasses.
|
||||||
* HttpStatus.Series#SERVER_ERROR}. Can be overridden in subclasses.
|
|
||||||
*
|
|
||||||
* @param statusCode the HTTP status code
|
* @param statusCode the HTTP status code
|
||||||
* @return <code>true</code> if the response has an error; <code>false</code> otherwise
|
* @return <code>true</code> if the response has an error; <code>false</code> otherwise
|
||||||
* @see HttpStatus.Series#CLIENT_ERROR
|
* @see HttpStatus.Series#CLIENT_ERROR
|
||||||
* @see HttpStatus.Series#SERVER_ERROR
|
* @see HttpStatus.Series#SERVER_ERROR
|
||||||
*/
|
*/
|
||||||
protected boolean hasError(HttpStatus statusCode) {
|
protected boolean hasError(HttpStatus statusCode) {
|
||||||
return statusCode.series() == HttpStatus.Series.CLIENT_ERROR ||
|
return (statusCode.series() == HttpStatus.Series.CLIENT_ERROR ||
|
||||||
statusCode.series() == HttpStatus.Series.SERVER_ERROR;
|
statusCode.series() == HttpStatus.Series.SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleError(ClientHttpResponse response) throws IOException {
|
public void handleError(ClientHttpResponse response) throws IOException {
|
||||||
|
@ -68,7 +66,8 @@ public class SimpleHttpErrorHandler implements HttpErrorHandler {
|
||||||
case SERVER_ERROR:
|
case SERVER_ERROR:
|
||||||
throw new HttpServerErrorException(statusCode, response.getStatusText());
|
throw new HttpServerErrorException(statusCode, response.getStatusText());
|
||||||
default:
|
default:
|
||||||
throw new HttpClientException("Unknown status code [" + statusCode + "]");
|
throw new RestClientException("Unknown status code [" + statusCode + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,20 +16,19 @@
|
||||||
|
|
||||||
package org.springframework.web.client;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown when a HTTP 4xx is received.
|
* Exception thrown when a HTTP 4xx is received.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see org.springframework.web.client.core.SimpleHttpErrorHandler
|
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
* @see DefaultResponseErrorHandler
|
||||||
*/
|
*/
|
||||||
public class HttpClientErrorException extends HttpStatusCodeException {
|
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
|
* @param statusCode the status code
|
||||||
*/
|
*/
|
||||||
public HttpClientErrorException(HttpStatus statusCode) {
|
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 statusCode the status code
|
||||||
* @param statusText the status text
|
* @param statusText the status text
|
||||||
*/
|
*/
|
||||||
public HttpClientErrorException(HttpStatus statusCode, String statusText) {
|
public HttpClientErrorException(HttpStatus statusCode, String statusText) {
|
||||||
super(statusCode, statusText);
|
super(statusCode, statusText);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,20 +16,19 @@
|
||||||
|
|
||||||
package org.springframework.web.client;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown when a HTTP 5xx is received.
|
* Exception thrown when a HTTP 5xx is received.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see org.springframework.web.client.core.SimpleHttpErrorHandler
|
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
* @see DefaultResponseErrorHandler
|
||||||
*/
|
*/
|
||||||
public class HttpServerErrorException extends HttpStatusCodeException {
|
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
|
* @param statusCode the status code
|
||||||
*/
|
*/
|
||||||
public HttpServerErrorException(HttpStatus statusCode) {
|
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 statusCode the status code
|
||||||
* @param statusText the status text
|
* @param statusText the status text
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,23 +16,23 @@
|
||||||
|
|
||||||
package org.springframework.web.client;
|
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
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public abstract class HttpStatusCodeException extends HttpClientException {
|
public abstract class HttpStatusCodeException extends RestClientException {
|
||||||
|
|
||||||
private final HttpStatus statusCode;
|
private final HttpStatus statusCode;
|
||||||
|
|
||||||
private final String statusText;
|
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
|
* @param statusCode the status code
|
||||||
*/
|
*/
|
||||||
protected HttpStatusCodeException(HttpStatus statusCode) {
|
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 statusCode the status code
|
||||||
* @param statusText the status text
|
* @param statusText the status text
|
||||||
*/
|
*/
|
||||||
|
@ -53,17 +52,19 @@ public abstract class HttpStatusCodeException extends HttpClientException {
|
||||||
this.statusText = statusText;
|
this.statusText = statusText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HTTP status code.
|
* Returns the HTTP status code.
|
||||||
*/
|
*/
|
||||||
public HttpStatus getStatusCode() {
|
public HttpStatus getStatusCode() {
|
||||||
return statusCode;
|
return this.statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HTTP status text.
|
* Returns the HTTP status text.
|
||||||
*/
|
*/
|
||||||
public String getStatusText() {
|
public String getStatusText() {
|
||||||
return statusText;
|
return this.statusText;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.client.core;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
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
|
* 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
|
* @see RestTemplate#execute
|
||||||
* @since 3.0
|
* @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
|
* Gets called by {@link RestTemplate#execute} with an opened {@code ClientHttpRequest}.
|
||||||
* closing the request, handling I/O errors, or about handling errors: this will all be handled by the {@code
|
* Does not need to care about closing the request or about handling errors:
|
||||||
* RestTemplate}.
|
* this will all be handled by the {@code RestTemplate}.
|
||||||
*
|
|
||||||
* @param request the active HTTP request
|
* @param request the active HTTP request
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
*/
|
*/
|
|
@ -19,29 +19,27 @@ package org.springframework.web.client;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown when a I/O error occurs.
|
* Exception thrown when an I/O error occurs.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @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
|
* @param msg the message
|
||||||
*/
|
*/
|
||||||
public HttpIOException(String msg) {
|
public ResourceAccessException(String msg) {
|
||||||
super(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 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);
|
super(msg, ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.client.core;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
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.
|
* 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
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public interface HttpErrorHandler {
|
public interface ResponseErrorHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the given response has any errors.
|
* Indicates whether the given response has any errors.
|
||||||
*
|
* Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus}
|
||||||
* Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response.
|
* of the response.
|
||||||
*
|
|
||||||
* @param response the response to inspect
|
* @param response the response to inspect
|
||||||
* @return <code>true</code> if the response has an error; <code>false</code> otherwise
|
* @return <code>true</code> if the response has an error; <code>false</code> otherwise
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
||||||
|
@ -41,13 +40,9 @@ public interface HttpErrorHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the error in the given response.
|
* Handles the error in the given response.
|
||||||
*
|
|
||||||
* This method is only called when {@link #hasError(ClientHttpResponse)} has returned <code>true</code>.
|
* This method is only called when {@link #hasError(ClientHttpResponse)} has returned <code>true</code>.
|
||||||
*
|
|
||||||
* @param response the response with the error
|
* @param response the response with the error
|
||||||
* @throws IOException in case of I/O errors
|
* @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;
|
void handleError(ClientHttpResponse response) throws IOException;
|
||||||
}
|
}
|
|
@ -14,28 +14,28 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.client.core;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
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
|
* Generic callback interface used by {@link RestTemplate}'s retrieval methods
|
||||||
* perform the actual work of extracting data from a {@link ClientHttpResponse}, but don't need to worry about exception
|
* 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.
|
* handling or closing resources.
|
||||||
*
|
*
|
||||||
* <p>Used internally by the {@link RestTemplate}, but also useful for application code.
|
* <p>Used internally by the {@link RestTemplate}, but also useful for application code.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see RestTemplate#execute
|
|
||||||
* @since 3.0
|
* @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
|
* @param response the HTTP response
|
||||||
* @return the extracted data
|
* @return the extracted data
|
||||||
* @throws IOException in case of I/O errors
|
* @throws IOException in case of I/O errors
|
|
@ -19,29 +19,28 @@ package org.springframework.web.client;
|
||||||
import org.springframework.core.NestedRuntimeException;
|
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
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @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
|
* @param msg the message
|
||||||
*/
|
*/
|
||||||
public HttpClientException(String msg) {
|
public RestClientException(String msg) {
|
||||||
super(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 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);
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.client.core;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.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;
|
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}
|
* your own converter and register it via the {@link #setMessageConverters(HttpMessageConverter[]) messageConverters}
|
||||||
* bean property.
|
* bean property.
|
||||||
*
|
*
|
||||||
* <p>This template uses a {@link org.springframework.web.http.client.SimpleClientHttpRequestFactory} and a {@link
|
* <p>This template uses a {@link org.springframework.http.client.SimpleClientHttpRequestFactory} and a {@link
|
||||||
* SimpleHttpErrorHandler} as default strategies for for creating HTTP connections or handling HTTP errors, respectively.
|
* 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
|
* 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
|
* @author Arjen Poutsma
|
||||||
* @see HttpMessageConverter
|
|
||||||
* @see HttpRequestCallback
|
|
||||||
* @see HttpResponseExtractor
|
|
||||||
* @see HttpErrorHandler
|
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
* @see HttpMessageConverter
|
||||||
|
* @see RequestCallback
|
||||||
|
* @see ResponseExtractor
|
||||||
|
* @see ResponseErrorHandler
|
||||||
*/
|
*/
|
||||||
public class RestTemplate extends HttpAccessor implements RestOperations {
|
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()
|
* @see #initDefaultStrategies()
|
||||||
*/
|
*/
|
||||||
public RestTemplate() {
|
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
|
* @param requestFactory HTTP request factory to use
|
||||||
* @see org.springframework.web.http.client.SimpleClientHttpRequestFactory
|
* @see org.springframework.http.client.SimpleClientHttpRequestFactory
|
||||||
* @see org.springframework.web.http.client.commons.CommonsClientHttpRequestFactory
|
* @see org.springframework.http.client.CommonsClientHttpRequestFactory
|
||||||
*/
|
*/
|
||||||
public RestTemplate(ClientHttpRequestFactory requestFactory) {
|
public RestTemplate(ClientHttpRequestFactory requestFactory) {
|
||||||
initDefaultStrategies();
|
|
||||||
setRequestFactory(requestFactory);
|
setRequestFactory(requestFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the default stragegies for this template.
|
* Set the message body converters to use. These converters are used to convert
|
||||||
*
|
* from and to HTTP requests and responses.
|
||||||
* <p>Default implementation sets up the {@link SimpleHttpErrorHandler} and the {@link ByteArrayHttpMessageConverter} and
|
|
||||||
* {@link StringHttpMessageConverter}.
|
|
||||||
*/
|
*/
|
||||||
protected void initDefaultStrategies() {
|
public void setMessageConverters(HttpMessageConverter<?>[] messageConverters) {
|
||||||
errorHandler = new SimpleHttpErrorHandler();
|
Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
|
||||||
messageConverters =
|
this.messageConverters = messageConverters;
|
||||||
new HttpMessageConverter[]{new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter()};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the array of message body converters. These converters are used to covert from and to HTTP requests and
|
* Returnsthe message body converters. These converters are used to convert
|
||||||
* responses.
|
* from and to HTTP requests and responses.
|
||||||
*/
|
*/
|
||||||
public HttpMessageConverter<?>[] getMessageConverters() {
|
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
|
* @param type the type to return converters for
|
||||||
* @return converts that support the given type
|
* @return converters that support the given type
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> List<HttpMessageConverter<T>> getSupportedMessageConverters(Class<T> type) {
|
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
|
* Set the error handler.
|
||||||
* responses.
|
|
||||||
*
|
|
||||||
* <strong>Note</strong> that setting this property overrides the {@linkplain #initDefaultStrategies() default strategies}.
|
|
||||||
*/
|
*/
|
||||||
public void setMessageConverters(HttpMessageConverter<?>[] messageConverters) {
|
public void setErrorHandler(ResponseErrorHandler errorHandler) {
|
||||||
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) {
|
|
||||||
Assert.notNull(errorHandler, "'errorHandler' must not be null");
|
Assert.notNull(errorHandler, "'errorHandler' must not be null");
|
||||||
this.errorHandler = errorHandler;
|
this.errorHandler = errorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the error handler. By default, this is the {@link DefaultResponseErrorHandler}.
|
||||||
|
*/
|
||||||
|
public ResponseErrorHandler getErrorHandler() {
|
||||||
|
return this.errorHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// GET
|
// GET
|
||||||
|
|
||||||
public <T> T getForObject(String url, Class<T> responseType, String... urlVariables) {
|
public <T> T getForObject(String url, Class<T> responseType, String... urlVariables)
|
||||||
checkForSupportedEntityConverter(responseType);
|
throws RestClientException {
|
||||||
|
|
||||||
|
checkForSupportedMessageConverter(responseType);
|
||||||
return execute(url, HttpMethod.GET, new GetCallback<T>(responseType),
|
return execute(url, HttpMethod.GET, new GetCallback<T>(responseType),
|
||||||
new HttpMessageConverterExtractor<T>(responseType), urlVariables);
|
new HttpMessageConverterExtractor<T>(responseType), urlVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getForObject(String url, Class<T> responseType, Map<String, String> urlVariables) {
|
public <T> T getForObject(String url, Class<T> responseType, Map<String, String> urlVariables)
|
||||||
checkForSupportedEntityConverter(responseType);
|
throws RestClientException {
|
||||||
|
|
||||||
|
checkForSupportedMessageConverter(responseType);
|
||||||
return execute(url, HttpMethod.GET, new GetCallback<T>(responseType),
|
return execute(url, HttpMethod.GET, new GetCallback<T>(responseType),
|
||||||
new HttpMessageConverterExtractor<T>(responseType), urlVariables);
|
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
|
// HEAD
|
||||||
|
|
||||||
public HttpHeaders headForHeaders(String url, String... urlVariables) {
|
public HttpHeaders headForHeaders(String url, String... urlVariables) throws RestClientException {
|
||||||
return execute(url, HttpMethod.HEAD, null, headersExtractor, urlVariables);
|
return execute(url, HttpMethod.HEAD, null, this.headersExtractor, urlVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpHeaders headForHeaders(String url, Map<String, String> urlVariables) {
|
public HttpHeaders headForHeaders(String url, Map<String, String> urlVariables) throws RestClientException {
|
||||||
return execute(url, HttpMethod.HEAD, null, headersExtractor, urlVariables);
|
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
|
// DELETE
|
||||||
|
|
||||||
public void delete(String url, String... urlVariables) {
|
public void delete(String url, String... urlVariables) throws RestClientException {
|
||||||
execute(url, HttpMethod.DELETE, null, null, urlVariables);
|
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);
|
execute(url, HttpMethod.DELETE, null, null, urlVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// OPTIONS
|
// OPTIONS
|
||||||
|
|
||||||
public EnumSet<HttpMethod> optionsForAllow(String url, String... urlVariables) {
|
public Set<HttpMethod> optionsForAllow(String url, String... urlVariables)
|
||||||
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, headersExtractor, urlVariables);
|
throws RestClientException {
|
||||||
|
|
||||||
|
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, this.headersExtractor, urlVariables);
|
||||||
return headers.getAllow();
|
return headers.getAllow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnumSet<HttpMethod> optionsForAllow(String url, Map<String, String> urlVariables) {
|
public Set<HttpMethod> optionsForAllow(String url, Map<String, String> urlVariables)
|
||||||
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, headersExtractor, urlVariables);
|
throws RestClientException {
|
||||||
|
|
||||||
|
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, this.headersExtractor, urlVariables);
|
||||||
return headers.getAllow();
|
return headers.getAllow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute
|
|
||||||
|
|
||||||
public <T> T execute(String url,
|
// general execution
|
||||||
HttpMethod method,
|
|
||||||
HttpRequestCallback requestCallback,
|
public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
|
||||||
HttpResponseExtractor<T> responseExtractor,
|
ResponseExtractor<T> responseExtractor, String... urlVariables)
|
||||||
String... urlVariables) {
|
throws RestClientException {
|
||||||
|
|
||||||
UriTemplate uriTemplate = new UriTemplate(url);
|
UriTemplate uriTemplate = new UriTemplate(url);
|
||||||
URI expanded = uriTemplate.expand(urlVariables);
|
URI expanded = uriTemplate.expand(urlVariables);
|
||||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T execute(String url,
|
public <T> T execute(String url,HttpMethod method, RequestCallback requestCallback,
|
||||||
HttpMethod method,
|
ResponseExtractor<T> responseExtractor, Map<String, String> urlVariables)
|
||||||
HttpRequestCallback requestCallback,
|
throws RestClientException {
|
||||||
HttpResponseExtractor<T> responseExtractor,
|
|
||||||
Map<String, String> urlVariables) {
|
|
||||||
UriTemplate uriTemplate = new UriTemplate(url);
|
UriTemplate uriTemplate = new UriTemplate(url);
|
||||||
URI expanded = uriTemplate.expand(urlVariables);
|
URI expanded = uriTemplate.expand(urlVariables);
|
||||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
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
|
* Execute the given method on the provided URI. The {@link ClientHttpRequest} is processed using the {@link
|
||||||
* HttpRequestCallback}; the response with the {@link HttpResponseExtractor}.
|
* RequestCallback}; the response with the {@link ResponseExtractor}.
|
||||||
*
|
* @param url the fully-expanded URL to connect to
|
||||||
* @param url the fully-expanded URL to connect to
|
* @param method the HTTP method to execute (GET, POST, etc.)
|
||||||
* @param method the HTTP method to execute (GET, POST, etc.)
|
* @param requestCallback object that prepares the request (can be <code>null</code>)
|
||||||
* @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>)
|
||||||
* @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}
|
||||||
* @return an arbitrary object, as returned by the {@link HttpResponseExtractor}
|
|
||||||
*/
|
*/
|
||||||
protected <T> T doExecute(URI url,
|
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
|
||||||
HttpMethod method,
|
ResponseExtractor<T> responseExtractor) throws RestClientException {
|
||||||
HttpRequestCallback requestCallback,
|
|
||||||
HttpResponseExtractor<T> responseExtractor) {
|
|
||||||
Assert.notNull(url, "'url' must not be null");
|
Assert.notNull(url, "'url' must not be null");
|
||||||
Assert.notNull(method, "'method' must not be null");
|
Assert.notNull(method, "'method' must not be null");
|
||||||
ClientHttpResponse response = null;
|
ClientHttpResponse response = null;
|
||||||
|
@ -311,7 +308,7 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new HttpIOException("I/O error: " + ex.getMessage(), ex);
|
throw new ResourceAccessException("I/O error: " + ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (response != null) {
|
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.
|
* converters} can convert the given type.
|
||||||
*
|
|
||||||
* @param type the type to check for
|
* @param type the type to check for
|
||||||
* @throws IllegalArgumentException if no supported entity converter can be found
|
* @throws IllegalArgumentException if no supported entity converter can be found
|
||||||
* @see HttpMessageConverter#supports(Class)
|
* @see HttpMessageConverter#supports(Class)
|
||||||
*/
|
*/
|
||||||
private void checkForSupportedEntityConverter(Class type) {
|
private void checkForSupportedMessageConverter(Class type) {
|
||||||
for (HttpMessageConverter<?> entityConverter : getMessageConverters()) {
|
for (HttpMessageConverter<?> entityConverter : getMessageConverters()) {
|
||||||
if (entityConverter.supports(type)) {
|
if (entityConverter.supports(type)) {
|
||||||
return;
|
return;
|
||||||
|
@ -337,30 +333,11 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
||||||
throw new IllegalArgumentException("Could not resolve HttpMessageConverter for [" + type.getName() + "]");
|
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
|
* Request callback implementation that prepares the request's accept headers.
|
||||||
* HttpMessageConverter entity converters}.
|
|
||||||
*/
|
*/
|
||||||
private class AcceptHeaderCallback implements HttpRequestCallback {
|
private class GetCallback<T> implements RequestCallback {
|
||||||
|
|
||||||
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 final Class<T> responseType;
|
private final Class<T> responseType;
|
||||||
|
|
||||||
|
@ -370,7 +347,7 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
||||||
|
|
||||||
public void doWithRequest(ClientHttpRequest request) throws IOException {
|
public void doWithRequest(ClientHttpRequest request) throws IOException {
|
||||||
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
|
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
|
||||||
for (HttpMessageConverter<?> entityConverter : getSupportedMessageConverters(responseType)) {
|
for (HttpMessageConverter<?> entityConverter : getSupportedMessageConverters(this.responseType)) {
|
||||||
List<MediaType> supportedMediaTypes = entityConverter.getSupportedMediaTypes();
|
List<MediaType> supportedMediaTypes = entityConverter.getSupportedMediaTypes();
|
||||||
for (MediaType supportedMediaType : supportedMediaTypes) {
|
for (MediaType supportedMediaType : supportedMediaTypes) {
|
||||||
if (supportedMediaType.getCharSet() != null) {
|
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;
|
private final Object request;
|
||||||
|
|
||||||
|
@ -398,19 +376,17 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void doWithRequest(ClientHttpRequest httpRequest) throws IOException {
|
public void doWithRequest(ClientHttpRequest httpRequest) throws IOException {
|
||||||
for (HttpMessageConverter entityConverter : getSupportedMessageConverters(request.getClass())) {
|
HttpMessageConverter entityConverter = getSupportedMessageConverters(this.request.getClass()).get(0);
|
||||||
entityConverter.write(request, httpRequest);
|
entityConverter.write(this.request, httpRequest);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response extractor that uses the registered {@linkplain HttpMessageConverter entity converters} to convert the
|
* Response extractor that uses the registered {@linkplain HttpMessageConverter entity converters}
|
||||||
* response into a type <code>T</code>.
|
* 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;
|
private final Class<T> responseType;
|
||||||
|
|
||||||
|
@ -421,29 +397,31 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
|
||||||
public T extractData(ClientHttpResponse response) throws IOException {
|
public T extractData(ClientHttpResponse response) throws IOException {
|
||||||
MediaType contentType = response.getHeaders().getContentType();
|
MediaType contentType = response.getHeaders().getContentType();
|
||||||
if (contentType == null) {
|
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()) {
|
for (MediaType supportedMediaType : messageConverter.getSupportedMediaTypes()) {
|
||||||
if (supportedMediaType.includes(contentType)) {
|
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 [" +
|
"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}.
|
* 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 {
|
public HttpHeaders extractData(ClientHttpResponse response) throws IOException {
|
||||||
return response.getHeaders();
|
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>
|
<html>
|
||||||
<body>
|
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -14,48 +14,42 @@
|
||||||
* limitations under the License.
|
* 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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.client.core.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenient super class for application classes that need REST access.
|
* 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
|
* <p>Requires a {@link ClientHttpRequestFactory} or a {@link RestTemplate} instance to be set.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @see #setRestTemplate(RestTemplate)
|
|
||||||
* @see RestTemplate
|
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
* @see #setRestTemplate
|
||||||
|
* @see org.springframework.web.client.RestTemplate
|
||||||
*/
|
*/
|
||||||
public class RestGatewaySupport {
|
public class RestGatewaySupport {
|
||||||
|
|
||||||
/**
|
/** Logger available to subclasses */
|
||||||
* Logger available to subclasses.
|
|
||||||
*/
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new instance of the {@link RestGatewaySupport}, with default parameters.
|
* Construct a new instance of the {@link RestGatewaySupport}, with default parameters.
|
||||||
*
|
|
||||||
* @see RestTemplate#RestTemplate()
|
|
||||||
*/
|
*/
|
||||||
public RestGatewaySupport() {
|
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
|
* @see RestTemplate#RestTemplate(ClientHttpRequestFactory
|
||||||
*/
|
*/
|
||||||
public RestGatewaySupport(ClientHttpRequestFactory requestFactory) {
|
public RestGatewaySupport(ClientHttpRequestFactory requestFactory) {
|
||||||
|
@ -63,12 +57,6 @@ public class RestGatewaySupport {
|
||||||
this.restTemplate = new RestTemplate(requestFactory);
|
this.restTemplate = new RestTemplate(requestFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link RestTemplate} for the gateway.
|
|
||||||
*/
|
|
||||||
public RestTemplate getRestTemplate() {
|
|
||||||
return restTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link RestTemplate} for the gateway.
|
* Sets the {@link RestTemplate} for the gateway.
|
||||||
|
@ -78,4 +66,11 @@ public class RestGatewaySupport {
|
||||||
this.restTemplate = restTemplate;
|
this.restTemplate = restTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link RestTemplate} for the gateway.
|
||||||
|
*/
|
||||||
|
public RestTemplate getRestTemplate() {
|
||||||
|
return this.restTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
This package provides generic HTTP support classes,
|
Classes supporting the <code>org.springframework.web.client</code> package.
|
||||||
to be used by higher-level classes like RestTemplate.
|
Contains a base class for RestTemplate usage.
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http;
|
package org.springframework.http;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
@ -27,7 +27,7 @@ import static org.junit.Assert.*;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.util;
|
package org.springframework.http;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -26,7 +26,7 @@ import org.junit.Test;
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
*/
|
*/
|
||||||
public class MediaTypeTest {
|
public class MediaTypeTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void includes() throws Exception {
|
public void includes() throws Exception {
|
||||||
|
@ -118,4 +118,5 @@ public class MediaTypeTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http;
|
package org.springframework.http;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http;
|
package org.springframework.http;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -38,8 +38,8 @@ import org.mortbay.jetty.servlet.Context;
|
||||||
import org.mortbay.jetty.servlet.ServletHolder;
|
import org.mortbay.jetty.servlet.ServletHolder;
|
||||||
|
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
public abstract class AbstractHttpRequestFactoryTestCase {
|
public abstract class AbstractHttpRequestFactoryTestCase {
|
||||||
|
|
|
@ -14,12 +14,13 @@
|
||||||
* limitations under the License.
|
* 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.http.client.AbstractHttpRequestFactoryTestCase;
|
||||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
|
import org.springframework.http.client.CommonsClientHttpRequestFactory;
|
||||||
|
|
||||||
public class CommonsHttpRequestFactoryTest extends AbstractHttpRequestFactoryTestCase {
|
public class CommonsHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ClientHttpRequestFactory createRequestFactory() {
|
protected ClientHttpRequestFactory createRequestFactory() {
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.client;
|
package org.springframework.http.client;
|
||||||
|
|
||||||
public class SimpleHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase {
|
public class SimpleHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.converter;
|
package org.springframework.http.converter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ import static org.junit.Assert.*;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.http.MockHttpInputMessage;
|
import org.springframework.http.MockHttpInputMessage;
|
||||||
import org.springframework.web.http.MockHttpOutputMessage;
|
import org.springframework.http.MockHttpOutputMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.converter;
|
package org.springframework.http.converter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
@ -24,9 +24,9 @@ import static org.junit.Assert.*;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.http.MockHttpInputMessage;
|
import org.springframework.http.MockHttpInputMessage;
|
||||||
import org.springframework.web.http.MockHttpOutputMessage;
|
import org.springframework.http.MockHttpOutputMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.server;
|
package org.springframework.http.server;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.http.server;
|
package org.springframework.http.server;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
|
@ -14,12 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.client.core;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.Set;
|
||||||
import javax.servlet.GenericServlet;
|
import javax.servlet.GenericServlet;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
|
@ -37,11 +38,9 @@ import org.mortbay.jetty.Server;
|
||||||
import org.mortbay.jetty.servlet.Context;
|
import org.mortbay.jetty.servlet.Context;
|
||||||
import org.mortbay.jetty.servlet.ServletHolder;
|
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.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
|
* @author Arjen Poutsma
|
||||||
|
@ -103,11 +102,12 @@ public class RestTemplateIntegrationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void optionsForAllow() {
|
public void optionsForAllow() {
|
||||||
EnumSet<HttpMethod> allowed = template.optionsForAllow("http://localhost:8889/get");
|
Set<HttpMethod> allowed = template.optionsForAllow("http://localhost:8889/get");
|
||||||
assertEquals("Invalid response",
|
assertEquals("Invalid response",
|
||||||
EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE), allowed);
|
EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE), allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Servlet that returns and error message for a given status code.
|
* 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 static class GetServlet extends HttpServlet {
|
||||||
|
|
||||||
private final byte[] buf;
|
private final byte[] buf;
|
||||||
|
@ -145,6 +146,7 @@ public class RestTemplateIntegrationTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class PostServlet extends HttpServlet {
|
private static class PostServlet extends HttpServlet {
|
||||||
|
|
||||||
private final String s;
|
private final String s;
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.client.core;
|
package org.springframework.web.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -22,31 +22,29 @@ import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.easymock.EasyMock.*;
|
import static org.easymock.EasyMock.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.util.MediaType;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.client.HttpClientException;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.web.client.HttpIOException;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.client.HttpServerErrorException;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.converter.ByteArrayHttpMessageConverter;
|
import org.springframework.http.client.ClientHttpRequest;
|
||||||
import org.springframework.web.converter.HttpMessageConverter;
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
import org.springframework.web.converter.StringHttpMessageConverter;
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
import org.springframework.web.http.HttpHeaders;
|
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||||
import org.springframework.web.http.HttpMethod;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.web.http.HttpStatus;
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
import org.springframework.web.http.client.ClientHttpRequest;
|
|
||||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
|
||||||
import org.springframework.web.http.client.ClientHttpResponse;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class RestTemplateTest {
|
public class RestTemplateTests {
|
||||||
|
|
||||||
private RestTemplate template;
|
private RestTemplate template;
|
||||||
|
|
||||||
|
@ -56,7 +54,7 @@ public class RestTemplateTest {
|
||||||
|
|
||||||
private ClientHttpResponse response;
|
private ClientHttpResponse response;
|
||||||
|
|
||||||
private HttpErrorHandler errorHandler;
|
private ResponseErrorHandler errorHandler;
|
||||||
|
|
||||||
private HttpMessageConverter converter;
|
private HttpMessageConverter converter;
|
||||||
|
|
||||||
|
@ -65,7 +63,7 @@ public class RestTemplateTest {
|
||||||
requestFactory = createMock(ClientHttpRequestFactory.class);
|
requestFactory = createMock(ClientHttpRequestFactory.class);
|
||||||
request = createMock(ClientHttpRequest.class);
|
request = createMock(ClientHttpRequest.class);
|
||||||
response = createMock(ClientHttpResponse.class);
|
response = createMock(ClientHttpResponse.class);
|
||||||
errorHandler = createMock(HttpErrorHandler.class);
|
errorHandler = createMock(ResponseErrorHandler.class);
|
||||||
converter = createMock(HttpMessageConverter.class);
|
converter = createMock(HttpMessageConverter.class);
|
||||||
template = new RestTemplate(requestFactory);
|
template = new RestTemplate(requestFactory);
|
||||||
template.setErrorHandler(errorHandler);
|
template.setErrorHandler(errorHandler);
|
||||||
|
@ -200,7 +198,7 @@ public class RestTemplateTest {
|
||||||
template.getForObject("http://example.com/{p}", String.class, "resource");
|
template.getForObject("http://example.com/{p}", String.class, "resource");
|
||||||
fail("UnsupportedMediaTypeException expected");
|
fail("UnsupportedMediaTypeException expected");
|
||||||
}
|
}
|
||||||
catch (HttpClientException ex) {
|
catch (RestClientException ex) {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
verifyMocks();
|
verifyMocks();
|
||||||
|
@ -309,7 +307,7 @@ public class RestTemplateTest {
|
||||||
|
|
||||||
replayMocks();
|
replayMocks();
|
||||||
|
|
||||||
EnumSet<HttpMethod> result = template.optionsForAllow("http://example.com");
|
Set<HttpMethod> result = template.optionsForAllow("http://example.com");
|
||||||
assertEquals("Invalid OPTIONS result", expected, result);
|
assertEquals("Invalid OPTIONS result", expected, result);
|
||||||
|
|
||||||
verifyMocks();
|
verifyMocks();
|
||||||
|
@ -330,7 +328,7 @@ public class RestTemplateTest {
|
||||||
template.getForObject("http://example.com/resource", String.class);
|
template.getForObject("http://example.com/resource", String.class);
|
||||||
fail("RestClientException expected");
|
fail("RestClientException expected");
|
||||||
}
|
}
|
||||||
catch (HttpIOException ex) {
|
catch (ResourceAccessException ex) {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue