Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

I also asked this on Stack Overflow

https://stackoverflow.com/questions/57073434/how-to-set-content-type-correctly-in-thymeleaf-when-mixing-html-and-json-templat has a similar question but solves it by using a secondary view resolver. I've implemented this approach and it accomplishes the functional requirement, but it seems like a clunky solution as I specify in my objection to approach #2 below.


However I'm able to use a single Thymeleaf templateResolver with the smart template mode resolution on file extensions (e.g. "view.xml" => XML mode, "view" => default mode, "view.txt" => TEXT mode). This template mode resolution from the view name file extension can be found at
AbstractConfigurableTemplateResolver::computeTemplateMode() which uses ContentTypeUtils::computeTemplateModeForTemplateName() in the source code.

Is there a way to accomplish a similar automatic view resolution with the appropriate content type?

It looks like content mime types are defined in ContentTypeUtils but it seems AbstractThymeleafViewResolver setContentType() only allows three ways to set contentType

  1. Calling setContentType explicitly on the view object
  2. Setting it in the view resolver
  3. Use the default text/html

1 would be the logical answer if I had a one-off controller, but I'm working on a large enterprise project where getting the view object before it's returned isn't even possible without a significant refactor.

2 seems unnecessarily bean-bloated for something that should be able to be resolved automatically (since the template mode is resolved automatically).

3 Doesn't work for multiple content types like xml in my case

It seems that not setting force content type should allow for automatic resolution. I gather this from the logical reverse of the comment at
AbstractThymeleafView::setForceContentType.

applied even if the template name ends in a known suffix:
     *   {@code .html}, {@code .htm}, {@code .xhtml},
     *   {@code .xml}, {@code .js}, {@code .json},
     *   {@code .css}, {@code .rss}, {@code .atom}, {@code .txt}.

this isn’t the case per the content type not being in the request.uri above.

but as specified above the smart content type resolution seems to only work if the file extension is in the request URI per SpringContentTypeUtils which relies on ContentTypeUtils::computeFileExtensionFromRequestPath.

SpringContentTypeUtils::computeViewContentType will rely on Spring's own ContentNegotiatingViewResolver per the comment

// First we will check if there is a content type already resolved by Spring's own content negotiation
// mechanism (see ContentNegotiatingViewResolver, which is autoconfigured in Spring Boot)

from

public static String computeViewContentType(
...        
        // First we will check if there is a content type already resolved by Spring's own content negotiation
        // mechanism (see ContentNegotiatingViewResolver, which is autoconfigured in Spring Boot)
        final MediaType negotiatedMediaType = (MediaType) webExchange.getAttributeValue(View.SELECTED_CONTENT_TYPE);
        if (negotiatedMediaType != null && negotiatedMediaType.isConcrete()) {
            final Charset negotiatedCharset = negotiatedMediaType.getCharset();
            if (negotiatedCharset != null) {
                return negotiatedMediaType.toString();
            } else {
                return ContentTypeUtils.combineContentTypeAndCharset(negotiatedMediaType.toString(), defaultCharset);
            }
        }

This seems to be the most promising path to explore.

For an example like the following, how should I approach this? Has anyone solved a similar problem?

Endpoint: /saml

Returns "samlMetadata.xml"

This seems relevant to:
#607 considered what I wanted but did something different linked below

Mapped an approach

Would the project owners be open to a refactor that enables the ViewResolver to have access to the template name (e.g. "view.xml") or template mode (e.g. XML) in order to set the content type automatically?

You must be logged in to vote

Replies: 0 comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
1 participant
Morty Proxy This is a proxified and sanitized view of the page, visit original site.