001/* 002 * Copyright 2002-2018 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.web.multipart.support; 018 019import java.util.Collections; 020import java.util.Enumeration; 021import java.util.Iterator; 022import java.util.List; 023import java.util.Map; 024 025import javax.servlet.http.HttpServletRequest; 026import javax.servlet.http.HttpServletRequestWrapper; 027 028import org.springframework.http.HttpHeaders; 029import org.springframework.http.HttpMethod; 030import org.springframework.lang.Nullable; 031import org.springframework.util.LinkedMultiValueMap; 032import org.springframework.util.MultiValueMap; 033import org.springframework.web.multipart.MultipartFile; 034import org.springframework.web.multipart.MultipartHttpServletRequest; 035 036/** 037 * Abstract base implementation of the MultipartHttpServletRequest interface. 038 * Provides management of pre-generated MultipartFile instances. 039 * 040 * @author Juergen Hoeller 041 * @author Arjen Poutsma 042 * @since 06.10.2003 043 */ 044public abstract class AbstractMultipartHttpServletRequest extends HttpServletRequestWrapper 045 implements MultipartHttpServletRequest { 046 047 @Nullable 048 private MultiValueMap<String, MultipartFile> multipartFiles; 049 050 051 /** 052 * Wrap the given HttpServletRequest in a MultipartHttpServletRequest. 053 * @param request the request to wrap 054 */ 055 protected AbstractMultipartHttpServletRequest(HttpServletRequest request) { 056 super(request); 057 } 058 059 060 @Override 061 public HttpServletRequest getRequest() { 062 return (HttpServletRequest) super.getRequest(); 063 } 064 065 @Override 066 public HttpMethod getRequestMethod() { 067 return HttpMethod.resolve(getRequest().getMethod()); 068 } 069 070 @Override 071 public HttpHeaders getRequestHeaders() { 072 HttpHeaders headers = new HttpHeaders(); 073 Enumeration<String> headerNames = getHeaderNames(); 074 while (headerNames.hasMoreElements()) { 075 String headerName = headerNames.nextElement(); 076 headers.put(headerName, Collections.list(getHeaders(headerName))); 077 } 078 return headers; 079 } 080 081 @Override 082 public Iterator<String> getFileNames() { 083 return getMultipartFiles().keySet().iterator(); 084 } 085 086 @Override 087 public MultipartFile getFile(String name) { 088 return getMultipartFiles().getFirst(name); 089 } 090 091 @Override 092 public List<MultipartFile> getFiles(String name) { 093 List<MultipartFile> multipartFiles = getMultipartFiles().get(name); 094 if (multipartFiles != null) { 095 return multipartFiles; 096 } 097 else { 098 return Collections.emptyList(); 099 } 100 } 101 102 @Override 103 public Map<String, MultipartFile> getFileMap() { 104 return getMultipartFiles().toSingleValueMap(); 105 } 106 107 @Override 108 public MultiValueMap<String, MultipartFile> getMultiFileMap() { 109 return getMultipartFiles(); 110 } 111 112 /** 113 * Determine whether the underlying multipart request has been resolved. 114 * @return {@code true} when eagerly initialized or lazily triggered, 115 * {@code false} in case of a lazy-resolution request that got aborted 116 * before any parameters or multipart files have been accessed 117 * @since 4.3.15 118 * @see #getMultipartFiles() 119 */ 120 public boolean isResolved() { 121 return (this.multipartFiles != null); 122 } 123 124 125 /** 126 * Set a Map with parameter names as keys and list of MultipartFile objects as values. 127 * To be invoked by subclasses on initialization. 128 */ 129 protected final void setMultipartFiles(MultiValueMap<String, MultipartFile> multipartFiles) { 130 this.multipartFiles = 131 new LinkedMultiValueMap<>(Collections.unmodifiableMap(multipartFiles)); 132 } 133 134 /** 135 * Obtain the MultipartFile Map for retrieval, 136 * lazily initializing it if necessary. 137 * @see #initializeMultipart() 138 */ 139 protected MultiValueMap<String, MultipartFile> getMultipartFiles() { 140 if (this.multipartFiles == null) { 141 initializeMultipart(); 142 } 143 return this.multipartFiles; 144 } 145 146 /** 147 * Lazily initialize the multipart request, if possible. 148 * Only called if not already eagerly initialized. 149 */ 150 protected void initializeMultipart() { 151 throw new IllegalStateException("Multipart request not initialized"); 152 } 153 154}