1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.web.filter;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.nio.charset.Charset;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.Enumeration;
26 import java.util.LinkedHashMap;
27 import java.util.LinkedHashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import javax.servlet.FilterChain;
32 import javax.servlet.ServletException;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletRequestWrapper;
35 import javax.servlet.http.HttpServletResponse;
36
37 import org.springframework.http.HttpInputMessage;
38 import org.springframework.http.MediaType;
39 import org.springframework.http.converter.FormHttpMessageConverter;
40 import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
41 import org.springframework.http.server.ServletServerHttpRequest;
42 import org.springframework.util.LinkedMultiValueMap;
43 import org.springframework.util.MultiValueMap;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class HttpPutFormContentFilter extends OncePerRequestFilter {
61
62 private final FormHttpMessageConverter formConverter = new AllEncompassingFormHttpMessageConverter();
63
64
65
66
67 public void setCharset(Charset charset) {
68 this.formConverter.setCharset(charset);
69 }
70
71 @Override
72 protected void doFilterInternal(final HttpServletRequest request, HttpServletResponse response,
73 FilterChain filterChain) throws ServletException, IOException {
74
75 if (("PUT".equals(request.getMethod()) || "PATCH".equals(request.getMethod())) && isFormContentType(request)) {
76 HttpInputMessage inputMessage = new ServletServerHttpRequest(request) {
77 @Override
78 public InputStream getBody() throws IOException {
79 return request.getInputStream();
80 }
81 };
82 MultiValueMap<String, String> formParameters = formConverter.read(null, inputMessage);
83 HttpServletRequest wrapper = new HttpPutFormContentRequestWrapper(request, formParameters);
84 filterChain.doFilter(wrapper, response);
85 }
86 else {
87 filterChain.doFilter(request, response);
88 }
89 }
90
91 private boolean isFormContentType(HttpServletRequest request) {
92 String contentType = request.getContentType();
93 if (contentType != null) {
94 try {
95 MediaType mediaType = MediaType.parseMediaType(contentType);
96 return (MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType));
97 }
98 catch (IllegalArgumentException ex) {
99 return false;
100 }
101 }
102 else {
103 return false;
104 }
105 }
106
107 private static class HttpPutFormContentRequestWrapper extends HttpServletRequestWrapper {
108
109 private MultiValueMap<String, String> formParameters;
110
111 public HttpPutFormContentRequestWrapper(HttpServletRequest request, MultiValueMap<String, String> parameters) {
112 super(request);
113 this.formParameters = (parameters != null) ? parameters : new LinkedMultiValueMap<String, String>();
114 }
115
116 @Override
117 public String getParameter(String name) {
118 String queryStringValue = super.getParameter(name);
119 String formValue = this.formParameters.getFirst(name);
120 return (queryStringValue != null) ? queryStringValue : formValue;
121 }
122
123 @Override
124 public Map<String, String[]> getParameterMap() {
125 Map<String, String[]> result = new LinkedHashMap<String, String[]>();
126 Enumeration<String> names = this.getParameterNames();
127 while (names.hasMoreElements()) {
128 String name = names.nextElement();
129 result.put(name, this.getParameterValues(name));
130 }
131 return result;
132 }
133
134 @Override
135 public Enumeration<String> getParameterNames() {
136 Set<String> names = new LinkedHashSet<String>();
137 names.addAll(Collections.list(super.getParameterNames()));
138 names.addAll(this.formParameters.keySet());
139 return Collections.enumeration(names);
140 }
141
142 @Override
143 public String[] getParameterValues(String name) {
144 String[] queryStringValues = super.getParameterValues(name);
145 List<String> formValues = this.formParameters.get(name);
146 if (formValues == null) {
147 return queryStringValues;
148 }
149 else if (queryStringValues == null) {
150 return formValues.toArray(new String[formValues.size()]);
151 }
152 else {
153 List<String> result = new ArrayList<String>();
154 result.addAll(Arrays.asList(queryStringValues));
155 result.addAll(formValues);
156 return result.toArray(new String[result.size()]);
157 }
158 }
159 }
160
161 }