private void process()

in freemarker-javax-servlet/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java [776:911]


    private void process(
        HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {
        // Give chance to subclasses to perform preprocessing
        if (preprocessRequest(request, response)) {
            return;
        }
        
        if (bufferSize != null && !response.isCommitted()) {
            try {
                response.setBufferSize(bufferSize.intValue());
            } catch (IllegalStateException e) {
                LOG.debug("Can't set buffer size any more,", e);
            }
        }

        String templatePath = requestUrlToTemplatePath(request);

        if (LOG.isDebugEnabled()) {
            LOG.debug("Requested template " + StringUtil.jQuoteNoXSS(templatePath) + ".");
        }

        Locale locale = request.getLocale();
        if (locale == null || overrideResponseLocale != OverrideResponseLocale.NEVER) {
            locale = deduceLocale(templatePath, request, response);
        }

        final Template template;
        try {
            template = config.getTemplate(templatePath, locale);
        } catch (TemplateNotFoundException e) {
            if (exceptionOnMissingTemplate) {
                throw newServletExceptionWithFreeMarkerLogging(
                        "Template not found for name " + StringUtil.jQuoteNoXSS(templatePath) + ".", e);
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Responding HTTP 404 \"Not found\" for missing template "
                            + StringUtil.jQuoteNoXSS(templatePath) + ".", e);
                }
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "Page template not found");
                return;
            }
        } catch (freemarker.core.ParseException e) {
            throw newServletExceptionWithFreeMarkerLogging(
                    "Parsing error with template " + StringUtil.jQuoteNoXSS(templatePath) + ".", e);
        } catch (Exception e) {
            throw newServletExceptionWithFreeMarkerLogging(
                    "Unexpected error when loading template " + StringUtil.jQuoteNoXSS(templatePath) + ".", e);
        }

        boolean tempSpecContentTypeContainsCharset = false;
        if (response.getContentType() == null || overrideResponseContentType != OverrideResponseContentType.NEVER) {
            ContentType templateSpecificContentType = getTemplateSpecificContentType(template);
            if (templateSpecificContentType != null) {
                // With ResponseCharacterEncoding.LEGACY we should append the charset, but we don't do that for b. c.
                response.setContentType(
                        responseCharacterEncoding != ResponseCharacterEncoding.DO_NOT_SET
                                ? templateSpecificContentType.httpHeaderValue
                                : templateSpecificContentType.getMimeType());
                tempSpecContentTypeContainsCharset = templateSpecificContentType.containsCharset;
            } else if (response.getContentType() == null
                    || overrideResponseContentType == OverrideResponseContentType.ALWAYS) {
                if (responseCharacterEncoding == ResponseCharacterEncoding.LEGACY && !contentType.containsCharset) {
                    // In legacy mode we don't call response.setCharacterEncoding, so the charset must be set here:
                    response.setContentType(
                            contentType.httpHeaderValue + "; charset=" + getTemplateSpecificOutputEncoding(template));
                } else {
                    response.setContentType(contentType.httpHeaderValue);
                }
            }
        }
        
        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 (!tempSpecContentTypeContainsCharset) {
                    response.setCharacterEncoding(getTemplateSpecificOutputEncoding(template));
                }
            } else {
                response.setCharacterEncoding(forcedResponseCharacterEncoding.name());
            }
        }

        setBrowserCachingPolicy(response);

        ServletContext servletContext = getServletContext();
        try {
            logWarnOnObjectWrapperMismatch();
            
            TemplateModel model = createModel(wrapper, servletContext, request, response);

            // Give subclasses a chance to hook into preprocessing
            if (preTemplateProcess(request, response, template, model)) {
                try {
                    // Process the template
                    Environment env = template.createProcessingEnvironment(model, response.getWriter());
                    if (responseCharacterEncoding != ResponseCharacterEncoding.LEGACY) {
                        String actualOutputCharset = response.getCharacterEncoding();
                        if (actualOutputCharset != null) {
                            env.setOutputEncoding(actualOutputCharset);
                        }
                    }
                    processEnvironment(env, request, response);
                } finally {
                    // Give subclasses a chance to hook into postprocessing
                    postTemplateProcess(request, response, template, model);
                }
            }
        } catch (TemplateException e) {
            boolean suppressServletException;

            final TemplateExceptionHandler teh = config.getTemplateExceptionHandler();
            // Ensure that debug handler responses aren't rolled back:
            if (teh == TemplateExceptionHandler.HTML_DEBUG_HANDLER || teh == TemplateExceptionHandler.DEBUG_HANDLER
                    || teh.getClass().getName().contains("Debug")) {
                response.flushBuffer();

                // Apparently, if the status is 200, yet the servlet throw an exception, Jetty (9.4.53) closes the
                // connection, so the developer possibly won't see the debug error page (or not all of it).
                suppressServletException = true;
            } else {
                suppressServletException = false;
            }

            if (suppressServletException) {
                logServletExceptionWithFreemarkerLog("Error executing FreeMarker template", e);
                log("Error executing FreeMarker template. " +
                        "Servlet-level exception was suppressed to show debug page with HTTP 200. " +
                        "See earlier FreeMarker log message for details!");
            } else {
                throw newServletExceptionWithFreeMarkerLogging("Error executing FreeMarker template", e);
            }
        }
    }