001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.web.client; 018 019import java.io.IOException; 020import java.net.URI; 021import java.nio.charset.Charset; 022import java.util.List; 023 024import org.springframework.http.HttpHeaders; 025import org.springframework.http.HttpMethod; 026import org.springframework.http.HttpStatus; 027import org.springframework.http.client.ClientHttpRequest; 028import org.springframework.http.client.ClientHttpRequestFactory; 029import org.springframework.http.client.ClientHttpResponse; 030import org.springframework.mock.http.client.MockClientHttpRequest; 031import org.springframework.mock.http.client.MockClientHttpResponse; 032import org.springframework.mock.web.MockHttpServletResponse; 033import org.springframework.test.web.servlet.MockMvc; 034import org.springframework.test.web.servlet.MvcResult; 035import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; 036import org.springframework.util.Assert; 037 038import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; 039 040/** 041 * A {@link ClientHttpRequestFactory} for requests executed via {@link MockMvc}. 042 * 043 * @author Rossen Stoyanchev 044 * @since 3.2 045 */ 046public class MockMvcClientHttpRequestFactory implements ClientHttpRequestFactory { 047 048 private static final Charset UTF8_CHARSET = Charset.forName("UTF-8"); 049 050 private final MockMvc mockMvc; 051 052 053 public MockMvcClientHttpRequestFactory(MockMvc mockMvc) { 054 Assert.notNull(mockMvc, "MockMvc must not be null"); 055 this.mockMvc = mockMvc; 056 } 057 058 059 @Override 060 public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) throws IOException { 061 return new MockClientHttpRequest(httpMethod, uri) { 062 @Override 063 public ClientHttpResponse executeInternal() throws IOException { 064 try { 065 MockHttpServletRequestBuilder requestBuilder = request(httpMethod, uri); 066 requestBuilder.content(getBodyAsBytes()); 067 requestBuilder.headers(getHeaders()); 068 MvcResult mvcResult = MockMvcClientHttpRequestFactory.this.mockMvc.perform(requestBuilder).andReturn(); 069 MockHttpServletResponse servletResponse = mvcResult.getResponse(); 070 HttpStatus status = HttpStatus.valueOf(servletResponse.getStatus()); 071 byte[] body = servletResponse.getContentAsByteArray(); 072 HttpHeaders headers = getResponseHeaders(servletResponse); 073 MockClientHttpResponse clientResponse = new MockClientHttpResponse(body, status); 074 clientResponse.getHeaders().putAll(headers); 075 return clientResponse; 076 } 077 catch (Exception ex) { 078 byte[] body = ex.toString().getBytes(UTF8_CHARSET); 079 return new MockClientHttpResponse(body, HttpStatus.INTERNAL_SERVER_ERROR); 080 } 081 } 082 }; 083 } 084 085 private HttpHeaders getResponseHeaders(MockHttpServletResponse response) { 086 HttpHeaders headers = new HttpHeaders(); 087 for (String name : response.getHeaderNames()) { 088 List<String> values = response.getHeaders(name); 089 for (String value : values) { 090 headers.add(name, value); 091 } 092 } 093 return headers; 094 } 095 096}