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:11 UTC
[07/25] incubator-freemarker git commit: Continued FREEMARKER-1
"Option to not to overwrite response ContentType in FreemarkerServlet": The
output_format setting of the Template also sets the response contentType,
similarly to the content_type custom att
Continued FREEMARKER-1 "Option to not to overwrite response ContentType in FreemarkerServlet": The output_format setting of the Template also sets the response contentType, similarly to the content_type custom attribute.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/2531f51e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/2531f51e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/2531f51e
Branch: refs/heads/2.3
Commit: 2531f51e7bc019480abdb35671b7c94bf75fc4b0
Parents: 3bf80f6
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 18 12:27:50 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 18 12:27:50 2015 +0200
----------------------------------------------------------------------
.../ext/servlet/FreemarkerServlet.java | 49 ++++++++++++++++----
.../ext/servlet/FreemarkerServletTest.java | 29 ++++++++++++
.../ext/servlet/outputFormatHeader.ftl | 20 ++++++++
3 files changed, 88 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/2531f51e/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 291df35..b4aa296 100644
--- a/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
+++ b/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
@@ -38,6 +38,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import com.sun.org.apache.xml.internal.serialize.OutputFormat;
+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
@@ -45,6 +47,7 @@ import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.cache.WebappTemplateLoader;
import freemarker.core.Configurable;
+import freemarker.core.UndefinedOutputFormat;
import freemarker.ext.jsp.TaglibFactory;
import freemarker.ext.jsp.TaglibFactory.ClasspathMetaInfTldSource;
import freemarker.ext.jsp.TaglibFactory.ClearMetaInfTldSource;
@@ -135,13 +138,24 @@ import freemarker.template.utility.StringUtil;
* HTTP client not to cache the returned page. The default is <tt>false</tt>.</li>
*
* <li><strong>{@value #INIT_PARAM_CONTENT_TYPE}</strong>: The Content-type HTTP header value used in the HTTP responses
- * (unless {@value #INIT_PARAM_OVERRIDE_RESPONSE_CONTENT_TYPE} is set to {@code false} and the response
- * {@code contentType} is already set by the time {@link FreemarkerServlet} is invoked). Defaults to
- * <tt>"text/html"</tt>. The value may include the charset (e.g. <tt>"text/html; charset=utf-8"</tt>). If the charset is
- * not specified in this init-param, then the charset (encoding) of the actual template file will be used (both in the
- * response HTTP header and for encoding the output stream). Note that this setting can be overridden on a per-template
- * basis by specifying a custom attribute named <tt>content_type</tt> in the <tt>attributes</tt> parameter of the
- * <tt><#ftl></tt> directive.</li>
+ * when nothing else specifies the MIME type. The things that may specify the MIME type (and hence this init-param is
+ * ignored), starting with the highest precedence, are:
+ * <ol>
+ * <li>The template's custom attribute name <tt>content_type</tt> in the <tt>attributes</tt> parameter of the
+ * <tt><#ftl></tt> directive. This is a legacy feature, deprecated by the {@link OutputFormat} mechanism.
+ * <li>The {@linkplain Template#getOutputFormat() output format of the template}, if that has non-{@code null} MIME-type
+ * ({@link OutputFormat#getMediaType()}). When a template has no output format specified, {@link UndefinedOutputFormat}
+ * is used, which has {@code null} MIME-type. (The output format of a template is deduced from {@link Configuration}
+ * settings, or can be specified directly in the template, like {@code <#ftl outputFormat="HTML">}. See the FreeMarker
+ * Manual for more about the output format mechanism. Note that setting an output format may turns on auto-escaping,
+ * so it's not just about MIME types.)
+ * <li>If the {@value #INIT_PARAM_OVERRIDE_RESPONSE_CONTENT_TYPE} init-param is {@code false} (the default is
+ * {@code true}), then the value of {@link HttpServletResponse#getContentType()} is used if that's non-{@code null}.
+ * </ol>
+ * If none of the above gives a MIME type, then this init-param does. Defaults to <tt>"text/html"</tt>. The
+ * value may include the charset (e.g. <tt>"text/html; charset=utf-8"</tt>). If the charset is not specified in this
+ * init-param, then the charset (encoding) of the actual template file will appended after it, which, as per the
+ * Servlet specification, also sets the actual encoding used to write the response body.</li>
*
* <li><strong>{@value #INIT_PARAM_OVERRIDE_RESPONSE_CONTENT_TYPE}</strong> (since 2.3.24): Specifies if we should
* always set the {@code contentType} in the {@link HttpServletResponse} to the value of the
@@ -725,9 +739,9 @@ public class FreemarkerServlet extends HttpServlet {
"Unexpected error when loading template " + StringUtil.jQuoteNoXSS(templatePath) + ".", e);
}
- Object attrContentType = template.getCustomAttribute("content_type");
- if (attrContentType != null) {
- response.setContentType(attrContentType.toString());
+ String templateSpecificContentType = getTemplateSpecificContentType(template);
+ if (templateSpecificContentType != null) {
+ response.setContentType(templateSpecificContentType);
} else {
if (overrideResponseContentType || response.getContentType() == null) {
if (noCharsetInContentType) {
@@ -767,6 +781,21 @@ public class FreemarkerServlet extends HttpServlet {
}
}
+ private String getTemplateSpecificContentType(final Template template) {
+ Object contentTypeAttr = template.getCustomAttribute("content_type");
+ if (contentTypeAttr != null) {
+ // Convert with toString() for backward compatibility
+ return contentTypeAttr.toString();
+ }
+
+ String outputFormatMimeType = template.getOutputFormat().getMimeType();
+ if (outputFormatMimeType != null) {
+ return outputFormatMimeType;
+ }
+
+ return null;
+ }
+
private ServletException newServletExceptionWithFreeMarkerLogging(String message, Throwable cause) throws ServletException {
if (cause instanceof TemplateException) {
// For backward compatibility, we log into the same category as Environment did when
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/2531f51e/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 9239ee0..5bb8dc9 100644
--- a/src/test/java/freemarker/ext/servlet/FreemarkerServletTest.java
+++ b/src/test/java/freemarker/ext/servlet/FreemarkerServletTest.java
@@ -198,6 +198,35 @@ public class FreemarkerServletTest {
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
assertEquals("text/plain", response.getContentType());
}
+
+ @Test
+ public void testContentTypeInitParams_outputFormatAlwaysWins_DefaultOverriding() throws ServletException, IOException {
+ MockHttpServletRequest request = createMockHttpServletRequest(servletContext, "/outputFormatHeader.ftl");
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ response.setContentType("application/json");
+ assertEquals("application/json", response.getContentType());
+
+ createFreemarkerServlet().doGet(request, response);
+ LOG.debug("response content: " + response.getContentAsString());
+
+ assertEquals(HttpServletResponse.SC_OK, response.getStatus());
+ assertEquals("text/plain", response.getContentType());
+ }
+
+ @Test
+ public void testContentTypeInitParams_outputFormatAlwaysWins_NoOverriding() throws ServletException, IOException {
+ MockHttpServletRequest request = createMockHttpServletRequest(servletContext, "/outputFormatHeader.ftl");
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ response.setContentType("application/json");
+ assertEquals("application/json", response.getContentType());
+
+ createFreemarkerServlet(FreemarkerServlet.INIT_PARAM_OVERRIDE_RESPONSE_CONTENT_TYPE, "false")
+ .doGet(request, response);
+ LOG.debug("response content: " + response.getContentAsString());
+
+ assertEquals(HttpServletResponse.SC_OK, response.getStatus());
+ assertEquals("text/plain", response.getContentType());
+ }
private FreemarkerServlet createFreemarkerServlet(String... initParams) throws ServletException {
MockServletConfig servletConfig = new MockServletConfig(servletContext);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/2531f51e/src/test/resources/freemarker/ext/servlet/outputFormatHeader.ftl
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/ext/servlet/outputFormatHeader.ftl b/src/test/resources/freemarker/ext/servlet/outputFormatHeader.ftl
new file mode 100644
index 0000000..27d7b2e
--- /dev/null
+++ b/src/test/resources/freemarker/ext/servlet/outputFormatHeader.ftl
@@ -0,0 +1,20 @@
+<#ftl outputFormat="plainText">
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+foo
\ No newline at end of file