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>&lt;#ftl&gt;</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>&lt;#ftl&gt;</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