SPR-5260: RestTemplate
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.EnumSet;
|
||||
import javax.servlet.GenericServlet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.Context;
|
||||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
|
||||
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
|
||||
*/
|
||||
public class RestTemplateIntegrationTests {
|
||||
|
||||
private RestTemplate template;
|
||||
|
||||
private static Server jettyServer;
|
||||
|
||||
@BeforeClass
|
||||
public static void startJettyServer() throws Exception {
|
||||
jettyServer = new Server(8889);
|
||||
Context jettyContext = new Context(jettyServer, "/");
|
||||
String s = "H\u00e9llo W\u00f6rld";
|
||||
byte[] bytes = s.getBytes("UTF-8");
|
||||
jettyContext.addServlet(new ServletHolder(new GetServlet(bytes, "text/plain;charset=utf-8")), "/get");
|
||||
jettyContext
|
||||
.addServlet(new ServletHolder(new PostServlet(s, new URI("http://localhost:8889/post/1"))), "/post");
|
||||
jettyContext.addServlet(new ServletHolder(new ErrorServlet(404)), "/errors/notfound");
|
||||
jettyContext.addServlet(new ServletHolder(new ErrorServlet(500)), "/errors/server");
|
||||
jettyServer.start();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void createTemplate() {
|
||||
// template = new RestTemplate();
|
||||
template = new RestTemplate(new CommonsClientHttpRequestFactory());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopJettyServer() throws Exception {
|
||||
if (jettyServer != null) {
|
||||
jettyServer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getString() {
|
||||
String s = template.getForObject("http://localhost:8889/{method}", String.class, "get");
|
||||
assertEquals("Invalid content", "H\u00e9llo W\u00f6rld", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postString() throws URISyntaxException {
|
||||
URI location = template.postForLocation("http://localhost:8889/{method}", "H\u00e9llo W\u00f6rld", "post");
|
||||
assertEquals("Invalid location", new URI("http://localhost:8889/post/1"), location);
|
||||
}
|
||||
|
||||
@Test(expected = HttpClientErrorException.class)
|
||||
public void notFound() {
|
||||
template.execute("http://localhost:8889/errors/notfound", HttpMethod.GET, null, null);
|
||||
}
|
||||
|
||||
@Test(expected = HttpServerErrorException.class)
|
||||
public void serverError() {
|
||||
template.execute("http://localhost:8889/errors/server", HttpMethod.GET, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optionsForAllow() {
|
||||
EnumSet<HttpMethod> allowed = template.optionsForAllow("http://localhost:8889/get");
|
||||
assertEquals("Invalid response",
|
||||
EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE), allowed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Servlet that returns and error message for a given status code.
|
||||
*/
|
||||
private static class ErrorServlet extends GenericServlet {
|
||||
|
||||
private final int sc;
|
||||
|
||||
private ErrorServlet(int sc) {
|
||||
this.sc = sc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
|
||||
((HttpServletResponse) response).sendError(sc);
|
||||
}
|
||||
}
|
||||
|
||||
private static class GetServlet extends HttpServlet {
|
||||
|
||||
private final byte[] buf;
|
||||
|
||||
private final String contentType;
|
||||
|
||||
private GetServlet(byte[] buf, String contentType) {
|
||||
this.buf = buf;
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
response.setContentLength(buf.length);
|
||||
response.setContentType(contentType);
|
||||
FileCopyUtils.copy(buf, response.getOutputStream());
|
||||
}
|
||||
}
|
||||
|
||||
private static class PostServlet extends HttpServlet {
|
||||
|
||||
private final String s;
|
||||
|
||||
private final URI location;
|
||||
|
||||
private PostServlet(String s, URI location) {
|
||||
this.s = s;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
assertTrue("Invalid request content-length", request.getContentLength() > 0);
|
||||
assertNotNull("No content-type", request.getContentType());
|
||||
String body = FileCopyUtils.copyToString(request.getReader());
|
||||
assertEquals("Invalid request body", s, body);
|
||||
response.setStatus(HttpServletResponse.SC_CREATED);
|
||||
response.setHeader("Location", location.toASCIIString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* 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.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.easymock.EasyMock.*;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.util.MediaType;
|
||||
import org.springframework.web.client.HttpClientException;
|
||||
import org.springframework.web.client.HttpIOException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.web.converter.HttpMessageConverter;
|
||||
import org.springframework.web.converter.StringHttpMessageConverter;
|
||||
import org.springframework.web.http.HttpHeaders;
|
||||
import org.springframework.web.http.HttpMethod;
|
||||
import org.springframework.web.http.HttpStatus;
|
||||
import org.springframework.web.http.client.ClientHttpRequest;
|
||||
import org.springframework.web.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.web.http.client.ClientHttpResponse;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class RestTemplateTest {
|
||||
|
||||
private RestTemplate template;
|
||||
|
||||
private ClientHttpRequestFactory requestFactory;
|
||||
|
||||
private ClientHttpRequest request;
|
||||
|
||||
private ClientHttpResponse response;
|
||||
|
||||
private HttpErrorHandler errorHandler;
|
||||
|
||||
private HttpMessageConverter converter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
requestFactory = createMock(ClientHttpRequestFactory.class);
|
||||
request = createMock(ClientHttpRequest.class);
|
||||
response = createMock(ClientHttpResponse.class);
|
||||
errorHandler = createMock(HttpErrorHandler.class);
|
||||
converter = createMock(HttpMessageConverter.class);
|
||||
template = new RestTemplate(requestFactory);
|
||||
template.setErrorHandler(errorHandler);
|
||||
template.setMessageConverters(new HttpMessageConverter<?>[]{converter});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSupportedMessageBodyConverters() {
|
||||
ByteArrayHttpMessageConverter byteArrayConverter = new ByteArrayHttpMessageConverter();
|
||||
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
||||
template.setMessageConverters(new HttpMessageConverter<?>[]{byteArrayConverter, stringConverter});
|
||||
|
||||
List<HttpMessageConverter<String>> result = template.getSupportedMessageConverters(String.class);
|
||||
assertEquals("Invalid amount of String converters", 1, result.size());
|
||||
assertEquals("Invalid String converters", stringConverter, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void varArgsTemplateVariables() throws Exception {
|
||||
expect(requestFactory.createRequest(new URI("http://example.com/hotels/42/bookings/21"), HttpMethod.GET))
|
||||
.andReturn(request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
template.execute("http://example.com/hotels/{hotel}/bookings/{booking}", HttpMethod.GET, null, null, "42",
|
||||
"21");
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapTemplateVariables() throws Exception {
|
||||
expect(requestFactory.createRequest(new URI("http://example.com/hotels/42/bookings/42"), HttpMethod.GET))
|
||||
.andReturn(request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
Map<String, String> vars = Collections.singletonMap("hotel", "42");
|
||||
template.execute("http://example.com/hotels/{hotel}/bookings/{hotel}", HttpMethod.GET, null, null, vars);
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorHandling() throws Exception {
|
||||
expect(requestFactory.createRequest(new URI("http://example.com"), HttpMethod.GET)).andReturn(request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(true);
|
||||
errorHandler.handleError(response);
|
||||
expectLastCall().andThrow(new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR));
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
try {
|
||||
template.execute("http://example.com", HttpMethod.GET, null, null);
|
||||
fail("HttpServerErrorException expected");
|
||||
}
|
||||
catch (HttpServerErrorException ex) {
|
||||
// expected
|
||||
}
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getForObject() throws Exception {
|
||||
expect(converter.supports(String.class)).andReturn(true).times(3);
|
||||
MediaType textPlain = new MediaType("text", "plain");
|
||||
expect(converter.getSupportedMediaTypes()).andReturn(Collections.singletonList(textPlain)).times(2);
|
||||
expect(requestFactory.createRequest(new URI("http://example.com"), HttpMethod.GET)).andReturn(request);
|
||||
HttpHeaders requestHeaders = new HttpHeaders();
|
||||
expect(request.getHeaders()).andReturn(requestHeaders);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
responseHeaders.setContentType(textPlain);
|
||||
expect(response.getHeaders()).andReturn(responseHeaders);
|
||||
String expected = "Hello World";
|
||||
expect(converter.read(String.class, response)).andReturn(expected);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
String result = template.getForObject("http://example.com", String.class);
|
||||
assertEquals("Invalid GET result", expected, result);
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getForObjectUnsupportedClass() throws Exception {
|
||||
expect(converter.supports(String.class)).andReturn(false);
|
||||
|
||||
replayMocks();
|
||||
|
||||
try {
|
||||
template.getForObject("http://example.com/{p}", String.class, "resource");
|
||||
fail("IllegalArgumentException expected");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUnsupportedMediaType() throws Exception {
|
||||
expect(converter.supports(String.class)).andReturn(true).times(3);
|
||||
MediaType supportedMediaType = new MediaType("foo", "bar");
|
||||
expect(converter.getSupportedMediaTypes()).andReturn(Collections.singletonList(supportedMediaType)).times(2);
|
||||
expect(requestFactory.createRequest(new URI("http://example.com/resource"), HttpMethod.GET)).andReturn(request);
|
||||
HttpHeaders requestHeaders = new HttpHeaders();
|
||||
expect(request.getHeaders()).andReturn(requestHeaders);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
MediaType contentType = new MediaType("bar", "baz");
|
||||
responseHeaders.setContentType(contentType);
|
||||
expect(response.getHeaders()).andReturn(responseHeaders);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
try {
|
||||
template.getForObject("http://example.com/{p}", String.class, "resource");
|
||||
fail("UnsupportedMediaTypeException expected");
|
||||
}
|
||||
catch (HttpClientException ex) {
|
||||
// expected
|
||||
}
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headForHeaders() throws Exception {
|
||||
expect(requestFactory.createRequest(new URI("http://example.com"), HttpMethod.HEAD)).andReturn(request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
expect(response.getHeaders()).andReturn(responseHeaders);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
HttpHeaders result = template.headForHeaders("http://example.com");
|
||||
|
||||
assertSame("Invalid headers returned", responseHeaders, result);
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postForLocation() throws Exception {
|
||||
expect(converter.supports(String.class)).andReturn(true).times(2);
|
||||
expect(requestFactory.createRequest(new URI("http://example.com"), HttpMethod.POST)).andReturn(request);
|
||||
String helloWorld = "Hello World";
|
||||
converter.write(helloWorld, request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
URI expected = new URI("http://example.com/hotels");
|
||||
responseHeaders.setLocation(expected);
|
||||
expect(response.getHeaders()).andReturn(responseHeaders);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
URI result = template.postForLocation("http://example.com", helloWorld);
|
||||
assertEquals("Invalid POST result", expected, result);
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postForLocationNoLocation() throws Exception {
|
||||
expect(converter.supports(String.class)).andReturn(true).times(2);
|
||||
expect(requestFactory.createRequest(new URI("http://example.com"), HttpMethod.POST)).andReturn(request);
|
||||
String helloWorld = "Hello World";
|
||||
converter.write(helloWorld, request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
expect(response.getHeaders()).andReturn(responseHeaders);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
URI result = template.postForLocation("http://example.com", helloWorld);
|
||||
assertNull("Invalid POST result", result);
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put() throws Exception {
|
||||
expect(converter.supports(String.class)).andReturn(true).times(2);
|
||||
expect(requestFactory.createRequest(new URI("http://example.com"), HttpMethod.PUT)).andReturn(request);
|
||||
String helloWorld = "Hello World";
|
||||
converter.write(helloWorld, request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
template.put("http://example.com", helloWorld);
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delete() throws Exception {
|
||||
expect(requestFactory.createRequest(new URI("http://example.com"), HttpMethod.DELETE)).andReturn(request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
template.delete("http://example.com");
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optionsForAllow() throws Exception {
|
||||
expect(requestFactory.createRequest(new URI("http://example.com"), HttpMethod.OPTIONS)).andReturn(request);
|
||||
expect(request.execute()).andReturn(response);
|
||||
expect(errorHandler.hasError(response)).andReturn(false);
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
EnumSet<HttpMethod> expected = EnumSet.of(HttpMethod.GET, HttpMethod.POST);
|
||||
responseHeaders.setAllow(expected);
|
||||
expect(response.getHeaders()).andReturn(responseHeaders);
|
||||
response.close();
|
||||
|
||||
replayMocks();
|
||||
|
||||
EnumSet<HttpMethod> result = template.optionsForAllow("http://example.com");
|
||||
assertEquals("Invalid OPTIONS result", expected, result);
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ioException() throws Exception {
|
||||
expect(converter.supports(String.class)).andReturn(true).times(2);
|
||||
MediaType mediaType = new MediaType("foo", "bar");
|
||||
expect(converter.getSupportedMediaTypes()).andReturn(Collections.singletonList(mediaType));
|
||||
expect(requestFactory.createRequest(new URI("http://example.com/resource"), HttpMethod.GET)).andReturn(request);
|
||||
expect(request.getHeaders()).andReturn(new HttpHeaders());
|
||||
expect(request.execute()).andThrow(new IOException());
|
||||
|
||||
replayMocks();
|
||||
|
||||
try {
|
||||
template.getForObject("http://example.com/resource", String.class);
|
||||
fail("RestClientException expected");
|
||||
}
|
||||
catch (HttpIOException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
verifyMocks();
|
||||
}
|
||||
|
||||
private void replayMocks() {
|
||||
replay(requestFactory, request, response, errorHandler, converter);
|
||||
}
|
||||
|
||||
private void verifyMocks() {
|
||||
verify(requestFactory, request, response, errorHandler, converter);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user