You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2015/11/29 12:59:26 UTC
[22/25] incubator-freemarker git commit: FreemarkerServlet
ResponseCharacterEncoding init-param doesn't use the "force" prefix anymore,
you just specify the charset name as its value.
FreemarkerServlet ResponseCharacterEncoding init-param doesn't use the "force" prefix anymore, you just specify the charset name as its value.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/7540a51c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/7540a51c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/7540a51c
Branch: refs/heads/2.3
Commit: 7540a51c13e9b666bea6e8e5065cb1ee1712aee8
Parents: 947428a
Author: ddekany <dd...@apache.org>
Authored: Thu Nov 26 22:36:42 2015 +0100
Committer: ddekany <dd...@apache.org>
Committed: Thu Nov 26 23:44:19 2015 +0100
----------------------------------------------------------------------
.../ext/servlet/FreemarkerServlet.java | 81 +++++++++++++-------
src/manual/book.xml | 32 ++++++--
.../ext/servlet/FreemarkerServletTest.java | 12 +--
3 files changed, 85 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7540a51c/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java b/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
index d745010..092dc8e 100644
--- a/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
+++ b/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
@@ -21,6 +21,8 @@ package freemarker.ext.servlet;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -45,6 +47,7 @@ import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.cache.WebappTemplateLoader;
+import freemarker.core.BugException;
import freemarker.core.Configurable;
import freemarker.core.Environment;
import freemarker.core.OutputFormat;
@@ -162,8 +165,7 @@ import freemarker.template.utility.StringUtil;
* the default of it), the content type may include the charset (as in <tt>"text/html; charset=utf-8"</tt>), in which
* case that specifies the actual charset of the output. If the the {@value #INIT_PARAM_RESPONSE_CHARACTER_ENCODING}
* init-param is not set to {@value #INIT_PARAM_VALUE_LEGACY}, then specifying the charset in the
- * {@value #INIT_PARAM_CONTENT_TYPE} init-param is not allowed, and will cause servlet initialization error.
- * </li>
+ * {@value #INIT_PARAM_CONTENT_TYPE} init-param is not allowed, and will cause servlet initialization error.</li>
*
* <li><strong>{@value #INIT_PARAM_OVERRIDE_RESPONSE_CONTENT_TYPE}</strong> (since 2.3.24): Specifies when we should
* override the {@code contentType} that might be already set (i.e., non-{@code null}) in the
@@ -185,7 +187,7 @@ import freemarker.template.utility.StringUtil;
*
* <li><strong>{@value #INIT_PARAM_RESPONSE_CHARACTER_ENCODING}</strong> (since 2.3.24): Specifies how the
* {@link HttpServletResponse} "character encoding" (as in {@link HttpServletResponse#setCharacterEncoding(String)})
- * will deduced. The possible modes are:
+ * will be deduced. The possible modes are:
* <ul>
* <li>{@value #INIT_PARAM_VALUE_LEGACY}: This is the default for backward compatibility; in new applications, use
* {@value #INIT_PARAM_VALUE_FROM_TEMPLATE} (or some of the other options) instead. {@value #INIT_PARAM_VALUE_LEGACY}
@@ -195,8 +197,8 @@ import freemarker.template.utility.StringUtil;
* or writes it (though very few applications utilize that setting anyway). Also, it sets the charset of the servlet
* response by adding it to the response content type via calling {@link HttpServletResponse#setContentType(String)} (as
* that was the only way before Servlet 2.4), not via the more modern
- * {@link HttpServletResponse#setCharacterEncoding(String)} method. Note that the charset of a template usually
- * comes from {@link Configuration#getDefaultEncoding()} (i.e., from the {@code default_encoding} FreeMarker setting),
+ * {@link HttpServletResponse#setCharacterEncoding(String)} method. Note that the charset of a template usually comes
+ * from {@link Configuration#getDefaultEncoding()} (i.e., from the {@code default_encoding} FreeMarker setting),
* occasionally from {@link Configuration#getEncoding(Locale)} (when FreeMarker was configured to use different charsets
* depending on the locale) or even more rarely from {@link Configuration#getTemplateConfigurers()} (when FreeMarker was
* configured to use a specific charset for certain templates).
@@ -205,16 +207,16 @@ import freemarker.template.utility.StringUtil;
* template usually just inherits that from the {@link Configuration}), and if that's not set, then reads the source
* charset of the template, just like {@value #INIT_PARAM_VALUE_LEGACY}. Then it passes the charset acquired this way to
* {@link HttpServletResponse#setCharacterEncoding(String)} and {@link Environment#setOutputEncoding(String)}. (It
- * doesn't call the legacy {@link HttpServletResponse#setContentType(String)} API to set the charset.) (Note that if
- * the template has a {@code content_type} template attribute (which is deprecated) that specifies a charset, it will be
- * considered as the output charset of that template.)
+ * doesn't call the legacy {@link HttpServletResponse#setContentType(String)} API to set the charset.) (Note that if the
+ * template has a {@code content_type} template attribute (which is deprecated) that specifies a charset, it will be
+ * used as the output charset of that template.)
* <li>{@value #INIT_PARAM_VALUE_DO_NOT_SET}: {@link FreemarkerServlet} will not set the {@link HttpServletResponse}
* "character encoding". It will still call {@link Environment#setOutputEncoding(String)}, so that the running template
* will be aware of the charset used for the output.
- * <li>{@value #INIT_PARAM_VALUE_FORCE_PREFIX} + charset name, for example {@code force UTF-8}: The output charset will
- * be the one specified after "force" + space, regardless of everything. The charset specified this way is passed to
- * {@link HttpServletResponse#setCharacterEncoding(String)} and {@link Environment#setOutputEncoding(String)}. If the
- * charset name is not recognized by Java, the servlet initialization will fail.
+ * <li>A charset name, for example {@code UTF-8}: The output charset will the specified charset, regardless of
+ * everything. The charset specified this way is passed to {@link HttpServletResponse#setCharacterEncoding(String)} and
+ * {@link Environment#setOutputEncoding(String)}. If the charset name is not recognized by Java, the servlet
+ * initialization will fail.
* </ul>
*
* <li><strong>{@value #INIT_PARAM_BUFFER_SIZE}</strong>: Sets the size of the output buffer in bytes, or if "KB" or
@@ -417,7 +419,6 @@ public class FreemarkerServlet extends HttpServlet {
public static final String INIT_PARAM_VALUE_FROM_TEMPLATE = "fromTemplate";
public static final String INIT_PARAM_VALUE_LEGACY = "legacy";
public static final String INIT_PARAM_VALUE_DO_NOT_SET = "doNotSet";
- public static final String INIT_PARAM_VALUE_FORCE_PREFIX = "force ";
/**
* When set, the items defined in it will be added after those coming from the
@@ -668,9 +669,20 @@ public class FreemarkerServlet extends HttpServlet {
overrideResponseContentType = initParamValueToEnum(value, OverrideResponseContentType.values());
} else if (name.equals(INIT_PARAM_RESPONSE_CHARACTER_ENCODING)) {
responseCharacterEncoding = initParamValueToEnum(value, ResponseCharacterEncoding.values());
- if (responseCharacterEncoding == ResponseCharacterEncoding.FORCE_CHARSET) {
- String charsetName = value.substring(INIT_PARAM_VALUE_FORCE_PREFIX.length()).trim();
- forcedResponseCharacterEncoding = Charset.forName(charsetName);
+ if (responseCharacterEncoding == ResponseCharacterEncoding.SPECIFIC_CHARSET) {
+ try {
+ forcedResponseCharacterEncoding = Charset.forName(value);
+ } catch (IllegalArgumentException e) {
+ if (!(e instanceof UnsupportedCharsetException
+ || e instanceof IllegalCharsetNameException)) {
+ throw e;
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(StringUtil.jQuote(value));
+ sb.append(" isn't a valid charset name, nor it is any of the predefined values: ");
+ appendEnumInitParamValues(sb, ResponseCharacterEncoding.values());
+ throw new IllegalArgumentException(sb.toString());
+ }
}
} else if (name.equals(INIT_PARAM_OVERRIDE_RESPONSE_LOCALE)) {
overrideResponseLocale = initParamValueToEnum(value, OverrideResponseLocale.values());
@@ -846,7 +858,7 @@ public class FreemarkerServlet extends HttpServlet {
if (responseCharacterEncoding != ResponseCharacterEncoding.LEGACY
&& responseCharacterEncoding != ResponseCharacterEncoding.DO_NOT_SET) {
// Using the Servlet 2.4 way of setting character encoding.
- if (responseCharacterEncoding != ResponseCharacterEncoding.FORCE_CHARSET) {
+ if (responseCharacterEncoding != ResponseCharacterEncoding.SPECIFIC_CHARSET) {
if (!tempSpecContentTypeContainsCharset) {
response.setCharacterEncoding(getTemplateSpecificOutputEncoding(template));
}
@@ -1589,28 +1601,42 @@ public class FreemarkerServlet extends HttpServlet {
}
private <T extends InitParamValueEnum> T initParamValueToEnum(String initParamValue, T[] enumValues) {
+ T wildcardEnumValue = null;
for (T enumValue : enumValues) {
String enumInitParamValue = enumValue.getInitParamValue();
- if (initParamValue.equals(enumInitParamValue)
- || enumInitParamValue.endsWith("}") && initParamValue.startsWith(
- enumInitParamValue.substring(0, enumInitParamValue.indexOf("${")))) {
+ if (enumInitParamValue == null) {
+ if (wildcardEnumValue != null) {
+ throw new BugException();
+ }
+ wildcardEnumValue = enumValue;
+ } else if (initParamValue.equals(enumInitParamValue)) {
return enumValue;
}
}
+ if (wildcardEnumValue != null) {
+ return wildcardEnumValue;
+ }
StringBuilder sb = new StringBuilder();
sb.append(StringUtil.jQuote(initParamValue));
sb.append(" is not a one of the enumeration values: ");
+ appendEnumInitParamValues(sb, enumValues);
+ throw new IllegalArgumentException(sb.toString());
+ }
+
+ protected <T extends InitParamValueEnum> void appendEnumInitParamValues(StringBuilder sb, T[] enumValues) {
boolean first = true;
for (T value : enumValues) {
- if (!first) {
- sb.append(", ");
- } else {
- first = false;
+ String initParamValue = value.getInitParamValue();
+ if (initParamValue != null) { // Not a wildcard enum
+ if (!first) {
+ sb.append(", ");
+ } else {
+ first = false;
+ }
+ sb.append(StringUtil.jQuote(initParamValue));
}
- sb.append(StringUtil.jQuote(value.getInitParamValue()));
}
- throw new IllegalArgumentException(sb.toString());
}
/**
@@ -1643,7 +1669,7 @@ public class FreemarkerServlet extends HttpServlet {
LEGACY(INIT_PARAM_VALUE_LEGACY),
FROM_TEMPLATE(INIT_PARAM_VALUE_FROM_TEMPLATE),
DO_NOT_SET(INIT_PARAM_VALUE_DO_NOT_SET),
- FORCE_CHARSET(INIT_PARAM_VALUE_FORCE_PREFIX + "${charsetName}");
+ SPECIFIC_CHARSET(null);
private final String initParamValue;
@@ -1655,7 +1681,6 @@ public class FreemarkerServlet extends HttpServlet {
public String getInitParamValue() {
return initParamValue;
}
-
}
private enum OverrideResponseLocale implements InitParamValueEnum {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7540a51c/src/manual/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/book.xml b/src/manual/book.xml
index c6f8033..1654417 100644
--- a/src/manual/book.xml
+++ b/src/manual/book.xml
@@ -10427,7 +10427,11 @@ TemplateHashModel roundingModeEnums =
</init-param>
<init-param>
<param-name>ContentType</param-name>
- <param-value>text/html; charset=UTF-8</param-value> <!-- Forces UTF-8 output encoding! -->
+ <param-value>text/html</param-value>
+ </init-param>
+ <init-param>
+ <param-name>ResponseCharacterEncoding</param-name>
+ <param-value>UTF-8</param-value>
</init-param>
<!-- FreeMarker settings: -->
@@ -26080,9 +26084,8 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
the <literal>outputEncoding</literal> setting),
<literal>doNotSet</literal> (keeps what the caller has
already set in the <literal>ServletRespone</literal>) and
- <literal>force
- <replaceable>charsetName</replaceable></literal> (forces a
- specific charset).</para>
+ any valid charset name (forces a specific output
+ charset).</para>
</listitem>
</itemizedlist>
</listitem>
@@ -26420,7 +26423,7 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
<itemizedlist>
<listitem>
- <para><literal>OverrideResponseContentType</literal>.
+ <para><literal>OverrideResponseContentType</literal>:
Specifies when should we override the
<literal>contentType</literal> that's already set (i.e.,
non-<literal>null</literal>) in the
@@ -26433,13 +26436,30 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
</listitem>
<listitem>
- <para><literal>OverrideResponseLocale</literal>. Specifies
+ <para><literal>OverrideResponseLocale</literal>: Specifies
if should we override the <literal>contentType</literal>
that's already set (i.e., non-<literal>null</literal>) in
the <literal>HttpServletResponse</literal>. Earlier, we have
always set it, but now this behavior can be changed so that
we only set it if it wasn't already set.</para>
</listitem>
+
+ <listitem>
+ <para><literal>ResponseCharacterEncoding</literal>:
+ Deprecates the old (and quirky) logic of specifying the
+ output charset, which was putting it into the
+ <literal>ContentType</literal> init-param after the MIME
+ type, otherwise falling back to using the template file
+ charset. The possible values are <literal>legacy</literal>
+ (the default for backward compatibility),
+ <literal>fromTemplate</literal> (which is
+ <literal>legacy</literal> without quirks, and is aware of
+ the <literal>outputEncoding</literal> setting),
+ <literal>doNotSet</literal> (keeps what the caller has
+ already set in the <literal>ServletRespone</literal>) and
+ any valid charset name (forces a specific output
+ charset).</para>
+ </listitem>
</itemizedlist>
</listitem>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7540a51c/src/test/java/freemarker/ext/servlet/FreemarkerServletTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/servlet/FreemarkerServletTest.java b/src/test/java/freemarker/ext/servlet/FreemarkerServletTest.java
index f008280..6e5ce09 100644
--- a/src/test/java/freemarker/ext/servlet/FreemarkerServletTest.java
+++ b/src/test/java/freemarker/ext/servlet/FreemarkerServletTest.java
@@ -310,23 +310,23 @@ public class FreemarkerServletTest {
assertOutputEncodingEquals(
"UTF-16LE", // <- expected response.characterEncoding
"UTF-16LE", // <- expected env.outputEncoding
- FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
+ "UTF-16LE", // <- init-param
FOO_FTL);
assertOutputEncodingEquals(
"UTF-16LE", // <- expected response.characterEncoding
"UTF-16LE", // <- expected env.outputEncoding
- FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
+ "UTF-16LE", // <- init-param
FOO_SRC_UTF8_FTL);
assertOutputEncodingEquals(
"UTF-16LE", // <- expected response.characterEncoding
"UTF-16LE", // <- expected env.outputEncoding
- FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
+ "UTF-16LE", // <- init-param
FOO_OUT_UTF8_FTL);
try {
assertOutputEncodingEquals(
null, // <- expected response.characterEncoding
null, // <- expected env.outputEncoding
- FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "noSuchCharset", // <- init-param
+ "noSuchCharset", // <- init-param
FOO_FTL);
fail();
} catch (ServletException e) {
@@ -337,7 +337,7 @@ public class FreemarkerServletTest {
assertOutputEncodingEquals(
"UTF-16LE", // <- expected response.characterEncoding
"UTF-16LE", // <- expected env.outputEncoding
- FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
+ "UTF-16LE", // <- init-param
"text/html; charset=ISO-8859-2", // ContentType init-param
FOO_FTL);
fail();
@@ -348,7 +348,7 @@ public class FreemarkerServletTest {
assertOutputEncodingEquals(
"UTF-16LE", // <- expected response.characterEncoding
"UTF-16LE", // <- expected env.outputEncoding
- FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
+ "UTF-16LE", // <- init-param
CONTENT_TYPE_ATTR_WITH_CHARSET_FTL);
}