VelocityServlet doesn't currently support the ability to override the
character encoding of its output on a per-request basis.  Instead,
it's hard-wired to the single value from the configuratin of the
RuntimeSingleton.  For I18N'd applications, this is painful.  The pain
can be alleviated by inserting a hook method for determining the
output character encoding to use on a per-request basis.

The above is a no-brainer.  However, I'd like the behavior of the
mergeTemplate() method be changed by having the default implementation
of this hook method first attempt to get the character encoding to use
from the response object, and only fall back to RuntimeSingleton's
config if not available from the respone.  Though this a backwards
incompatible change, I estimate that in 85% of use cases this change
will be transparent, as a Latin-1 encoding (e.g. ISO-8859-1) will
generally already be in use.  As VelocityServlet is the glue
integrating the Velocity engine into a request-response paradigm of
the Servlet API, a behavioral change like this which facilitates more
transparent integration makes a lot of sense.  Thoughts?


Index: VelocityServlet.java
===================================================================
RCS file: 
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/servlet/VelocityServlet.java,v
retrieving revision 1.49
diff -u -u -r1.49 VelocityServlet.java
--- VelocityServlet.java        4 May 2003 17:46:34 -0000       1.49
+++ VelocityServlet.java        15 Aug 2003 15:14:56 -0000
@@ -154,11 +154,6 @@
      *  Encoding for the output stream
      */
     public static final String DEFAULT_OUTPUT_ENCODING = "ISO-8859-1";
- 
-    /**
-     * The encoding to use when generating outputing.
-     */
-    private static String encoding = null;
 
     /**
      * The default content type.
@@ -205,9 +200,8 @@
         /*
          *  we can get these now that velocity is initialized
          */
-        defaultContentType = RuntimeSingleton.getString( CONTENT_TYPE, 
DEFAULT_CONTENT_TYPE);
-        encoding = RuntimeSingleton.getString( RuntimeSingleton.OUTPUT_ENCODING, 
-                        DEFAULT_OUTPUT_ENCODING);
+        defaultContentType = RuntimeSingleton.getString(CONTENT_TYPE,
+                                                        DEFAULT_CONTENT_TYPE);
     }
 
     /**
@@ -455,6 +449,7 @@
     {
         ServletOutputStream output = response.getOutputStream();
         VelocityWriter vw = null;
+        String encoding = getCharacterEncoding(context, response);
         
         try
         {
@@ -462,14 +457,16 @@
             
             if (vw == null)
             {
-                vw = new VelocityWriter( new OutputStreamWriter(output, encoding), 
4*1024, true);
+                vw = new VelocityWriter(new OutputStreamWriter(output,
+                                                               encoding),
+                                        4 * 1024, true);
             }
             else
             {
                 vw.recycle(new OutputStreamWriter(output, encoding));
             }
            
-            template.merge( context, vw);
+            template.merge(context, vw);
         }
         finally
         {
@@ -495,13 +492,35 @@
     }
 
     /**
-     *  Sets the content type of the response.  This is available to be overriden
-     *  by a derived class.
+     * Return the character encoding to use for servlet output.
+     * Overrides any configured Velocity encoding with any encoding
+     * already setup for the response.
      *
-     *  The default implementation is :
+     * @param context Velocity context, possibly used to derive which
+     * encoding to use.
+     * @param response Servlet reponse to client.
+     */
+    protected String getCharacterEncoding(Context context,
+                                          HttpServletResponse response)
+    {
+        String encoding = response.getCharacterEncoding();
+        if (encoding == null)
+        {
+            encoding =
+                RuntimeSingleton.getString(RuntimeSingleton.OUTPUT_ENCODING, 
+                                           DEFAULT_OUTPUT_ENCODING);
+        }
+        return encoding;
+    }
+
+    /**
+     *  Sets the content type of the response.  This is available to
+     *  be overriden by a derived class.
      *
+     *  The default implementation is :
+     *  <blockquote>
      *     response.setContentType( defaultContentType );
-     * 
+     *  </blockquote>
      *  where defaultContentType is set to the value of the default.contentType
      *  property, or "text/html" if that is not set.
      *

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to