All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.restassured.module.mockmvc.internal.MockMvcRequestSenderImpl Maven / Gradle / Ivy

/*
 * Copyright 2016 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 io.restassured.module.mockmvc.internal;

import io.restassured.RestAssured;
import io.restassured.authentication.NoAuthScheme;
import io.restassured.builder.MultiPartSpecBuilder;
import io.restassured.config.EncoderConfig;
import io.restassured.filter.Filter;
import io.restassured.filter.log.RequestLoggingFilter;
import io.restassured.filter.time.TimingFilter;
import io.restassured.http.*;
import io.restassured.internal.RequestSpecificationImpl;
import io.restassured.internal.ResponseParserRegistrar;
import io.restassured.internal.ResponseSpecificationImpl;
import io.restassured.internal.filter.FilterContextImpl;
import io.restassured.internal.http.CharsetExtractor;
import io.restassured.internal.log.LogRepository;
import io.restassured.internal.support.PathSupport;
import io.restassured.internal.util.SafeExceptionRethrower;
import io.restassured.module.mockmvc.config.AsyncConfig;
import io.restassured.module.mockmvc.config.RestAssuredMockMvcConfig;
import io.restassured.module.mockmvc.intercept.MockHttpServletRequestBuilderInterceptor;
import io.restassured.module.mockmvc.response.MockMvcResponse;
import io.restassured.module.mockmvc.specification.MockMvcRequestAsyncConfigurer;
import io.restassured.module.mockmvc.specification.MockMvcRequestAsyncSender;
import io.restassured.module.mockmvc.specification.MockMvcRequestSender;
import io.restassured.specification.ResponseSpecification;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultHandler;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.*;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.Principal;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static io.restassured.internal.assertion.AssertParameter.notNull;
import static io.restassured.internal.support.PathSupport.mergeAndRemoveDoubleSlash;
import static io.restassured.module.mockmvc.internal.SpringSecurityClassPathChecker.isSpringSecurityInClasspath;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trimToNull;
import static org.springframework.http.HttpMethod.*;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;

class MockMvcRequestSenderImpl implements MockMvcRequestSender, MockMvcRequestAsyncConfigurer, MockMvcRequestAsyncSender {
    private static final String ATTRIBUTE_NAME_URL_TEMPLATE = "org.springframework.restdocs.urlTemplate";
    private static final String CONTENT_TYPE = "Content-Type";
    private static final String CHARSET = "charset";
    private static final String LINE_SEPARATOR = "line.separator";

    private final MockMvc mockMvc;
    private final Map params;
    private final Map queryParams;
    private final Map formParams;
    private final Map attributes;
    private final RestAssuredMockMvcConfig config;
    private final Object requestBody;
    private Headers headers;
    private final Cookies cookies;
    private final List multiParts;
    private final RequestLoggingFilter requestLoggingFilter;
    private final List resultHandlers;
    private final List requestPostProcessors;
    private final MockHttpServletRequestBuilderInterceptor interceptor;
    private final String basePath;
    private final ResponseSpecification responseSpecification;
    private final Object authentication;
    private final LogRepository logRepository;
    private final boolean isAsyncRequest;
    private final Map sessionAttributes;

    MockMvcRequestSenderImpl(MockMvc mockMvc, Map params, Map queryParams, Map formParams, Map attributes,
                             RestAssuredMockMvcConfig config, Object requestBody, Headers headers, Cookies cookies, Map sessionAttributes,
                             List multiParts, RequestLoggingFilter requestLoggingFilter, List resultHandlers,
                             List requestPostProcessors, MockHttpServletRequestBuilderInterceptor interceptor, String basePath, ResponseSpecification responseSpecification,
                             Object authentication, LogRepository logRepository) {
        this(mockMvc, params, queryParams, formParams, attributes, config, requestBody, headers, cookies, sessionAttributes, multiParts, requestLoggingFilter, resultHandlers, requestPostProcessors, interceptor,
                basePath, responseSpecification, authentication, logRepository, false);
    }

    private MockMvcRequestSenderImpl(MockMvc mockMvc, Map params, Map queryParams, Map formParams, Map attributes,
                                     RestAssuredMockMvcConfig config, Object requestBody, Headers headers, Cookies cookies, Map sessionAttributes,
                                     List multiParts, RequestLoggingFilter requestLoggingFilter, List resultHandlers,
                                     List requestPostProcessors, MockHttpServletRequestBuilderInterceptor interceptor, String basePath, ResponseSpecification responseSpecification,
                                     Object authentication, LogRepository logRepository, boolean isAsyncRequest) {
        this.mockMvc = mockMvc;
        this.params = params;
        this.queryParams = queryParams;
        this.formParams = formParams;
        this.attributes = attributes;
        this.config = config;
        this.requestBody = requestBody;
        this.headers = headers;
        this.cookies = cookies;
        this.sessionAttributes = sessionAttributes;
        this.multiParts = multiParts;
        this.requestLoggingFilter = requestLoggingFilter;
        this.resultHandlers = resultHandlers;
        this.requestPostProcessors = requestPostProcessors;
        this.interceptor = interceptor;
        this.basePath = basePath;
        this.responseSpecification = responseSpecification;
        this.authentication = authentication;
        this.logRepository = logRepository;
        this.isAsyncRequest = isAsyncRequest;
    }

    private Object assembleHeaders(MockHttpServletResponse response) {
        Collection headerNames = response.getHeaderNames();

        List
headers = new ArrayList
(); for (String headerName : headerNames) { List headerValues = response.getHeaders(headerName); for (String headerValue : headerValues) { headers.add(new Header(headerName, headerValue)); } } return new Headers(headers); } @SuppressWarnings("unchecked") private MockMvcResponse performRequest(MockHttpServletRequestBuilder requestBuilder) { MockHttpServletResponse response; if (interceptor != null) { interceptor.intercept(requestBuilder); } if (isSpringSecurityInClasspath() && authentication instanceof org.springframework.security.core.Authentication) { org.springframework.security.core.context.SecurityContextHolder.getContext().setAuthentication((org.springframework.security.core.Authentication) authentication); } else if (authentication instanceof Principal) { requestBuilder.principal((Principal) authentication); } for (RequestPostProcessor requestPostProcessor : requestPostProcessors) { requestBuilder.with(requestPostProcessor); } MockMvcRestAssuredResponseImpl restAssuredResponse; try { final long start = System.currentTimeMillis(); ResultActions perform = mockMvc.perform(requestBuilder); final long responseTime = System.currentTimeMillis() - start; if (!resultHandlers.isEmpty()) { for (ResultHandler resultHandler : resultHandlers) { perform.andDo(resultHandler); } } MvcResult mvcResult = getMvcResult(perform, isAsyncRequest); response = mvcResult.getResponse(); restAssuredResponse = new MockMvcRestAssuredResponseImpl(perform, logRepository); restAssuredResponse.setConfig(ConfigConverter.convertToRestAssuredConfig(config)); restAssuredResponse.setContent(response.getContentAsString()); restAssuredResponse.setContentType(response.getContentType()); restAssuredResponse.setHasExpectations(false); restAssuredResponse.setStatusCode(response.getStatus()); restAssuredResponse.setResponseHeaders(assembleHeaders(response)); restAssuredResponse.setRpr(getRpr()); restAssuredResponse.setStatusLine(assembleStatusLine(response, mvcResult.getResolvedException())); restAssuredResponse.setFilterContextProperties(new HashMap() {{ put(TimingFilter.RESPONSE_TIME_MILLISECONDS, responseTime); }}); if (responseSpecification != null) { responseSpecification.validate(ResponseConverter.toStandardResponse(restAssuredResponse)); } } catch (Exception e) { return SafeExceptionRethrower.safeRethrow(e); } finally { if (isSpringSecurityInClasspath()) { org.springframework.security.core.context.SecurityContextHolder.clearContext(); } } return restAssuredResponse; } private MvcResult getMvcResult(ResultActions perform, boolean isAsyncRequest) throws Exception { MvcResult mvcResult; if (isAsyncRequest) { MvcResult startedAsyncRequestProcessing = perform.andExpect(MockMvcResultMatchers.request().asyncStarted()).andReturn(); startedAsyncRequestProcessing.getAsyncResult(config.getAsyncConfig().timeoutInMs()); mvcResult = mockMvc.perform(asyncDispatch(startedAsyncRequestProcessing)).andReturn(); } else { mvcResult = perform.andReturn(); } return mvcResult; } private ResponseParserRegistrar getRpr() { if (responseSpecification != null && responseSpecification instanceof ResponseSpecificationImpl) { return ((ResponseSpecificationImpl) responseSpecification).getRpr(); } return new ResponseParserRegistrar(); } private String assembleStatusLine(MockHttpServletResponse response, Exception resolvedException) { StringBuilder builder = new StringBuilder(); builder.append(response.getStatus()); if (isNotBlank(response.getErrorMessage())) { builder.append(" ").append(response.getErrorMessage()); } else if (resolvedException != null) { builder.append(" ").append(resolvedException.getMessage()); } return builder.toString(); } private Object[] mapToArray(Map map) { if (map == null) { return new Object[0]; } return map.values().toArray(new Object[map.values().size()]); } private MockMvcResponse sendRequest(HttpMethod method, String path, Object[] pathParams) { notNull(path, "Path"); if (requestBody != null && !multiParts.isEmpty()) { throw new IllegalStateException("You cannot specify a request body and a multi-part body in the same request. Perhaps you want to change the body to a multi part?"); } String baseUri; if (isNotBlank(basePath)) { baseUri = mergeAndRemoveDoubleSlash(basePath, path); } else { baseUri = path; } final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(baseUri); if (!queryParams.isEmpty()) { new ParamApplier(queryParams) { @Override protected void applyParam(String paramName, String[] paramValues) { uriComponentsBuilder.queryParam(paramName, paramValues); } }.applyParams(); } String uri = uriComponentsBuilder.build().toUriString(); final MockHttpServletRequestBuilder request; if (multiParts.isEmpty()) { request = MockMvcRequestBuilders.request(method, uri, pathParams); } else if (method != POST) { throw new IllegalArgumentException("Currently multi-part file data uploading only works for " + POST); } else { request = MockMvcRequestBuilders.fileUpload(uri, pathParams); } String requestContentType = findContentType(); if (!params.isEmpty()) { new ParamApplier(params) { @Override protected void applyParam(String paramName, String[] paramValues) { request.param(paramName, paramValues); } }.applyParams(); if (StringUtils.isBlank(requestContentType) && method == POST && !isInMultiPartMode(request)) { setContentTypeToApplicationFormUrlEncoded(request); } } if (!formParams.isEmpty()) { if (method == GET) { throw new IllegalArgumentException("Cannot use form parameters in a GET request"); } new ParamApplier(formParams) { @Override protected void applyParam(String paramName, String[] paramValues) { request.param(paramName, paramValues); } }.applyParams(); boolean isInMultiPartMode = isInMultiPartMode(request); if (StringUtils.isBlank(requestContentType) && !isInMultiPartMode) { setContentTypeToApplicationFormUrlEncoded(request); } } if (!attributes.isEmpty()) { new ParamApplier(attributes) { @Override protected void applyParam(String paramName, String[] paramValues) { request.requestAttr(paramName, paramValues[0]); } }.applyParams(); } if (RestDocsClassPathChecker.isSpringRestDocsInClasspath() && config.getMockMvcConfig().shouldAutomaticallyApplySpringRestDocsMockMvcSupport()) { request.requestAttr(ATTRIBUTE_NAME_URL_TEMPLATE, PathSupport.getPath(uri)); } if (StringUtils.isNotBlank(requestContentType)) { request.contentType(MediaType.parseMediaType(requestContentType)); } if (headers.exist()) { for (Header header : headers) { request.header(header.getName(), header.getValue()); } } if (cookies.exist()) { for (Cookie cookie : cookies) { javax.servlet.http.Cookie servletCookie = new javax.servlet.http.Cookie(cookie.getName(), cookie.getValue()); if (cookie.hasComment()) { servletCookie.setComment(cookie.getComment()); } if (cookie.hasDomain()) { servletCookie.setDomain(cookie.getDomain()); } if (cookie.hasMaxAge()) { servletCookie.setMaxAge(cookie.getMaxAge()); } if (cookie.hasPath()) { servletCookie.setPath(cookie.getPath()); } if (cookie.hasVersion()) { servletCookie.setVersion(cookie.getVersion()); } request.cookie(servletCookie); } } if (!sessionAttributes.isEmpty()) { request.sessionAttrs(sessionAttributes); } if (!multiParts.isEmpty()) { MockMultipartHttpServletRequestBuilder multiPartRequest = (MockMultipartHttpServletRequestBuilder) request; for (MockMvcMultiPart multiPart : multiParts) { MockMultipartFile multipartFile; String fileName = multiPart.getFileName(); String controlName = multiPart.getControlName(); String mimeType = multiPart.getMimeType(); if (multiPart.isByteArray()) { multipartFile = new MockMultipartFile(controlName, fileName, mimeType, (byte[]) multiPart.getContent()); } else if (multiPart.isFile() || multiPart.isInputStream()) { InputStream inputStream; if (multiPart.isFile()) { try { inputStream = new FileInputStream((File) multiPart.getContent()); } catch (FileNotFoundException e) { return SafeExceptionRethrower.safeRethrow(e); } } else { inputStream = (InputStream) multiPart.getContent(); } try { multipartFile = new MockMultipartFile(controlName, fileName, mimeType, inputStream); } catch (IOException e) { return SafeExceptionRethrower.safeRethrow(e); } } else { // String multipartFile = new MockMultipartFile(controlName, fileName, mimeType, ((String) multiPart.getContent()).getBytes()); } multiPartRequest.file(multipartFile); } } if (requestBody != null) { if (requestBody instanceof byte[]) { request.content((byte[]) requestBody); } else if (requestBody instanceof File) { byte[] bytes = toByteArray((File) requestBody); request.content(bytes); } else { request.content(requestBody.toString()); } } logRequestIfApplicable(method, baseUri, path, pathParams); return performRequest(request); } // TODO Extract content-type from headers and apply charset if needed! private String findContentType() { String requestContentType = headers.getValue(CONTENT_TYPE); if (StringUtils.isBlank(requestContentType) && !multiParts.isEmpty()) { requestContentType = "multipart/" + config.getMultiPartConfig().defaultSubtype(); } EncoderConfig encoderConfig = config.getEncoderConfig(); if (requestContentType != null && encoderConfig.shouldAppendDefaultContentCharsetToContentTypeIfUndefined() && !StringUtils.containsIgnoreCase(requestContentType, CHARSET)) { // Append default charset to request content type requestContentType += "; charset="; if (encoderConfig.hasDefaultCharsetForContentType(requestContentType)) { requestContentType += encoderConfig.defaultCharsetForContentType(requestContentType); } else { requestContentType += encoderConfig.defaultContentCharset(); } } return requestContentType; } private static byte[] toByteArray(File file) { ByteArrayOutputStream ous = null; InputStream ios = null; try { byte[] buffer = new byte[4096]; ous = new ByteArrayOutputStream(); ios = new FileInputStream(file); int read = 0; while ((read = ios.read(buffer)) != -1) { ous.write(buffer, 0, read); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (ous != null) { ous.close(); } if (ios != null) { ios.close(); } } catch (IOException ignored) { } } return ous.toByteArray(); } private void setContentTypeToApplicationFormUrlEncoded(MockHttpServletRequestBuilder request) { String contentType = APPLICATION_FORM_URLENCODED_VALUE; EncoderConfig encoderConfig = config.getEncoderConfig(); if (encoderConfig.shouldAppendDefaultContentCharsetToContentTypeIfUndefined()) { contentType += "; charset="; if (encoderConfig.hasDefaultCharsetForContentType(contentType)) { contentType += encoderConfig.defaultCharsetForContentType(contentType); } else { contentType += encoderConfig.defaultContentCharset(); } } MediaType mediaType = MediaType.parseMediaType(contentType); request.contentType(mediaType); List
newHeaders = new ArrayList
(headers.asList()); newHeaders.add(new Header(CONTENT_TYPE, mediaType.toString())); headers = new Headers(newHeaders); } private boolean isInMultiPartMode(MockHttpServletRequestBuilder request) { return request instanceof MockMultipartHttpServletRequestBuilder; } private void logRequestIfApplicable(HttpMethod method, String uri, String originalPath, Object[] unnamedPathParams) { if (requestLoggingFilter == null) { return; } final RequestSpecificationImpl reqSpec = new RequestSpecificationImpl("http://localhost", RestAssured.UNDEFINED_PORT, "", new NoAuthScheme(), Collections.emptyList(), null, true, ConfigConverter.convertToRestAssuredConfig(config), logRepository, null); reqSpec.setMethod(method.toString()); reqSpec.path(uri); reqSpec.buildUnnamedPathParameterTuples(unnamedPathParams); if (params != null) { new ParamLogger(params) { protected void logParam(String paramName, Object paramValue) { reqSpec.param(paramName, paramValue); } }.logParams(); } if (queryParams != null) { new ParamLogger(queryParams) { protected void logParam(String paramName, Object paramValue) { reqSpec.queryParam(paramName, paramValue); } }.logParams(); } if (formParams != null) { new ParamLogger(formParams) { protected void logParam(String paramName, Object paramValue) { reqSpec.formParam(paramName, paramValue); } }.logParams(); } if (headers != null) { for (Header header : headers) { reqSpec.header(header); } } if (cookies != null) { for (Cookie cookie : cookies) { reqSpec.cookie(cookie); } } if (requestBody != null) { if (requestBody instanceof byte[]) { reqSpec.body((byte[]) requestBody); } else if (requestBody instanceof File) { String contentType = findContentType(); String charset = null; if (StringUtils.isNotBlank(contentType)) { charset = CharsetExtractor.getCharsetFromContentType(contentType); } if (charset == null) { charset = Charset.defaultCharset().toString(); } String string = fileToString((File) requestBody, charset); reqSpec.body(string); } else { reqSpec.body(requestBody); } } if (multiParts != null) { for (MockMvcMultiPart multiPart : multiParts) { reqSpec.multiPart(new MultiPartSpecBuilder(multiPart.getContent()). controlName(multiPart.getControlName()). fileName(multiPart.getFileName()). mimeType(multiPart.getMimeType()). build()); } } String uriPath = PathSupport.getPath(uri); String originalUriPath = PathSupport.getPath(originalPath); requestLoggingFilter.filter(reqSpec, null, new FilterContextImpl(uri, originalUriPath, uriPath, uri, uri, new Object[0], method.toString(), null, Collections.emptyList().iterator(), new HashMap())); } private String fileToString(File file, String charset) { StringBuilder fileContents = new StringBuilder((int) file.length()); Scanner scanner; try { scanner = new Scanner(file, charset); } catch (FileNotFoundException e) { throw new RuntimeException(e); } String lineSeparator = System.getProperty(LINE_SEPARATOR); try { while (scanner.hasNextLine()) { fileContents.append(scanner.nextLine()).append(lineSeparator); } return fileContents.toString(); } finally { scanner.close(); } } public MockMvcResponse get(String path, Object... pathParams) { return sendRequest(GET, path, pathParams); } public MockMvcResponse get(String path, Map pathParams) { return get(path, mapToArray(pathParams)); } public MockMvcResponse post(String path, Object... pathParams) { return sendRequest(POST, path, pathParams); } public MockMvcResponse post(String path, Map pathParams) { return post(path, mapToArray(pathParams)); } public MockMvcResponse put(String path, Object... pathParams) { return sendRequest(PUT, path, pathParams); } public MockMvcResponse put(String path, Map pathParams) { return put(path, mapToArray(pathParams)); } public MockMvcResponse delete(String path, Object... pathParams) { return sendRequest(DELETE, path, pathParams); } public MockMvcResponse delete(String path, Map pathParams) { return delete(path, mapToArray(pathParams)); } public MockMvcResponse head(String path, Object... pathParams) { return sendRequest(HEAD, path, pathParams); } public MockMvcResponse head(String path, Map pathParams) { return head(path, mapToArray(pathParams)); } public MockMvcResponse patch(String path, Object... pathParams) { return sendRequest(PATCH, path, pathParams); } public MockMvcResponse patch(String path, Map pathParams) { return patch(path, mapToArray(pathParams)); } public MockMvcResponse options(String path, Object... pathParams) { return sendRequest(OPTIONS, path, pathParams); } public MockMvcResponse options(String path, Map pathParams) { return options(path, mapToArray(pathParams)); } public MockMvcResponse get(URI uri) { return get(uri.toString()); } public MockMvcResponse post(URI uri) { return post(uri.toString()); } public MockMvcResponse put(URI uri) { return put(uri.toString()); } public MockMvcResponse delete(URI uri) { return delete(uri.toString()); } public MockMvcResponse head(URI uri) { return head(uri.toString()); } public MockMvcResponse patch(URI uri) { return patch(uri.toString()); } public MockMvcResponse options(URI uri) { return options(uri.toString()); } public MockMvcResponse get(URL url) { return get(url.toString()); } public MockMvcResponse post(URL url) { return post(url.toString()); } public MockMvcResponse put(URL url) { return put(url.toString()); } public MockMvcResponse delete(URL url) { return delete(url.toString()); } public MockMvcResponse head(URL url) { return head(url.toString()); } public MockMvcResponse patch(URL url) { return patch(url.toString()); } public MockMvcResponse options(URL url) { return options(url.toString()); } public MockMvcResponse get() { return get(""); } public MockMvcResponse post() { return post(""); } public MockMvcResponse put() { return put(""); } public MockMvcResponse delete() { return delete(""); } public MockMvcResponse head() { return head(""); } public MockMvcResponse patch() { return patch(""); } public MockMvcResponse options() { return options(""); } public MockMvcResponse request(Method method) { return request(method, ""); } public MockMvcResponse request(String method) { return request(method, ""); } public MockMvcResponse request(Method method, String path, Object... pathParams) { return request(notNull(method, Method.class).name(), path, pathParams); } public MockMvcResponse request(String method, String path, Object... pathParams) { return sendRequest(toValidHttpMethod(method), path, pathParams); } public MockMvcResponse request(Method method, URI uri) { return request(method, notNull(uri, URI.class).toString()); } public MockMvcResponse request(Method method, URL url) { return request(method, notNull(url, URL.class).toString()); } public MockMvcResponse request(String method, URI uri) { return request(method, notNull(uri, URI.class).toString()); } public MockMvcResponse request(String method, URL url) { return request(method, notNull(url, URL.class).toString()); } public MockMvcRequestAsyncConfigurer with() { return this; } public MockMvcRequestAsyncConfigurer and() { return this; } public MockMvcRequestAsyncConfigurer timeout(long duration, TimeUnit timeUnit) { RestAssuredMockMvcConfig newConfig = config.asyncConfig(new AsyncConfig(duration, timeUnit)); return new MockMvcRequestSenderImpl(mockMvc, params, queryParams, formParams, attributes, newConfig, requestBody, headers, cookies, sessionAttributes, multiParts, requestLoggingFilter, resultHandlers, requestPostProcessors, interceptor, basePath, responseSpecification, authentication, logRepository, isAsyncRequest); } public MockMvcRequestAsyncConfigurer timeout(long durationInMs) { return timeout(durationInMs, TimeUnit.MILLISECONDS); } public MockMvcRequestSender then() { return this; } public MockMvcRequestAsyncConfigurer async() { return new MockMvcRequestSenderImpl(mockMvc, params, queryParams, formParams, attributes, config, requestBody, headers, cookies, sessionAttributes, multiParts, requestLoggingFilter, resultHandlers, requestPostProcessors, interceptor, basePath, responseSpecification, authentication, logRepository, true); } private abstract static class ParamApplier { private Map map; protected ParamApplier(Map parameters) { this.map = parameters; } public void applyParams() { for (Map.Entry listEntry : map.entrySet()) { Object value = listEntry.getValue(); String[] stringValues; if (value instanceof Collection) { Collection col = (Collection) value; stringValues = new String[col.size()]; int index = 0; for (Object val : col) { stringValues[index] = val == null ? null : val.toString(); index++; } } else { stringValues = new String[1]; stringValues[0] = value == null ? null : value.toString(); } applyParam(listEntry.getKey(), stringValues); } } protected abstract void applyParam(String paramName, String[] paramValues); } private abstract static class ParamLogger { private Map map; protected ParamLogger(Map parameters) { this.map = parameters; } public void logParams() { for (Map.Entry stringListEntry : map.entrySet()) { Object value = stringListEntry.getValue(); Collection values; if (value instanceof Collection) { values = (Collection) value; } else { values = new ArrayList(); values.add(value); } for (Object theValue : values) { logParam(stringListEntry.getKey(), theValue); } } } protected abstract void logParam(String paramName, Object paramValue); } private HttpMethod toValidHttpMethod(String method) { String httpMethodAsString = notNull(trimToNull(method), "HTTP Method"); HttpMethod httpMethod = HttpMethod.resolve(httpMethodAsString.toUpperCase()); if (httpMethod == null) { throw new IllegalArgumentException("HTTP method '" + method + "' is not supported by MockMvc"); } return httpMethod; } }