@ -16,6 +16,13 @@
@@ -16,6 +16,13 @@
package org.springframework.web.servlet.view.freemarker ;
import java.util.Locale ;
import freemarker.template.Configuration ;
import org.springframework.lang.Nullable ;
import org.springframework.util.StringUtils ;
import org.springframework.web.servlet.View ;
import org.springframework.web.servlet.view.AbstractTemplateViewResolver ;
import org.springframework.web.servlet.view.AbstractUrlBasedView ;
@ -29,12 +36,19 @@ import org.springframework.web.servlet.view.AbstractUrlBasedView;
@@ -29,12 +36,19 @@ import org.springframework.web.servlet.view.AbstractUrlBasedView;
* < p > < b > Note : < / b > To ensure that the correct encoding is used when the rendering
* the response , set the { @linkplain # setContentType ( String ) content type } with an
* appropriate { @code charset } attribute & mdash ; for example ,
* { @code "text/html;charset=UTF-8" } .
* { @code "text/html;charset=UTF-8" } ; however , as of Spring Framework 6 . 2 , it is
* no longer strictly necessary to explicitly set the content type in the
* { @code FreeMarkerViewResolver } if you have set an explicit encoding via either
* { @link FreeMarkerView # setEncoding ( String ) } ,
* { @link FreeMarkerConfigurer # setDefaultEncoding ( String ) } , or
* { @link Configuration # setDefaultEncoding ( String ) } .
*
* < p > < b > Note : < / b > When chaining ViewResolvers , a { @code FreeMarkerViewResolver } will
* check for the existence of the specified template resources and only return
* a non - null { @code View } object if the template was actually found .
*
* < p > Note : Spring ' s FreeMarker support requires FreeMarker 2 . 3 . 26 or higher .
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1 . 1
@ -83,4 +97,65 @@ public class FreeMarkerViewResolver extends AbstractTemplateViewResolver {
@@ -83,4 +97,65 @@ public class FreeMarkerViewResolver extends AbstractTemplateViewResolver {
return ( getViewClass ( ) = = FreeMarkerView . class ? new FreeMarkerView ( ) : super . instantiateView ( ) ) ;
}
/ * *
* Delegates to { @code super . loadView ( viewName , locale ) } for standard behavior
* and then to { @link # postProcessView ( FreeMarkerView ) } for customization .
* @since 6 . 2
* @see org . springframework . web . servlet . view . UrlBasedViewResolver # loadView ( String , Locale )
* @see # postProcessView ( FreeMarkerView )
* /
@Override
@Nullable
protected View loadView ( String viewName , Locale locale ) throws Exception {
View view = super . loadView ( viewName , locale ) ;
if ( view instanceof FreeMarkerView freeMarkerView ) {
postProcessView ( freeMarkerView ) ;
}
return view ;
}
/ * *
* Post process the supplied { @link FreeMarkerView } after it has been { @linkplain
* org . springframework . web . servlet . view . UrlBasedViewResolver # loadView ( String , Locale )
* loaded } .
* < p > The default implementation attempts to override the
* { @linkplain org . springframework . web . servlet . view . AbstractView # setContentType ( String )
* content type } of the view with { @code "text/html;charset=<encoding>" } ,
* where { @code < encoding > } is equal to an explicitly configured character
* encoding for the underlying FreeMarker template file . If an explicit content
* type has been configured for this view resolver or if no explicit character
* encoding has been configured for the template file , this method does not
* modify the supplied { @code FreeMarkerView } .
* @since 6 . 2
* @see # loadView ( String , Locale )
* @see # setContentType ( String )
* @see org . springframework . web . servlet . view . AbstractView # setContentType ( String )
* /
protected void postProcessView ( FreeMarkerView freeMarkerView ) {
// If an explicit content type has been configured for all views, it has
// already been set in the view in UrlBasedViewResolver#buildView(String),
// and there is no need to override it here.
if ( getContentType ( ) ! = null ) {
return ;
}
// Check if the view has an explicit encoding set.
String encoding = freeMarkerView . getEncoding ( ) ;
if ( encoding = = null ) {
// If an explicit encoding has not been configured for this particular view,
// use the explicit default encoding for the FreeMarker Configuration, if set.
Configuration configuration = freeMarkerView . obtainConfiguration ( ) ;
if ( configuration . isDefaultEncodingExplicitlySet ( ) ) {
encoding = configuration . getDefaultEncoding ( ) ;
}
}
if ( StringUtils . hasText ( encoding ) ) {
String contentType = "text/html;charset=" + encoding ;
if ( logger . isDebugEnabled ( ) ) {
logger . debug ( "Setting Content-Type for view [%s] to: %s" . formatted ( freeMarkerView , contentType ) ) ;
}
freeMarkerView . setContentType ( contentType ) ;
}
}
}