SPR-8750 Refine 'Content-Type' update in MockHttpServletRequest/Response.

The initial solution kept these three in full sync at all times:
contentType field, characterEncoding field, 'Content-Type' header.
That is correct behavior, however it breaks existing tests that rely
on contentType and characterEncoding being equal to exactly what 
they were set to.

For example, consider:
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");

Ideally both contentType and the 'Content-Type' header would now be
"text/plain;charset=UTF-8". However, existing tests would expect 
that contentType is equal to "text/plain".

To avoid breaking existing tests, contentType and characterEncoding
will continue to be equal to exactly what they were set to while
the 'Content-Type' header will always include both the content 
type and the charset.

The only exception to this rule is when a 'Content-Type' header
is set explicitly, the contentType and characterEncoding fields will 
be updated accordingly, possibly overriding the existing values.
This commit is contained in:
Rossen Stoyanchev
2011-11-17 15:07:15 +00:00
parent 56608d6bd6
commit 63e235f215
11 changed files with 124 additions and 167 deletions

View File

@@ -310,18 +310,17 @@ public class MockHttpServletRequest implements HttpServletRequest {
public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
if (this.contentType != null) {
String type = removeCharset(this.contentType);
setContentType(type);
}
updateContentTypeHeader();
}
private String removeCharset(String contentType) {
int index = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
if (index != -1) {
contentType = contentType.substring(0, contentType.lastIndexOf(';', index));
private void updateContentTypeHeader() {
if (this.contentType != null) {
StringBuilder sb = new StringBuilder(this.contentType);
if (this.contentType.toLowerCase().indexOf(CHARSET_PREFIX) == -1 && this.characterEncoding != null) {
sb.append(";").append(CHARSET_PREFIX).append(this.characterEncoding);
}
doAddHeaderValue(CONTENT_TYPE_HEADER, sb.toString(), true);
}
return contentType;
}
public void setContent(byte[] content) {
@@ -340,10 +339,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length());
this.characterEncoding = encoding;
}
else if (this.characterEncoding != null) {
this.contentType += ";" + CHARSET_PREFIX + this.characterEncoding;
}
doAddHeaderValue(CONTENT_TYPE_HEADER, this.contentType, true);
updateContentTypeHeader();
}
}

View File

@@ -144,18 +144,17 @@ public class MockHttpServletResponse implements HttpServletResponse {
public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
this.charset = true;
if (this.contentType != null) {
String type = removeCharset(this.contentType);
setContentType(type);
}
updateContentTypeHeader();
}
private String removeCharset(String contentType) {
int index = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
if (index != -1) {
contentType = contentType.substring(0, contentType.lastIndexOf(';', index));
private void updateContentTypeHeader() {
if (this.contentType != null) {
StringBuilder sb = new StringBuilder(this.contentType);
if (this.contentType.toLowerCase().indexOf(CHARSET_PREFIX) == -1 && this.charset) {
sb.append(";").append(CHARSET_PREFIX).append(this.characterEncoding);
}
doAddHeaderValue(CONTENT_TYPE_HEADER, sb.toString(), true);
}
return contentType;
}
public String getCharacterEncoding() {
@@ -208,11 +207,9 @@ public class MockHttpServletResponse implements HttpServletResponse {
if (charsetIndex != -1) {
String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length());
this.characterEncoding = encoding;
this.charset = true;
}
else if (this.charset) {
this.contentType += ";" + CHARSET_PREFIX + this.characterEncoding;
}
doAddHeaderValue(CONTENT_TYPE_HEADER, this.contentType, true);
updateContentTypeHeader();
}
}