[ 
https://issues.apache.org/jira/browse/VELTOOLS-83?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

bruce sherrod updated VELTOOLS-83:
----------------------------------


I could implement this myself by extending VelocityViewServlet, if 
VelocityViewServlet.writerPool was protected instead of private -- or if a 
protected getWriterPool() method was added (similar to the protected 
getVelocityEngine() method).    This would be the minimum change that would 
allow
either behavior (given some programmer intervention).

I recognize that there are potential performance issues in writing first to a 
StringWriter rather than directly to the HttpServletResponse writer.  However, 
the VelocityViewServlet as it is currently implemented is IMO wrong -- it 
returns "200 OK" when there is an internal server error (unhandled exception).  
In its current form it cannot be used in a production environment -- we cannot 
allow end users to see the velocity error messages, and the error() method 
cannot be overridden to redirect to a nice error page.   The correct behavior, 
on error, is to interoperate with the container's error handling mechanism 
(e.g. redirect based on the rules specified in web.xml).

Given the choice between "faster and wrong" or "slower and correct", I'd rather 
have "slower and correct."

I did review VelocityLayoutTemplate, but this seems like a lot of unnecessary 
machinery -- if I use VelocityLayoutTemplate, I have to 2-pass render *every* 
page, just to get the effect I want, which is to render to a StringWriter 
first, then to the HttpServletResponse writer.




> VelocityViewServlet returns 200 OK on error 
> --------------------------------------------
>
>                 Key: VELTOOLS-83
>                 URL: https://issues.apache.org/jira/browse/VELTOOLS-83
>             Project: Velocity Tools
>          Issue Type: Bug
>          Components: VelocityView
>    Affects Versions: 1.3
>            Reporter: bruce sherrod
>
> When VelocityViewServlet reports and error (e.g. if an exception is thrown 
> from a $reference.method()), it returns a detailed error page with status 200.
> This interoperates with the web container poorly, as it cannot be caught and 
> redirected to a nice error page in a production environment (e.g. through the 
> <error-page> mechanism in web.xml).
> This is complicated by the fact that VelocityViewServlet writes directly to 
> the HttpResponseServlet writer, so once the template processing has begun, it 
> is no longer possible to call HttpServletResponse.sendError() and send, say, 
> a "500 Internal Server Error", which would be more appropriate.
> Here is a patch: change VelocityViewServlet.mergeTemplate() so that it 
> buffers to a StringWriter, and only writes to the HttpServletResponse writer 
> after the merge is completed.
> This way, users can override VelocityViewServlet.error() to call 
> response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR) if desired.
>     protected void mergeTemplate(Template template,
>                                  Context context,
>                                  HttpServletResponse response)
>         throws ResourceNotFoundException, ParseErrorException,
>                MethodInvocationException, IOException,
>                UnsupportedEncodingException, Exception
>     {
>         VelocityWriter vw = null;
>               // write to a temporary string buffer, so that if we have to 
> bail 
>               // and call HttpServletResponse.sendError(), we still can -- bs
>         //Writer writer = getResponseWriter(response);
>               StringWriter sw = new StringWriter();
>         try
>         {
>             vw = (VelocityWriter)writerPool.get();
>             if (vw == null)
>             {
>                 vw = new VelocityWriter(sw, 4 * 1024, true);
>             }
>             else
>             {
>                 vw.recycle(sw);
>             }
>             performMerge(template, context, vw);
>         }
>         finally
>         {
>             if (vw != null)
>             {
>                 try
>                 {
>                     // flush and put back into the pool
>                     // don't close to allow us to play
>                     // nicely with others.
>                     vw.flush();
>                                       // really write to the 
> HttpServletResponse
>                                       String output = 
> sw.getBuffer().toString();
>                                       Writer writer = 
> getResponseWriter(response);
>                                       writer.write(output);
>                     /* This hack sets the VelocityWriter's internal ref to the
>                      * PrintWriter to null to keep memory free while
>                      * the writer is pooled. See bug report #18951 */
>                     vw.recycle(null);
>                     writerPool.put(vw);
>                 }
>                 catch (Exception e)
>                 {
>                     velocity.getLog().debug("VelocityViewServlet: " +
>                                    "Trouble releasing VelocityWriter: " +
>                                    e.getMessage());
>                 }
>             }
>         }
>     }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


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

Reply via email to