Skip to content

ViewableWriter does not preserve MVC-selected response metadata when JSP/container updates Content-Type via setHeader #401

@robertpatrick

Description

@robertpatrick

Jakarta MVC 3.0 allows an application to explicitly control response metadata, including media type and headers, through normal JAX-RS mechanisms such as @produces and Response. During view rendering, Krazo should preserve that MVC-sel
ected response metadata instead of letting a later JSP/container default override it. (jakarta.ee (https://jakarta.ee/specifications/mvc/3.0/jakarta-mvc-spec-3.0))

In practice, when a controller renders a JSP view with an explicit non-HTML media type or explicit response headers, the final response can be changed by a later JSP/container Content-Type write. This appears to happen when the JSP/
container uses setHeader("Content-Type", "text/html") rather than only setContentType("text/html").

Expected behavior

If the controller has already selected response metadata, for example:

  • @produces("text/plain")
  • controller-set response headers
  • controller-set cache control

then JSP view rendering should not overwrite that explicit MVC/JAX-RS response metadata with the JSP default text/html. Jakarta Pages may establish an initial default response content type for the page, but that default should not erase
explicit response metadata already selected by MVC/JAX-RS. (jakarta.ee (https://jakarta.ee/specifications/pages/3.0/jakarta-server-pages-spec-3.0) jakarta.ee (https://jakarta.ee/specifications/mvc/3.0/jakarta-mvc-spec-3.0))

Actual behavior

Krazo already guards one path where JSP tries to force HTML through setContentType(...), but the equivalent setHeader("Content-Type", ...) path is not protected. As a result, explicit MVC-selected metadata can be lost during JSP
rendering.

Observed effects include:

  • explicit text/plain becoming final text/html
  • controller-set headers disappearing from the final response
  • controller-set cache-control disappearing from the final response

Root cause

ViewableWriter.MvcHttpServletResponse special-cases setContentType(...), but not the logically equivalent Content-Type mutation through setHeader(...) or addHeader(...).

In debugger-based investigation, the request entered ViewableWriter with the correct explicit media type already selected. The later overwrite occurred when JSP/container code wrote:

  • setHeader("Content-Type", "text/html")

That bypassed the existing guard.

Suggested fix

Handle Content-Type updates through setHeader(...) and addHeader(...) using the same preservation logic already applied to setContentType(...).

Reproducer shape

A minimal reproducer is:

  1. Controller returns a view and explicitly selects response metadata, such as @produces("text/plain") or custom headers.
  2. Krazo forwards to a JSP view.
  3. JSP/container writes the default HTML content type during rendering.
  4. Final response incorrectly loses the explicit MVC-selected metadata.

Related issues

Scope note

This issue is only about Krazo preserving explicit MVC/JAX-RS response metadata during JSP rendering. It should be tracked independently from any container-specific unwrapping problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions