Skip to content

Commit edc80ff

Browse files
poutsmarstoyanchev
authored andcommitted
Use request contentType/encoding in ServletServetHttpRequest/Response
ServletServerHttpRequest now falls back on the contentType and the the characterEncoding of the ServletRequest, if the headers of the incoming request don't specify one. Similary ServletServerHttpResponse sets the contentType and the characterEncoding of the ServletResponse if not already set. This allows using the CharacterEncodingFilter to set a character encoding where the request doesn't specify one and have it be used in HttpMessageConverter's. SPR-9096
1 parent ff44c91 commit edc80ff

File tree

6 files changed

+62
-11
lines changed

6 files changed

+62
-11
lines changed

build-spring-framework/resources/changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Changes in version 3.1.1 (2012-02-13)
4242
* fixed request mapping bug involving direct vs pattern path matches with HTTP methods
4343
* removed check for HTTP "POST" when resolving multipart request controller method arguments
4444
* updated @RequestMapping and reference docs wrt differences between @MVC 3.1 and @MVC 2.5-3.0
45+
* ServletServerHttpRequest/Response fall back on the Content-Type and encoding of the request
4546

4647

4748
Changes in version 3.1 GA (2011-12-12)

org.springframework.web/src/main/java/org/springframework/http/MediaType.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -450,6 +450,14 @@ public String getParameter(String name) {
450450
return this.parameters.get(name);
451451
}
452452

453+
/**
454+
* Return all generic parameter values.
455+
* @return a read-only map, possibly empty, never <code>null</code>
456+
*/
457+
public Map<String, String> getParameters() {
458+
return parameters;
459+
}
460+
453461
/**
454462
* Indicate whether this {@code MediaType} includes the given media type.
455463
* <p>For instance, {@code text/*} includes {@code text/plain} and {@code text/html}, and {@code application/*+xml}

org.springframework.web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,15 +25,19 @@
2525
import java.net.URI;
2626
import java.net.URISyntaxException;
2727
import java.net.URLEncoder;
28+
import java.nio.charset.Charset;
2829
import java.util.Arrays;
2930
import java.util.Enumeration;
31+
import java.util.HashMap;
3032
import java.util.Iterator;
3133
import java.util.List;
3234
import java.util.Map;
35+
3336
import javax.servlet.http.HttpServletRequest;
3437

3538
import org.springframework.http.HttpHeaders;
3639
import org.springframework.http.HttpMethod;
40+
import org.springframework.http.MediaType;
3741
import org.springframework.util.Assert;
3842

3943
/**
@@ -90,14 +94,31 @@ public URI getURI() {
9094
public HttpHeaders getHeaders() {
9195
if (this.headers == null) {
9296
this.headers = new HttpHeaders();
93-
for (Enumeration headerNames = this.servletRequest.getHeaderNames(); headerNames.hasMoreElements();) {
97+
for (Enumeration<?> headerNames = this.servletRequest.getHeaderNames(); headerNames.hasMoreElements();) {
9498
String headerName = (String) headerNames.nextElement();
95-
for (Enumeration headerValues = this.servletRequest.getHeaders(headerName);
99+
for (Enumeration<?> headerValues = this.servletRequest.getHeaders(headerName);
96100
headerValues.hasMoreElements();) {
97101
String headerValue = (String) headerValues.nextElement();
98102
this.headers.add(headerName, headerValue);
99103
}
100104
}
105+
// HttpServletRequest exposes some headers as properties: we should include those if not already present
106+
if (this.headers.getContentType() == null && this.servletRequest.getContentType() != null) {
107+
MediaType contentType = MediaType.parseMediaType(this.servletRequest.getContentType());
108+
this.headers.setContentType(contentType);
109+
}
110+
if (this.headers.getContentType() != null && this.headers.getContentType().getCharSet() == null &&
111+
this.servletRequest.getCharacterEncoding() != null) {
112+
MediaType oldContentType = this.headers.getContentType();
113+
Charset charSet = Charset.forName(this.servletRequest.getCharacterEncoding());
114+
Map<String, String> params = new HashMap<String, String>(oldContentType.getParameters());
115+
params.put("charset", charSet.toString());
116+
MediaType newContentType = new MediaType(oldContentType.getType(), oldContentType.getSubtype(), params);
117+
this.headers.setContentType(newContentType);
118+
}
119+
if (this.headers.getContentLength() == -1 && this.servletRequest.getContentLength() != -1) {
120+
this.headers.setContentLength(this.servletRequest.getContentLength());
121+
}
101122
}
102123
return this.headers;
103124
}

org.springframework.web/src/main/java/org/springframework/http/server/ServletServerHttpResponse.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -83,6 +83,14 @@ private void writeHeaders() {
8383
this.servletResponse.addHeader(headerName, headerValue);
8484
}
8585
}
86+
// HttpServletResponse exposes some headers as properties: we should include those if not already present
87+
if (this.servletResponse.getContentType() == null && this.headers.getContentType() != null) {
88+
this.servletResponse.setContentType(this.headers.getContentType().toString());
89+
}
90+
if (this.servletResponse.getCharacterEncoding() == null && this.headers.getContentType() != null &&
91+
this.headers.getContentType().getCharSet() != null) {
92+
this.servletResponse.setCharacterEncoding(this.headers.getContentType().getCharSet().name());
93+
}
8694
this.headersWritten = true;
8795
}
8896
}

org.springframework.web/src/test/java/org/springframework/http/server/ServletServerHttpRequestTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,13 +17,15 @@
1717
package org.springframework.http.server;
1818

1919
import java.net.URI;
20+
import java.nio.charset.Charset;
2021
import java.util.List;
2122

2223
import org.junit.Before;
2324
import org.junit.Test;
2425

2526
import org.springframework.http.HttpHeaders;
2627
import org.springframework.http.HttpMethod;
28+
import org.springframework.http.MediaType;
2729
import org.springframework.mock.web.MockHttpServletRequest;
2830
import org.springframework.util.FileCopyUtils;
2931

@@ -67,6 +69,8 @@ public void getHeaders() throws Exception {
6769
mockRequest.addHeader(headerName, headerValue1);
6870
String headerValue2 = "value2";
6971
mockRequest.addHeader(headerName, headerValue2);
72+
mockRequest.setContentType("text/plain");
73+
mockRequest.setCharacterEncoding("UTF-8");
7074

7175
HttpHeaders headers = request.getHeaders();
7276
assertNotNull("No HttpHeaders returned", headers);
@@ -75,6 +79,8 @@ public void getHeaders() throws Exception {
7579
assertEquals("Invalid header values returned", 2, headerValues.size());
7680
assertTrue("Invalid header values returned", headerValues.contains(headerValue1));
7781
assertTrue("Invalid header values returned", headerValues.contains(headerValue2));
82+
assertEquals("Invalid Content-Type", new MediaType("text", "plain", Charset.forName("UTF-8")),
83+
headers.getContentType());
7884
}
7985

8086
@Test

org.springframework.web/src/test/java/org/springframework/http/server/ServletServerHttpResponseTests.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,16 +16,19 @@
1616

1717
package org.springframework.http.server;
1818

19+
import java.nio.charset.Charset;
1920
import java.util.List;
2021

21-
import static org.junit.Assert.*;
2222
import org.junit.Before;
2323
import org.junit.Test;
2424

25-
import org.springframework.mock.web.MockHttpServletResponse;
26-
import org.springframework.util.FileCopyUtils;
2725
import org.springframework.http.HttpHeaders;
2826
import org.springframework.http.HttpStatus;
27+
import org.springframework.http.MediaType;
28+
import org.springframework.mock.web.MockHttpServletResponse;
29+
import org.springframework.util.FileCopyUtils;
30+
31+
import static org.junit.Assert.*;
2932

3033
/**
3134
* @author Arjen Poutsma
@@ -56,12 +59,16 @@ public void getHeaders() throws Exception {
5659
headers.add(headerName, headerValue1);
5760
String headerValue2 = "value2";
5861
headers.add(headerName, headerValue2);
62+
headers.setContentType(new MediaType("text", "plain", Charset.forName("UTF-8")));
5963

6064
response.close();
6165
assertTrue("Header not set", mockResponse.getHeaderNames().contains(headerName));
6266
List headerValues = mockResponse.getHeaders(headerName);
6367
assertTrue("Header not set", headerValues.contains(headerValue1));
6468
assertTrue("Header not set", headerValues.contains(headerValue2));
69+
assertEquals("Invalid Content-Type", "text/plain;charset=UTF-8", mockResponse.getHeader("Content-Type"));
70+
assertEquals("Invalid Content-Type", "text/plain;charset=UTF-8", mockResponse.getContentType());
71+
assertEquals("Invalid Content-Type", "UTF-8", mockResponse.getCharacterEncoding());
6572
}
6673

6774
@Test

0 commit comments

Comments
 (0)