Upgrade to Thymeleaf 3.1 RC2
This commit is contained in:
@@ -72,17 +72,17 @@
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>3.1.0.M1</version>
|
||||
<version>3.1.0.RC2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-spring6</artifactId>
|
||||
<version>3.1.0.M1</version>
|
||||
<version>3.1.0.RC2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
|
||||
<version>3.1.0.M1</version>
|
||||
<version>3.1.0.RC2</version>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
|
||||
@@ -7,8 +7,8 @@ import jakarta.servlet.ServletContext;
|
||||
import org.thymeleaf.dialect.IDialect;
|
||||
import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect;
|
||||
import org.thymeleaf.spring6.SpringTemplateEngine;
|
||||
import org.thymeleaf.spring6.view.AjaxThymeleafViewResolver;
|
||||
import org.thymeleaf.spring6.view.FlowAjaxThymeleafView;
|
||||
import org.thymeleaf.spring6.webflow.view.AjaxThymeleafViewResolver;
|
||||
import org.thymeleaf.spring6.webflow.view.FlowAjaxThymeleafView;
|
||||
import org.thymeleaf.templateresolver.WebApplicationTemplateResolver;
|
||||
import org.thymeleaf.web.IWebApplication;
|
||||
import org.thymeleaf.web.servlet.JakartaServletWebApplication;
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
*
|
||||
* Copyright (c) 2011-2018, The THYMELEAF team (http://www.thymeleaf.org)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
package org.thymeleaf.spring6.view;
|
||||
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.webflow.context.servlet.AjaxHandler;
|
||||
|
||||
|
||||
// Copied from thymeleaf-spring5.
|
||||
// Temporarily here until available in thymeleaf-spring6.
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Interface defining getter and setter methods for an
|
||||
* {@code ajaxHandler} property in Views, so that they can
|
||||
* be used in Spring AJAX environments.
|
||||
* </p>
|
||||
*
|
||||
* @author Daniel Fernández
|
||||
*
|
||||
* @since 3.0.3
|
||||
*
|
||||
*/
|
||||
public interface AjaxEnabledView extends View {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Return the AJAX handler (from Spring Javascript) used
|
||||
* to determine whether a request is an AJAX request or not.
|
||||
* </p>
|
||||
* <p>
|
||||
* Views implementing this interface should be used with an instance of
|
||||
* {@link AjaxThymeleafViewResolver} or any of its subclasses,
|
||||
* so that {@link #setAjaxHandler(AjaxHandler)} can be called by
|
||||
* the resolver when resolving the view, setting the default
|
||||
* AJAX handler being used.
|
||||
* </p>
|
||||
*
|
||||
* @return the AJAX handler.
|
||||
*/
|
||||
public AjaxHandler getAjaxHandler();
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the AJAX handler (from Spring Javascript) used
|
||||
* to determine whether a request is an AJAX request or not.
|
||||
* </p>
|
||||
* <p>
|
||||
* Views implementing this interface should be used with an instance of
|
||||
* {@link AjaxThymeleafViewResolver} or any of its subclasses,
|
||||
* so that this method can be called by
|
||||
* the resolver when resolving the view, setting the default
|
||||
* AJAX handler being used.
|
||||
* </p>
|
||||
*
|
||||
* @param ajaxHandler the AJAX handler.
|
||||
*/
|
||||
public void setAjaxHandler(final AjaxHandler ajaxHandler);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
*
|
||||
* Copyright (c) 2011-2018, The THYMELEAF team (http://www.thymeleaf.org)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
package org.thymeleaf.spring6.view;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.context.servlet.AjaxHandler;
|
||||
import org.thymeleaf.exceptions.ConfigurationException;
|
||||
|
||||
|
||||
// Copied from thymeleaf-spring5.
|
||||
// Temporarily here until available in thymeleaf-spring6.
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Subclass of {@link ThymeleafView} adding compatibility with AJAX events in
|
||||
* Spring JavaScript (part of Spring WebFlow). This allows this View implementation
|
||||
* to be able to return only <i>fragments</i> of the page.
|
||||
* </p>
|
||||
* <p>
|
||||
* These rendering of fragments is used, for example, in Spring WebFlow's <render>
|
||||
* instructions (though not only).
|
||||
* </p>
|
||||
* <p>
|
||||
* This view searches for a comma-separated list of <i>markup selectors</i> in a request
|
||||
* parameter called {@code fragments}.
|
||||
* </p>
|
||||
*
|
||||
* @author Daniel Fernández
|
||||
*
|
||||
* @since 3.0.3
|
||||
*
|
||||
*/
|
||||
public class AjaxThymeleafView extends ThymeleafView implements AjaxEnabledView {
|
||||
|
||||
private static final Logger vlogger = LoggerFactory.getLogger(AjaxThymeleafView.class);
|
||||
|
||||
private static final String FRAGMENTS_PARAM = "fragments";
|
||||
|
||||
|
||||
private AjaxHandler ajaxHandler = null;
|
||||
|
||||
|
||||
|
||||
public AjaxThymeleafView() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AjaxHandler getAjaxHandler() {
|
||||
return this.ajaxHandler;
|
||||
}
|
||||
|
||||
|
||||
public void setAjaxHandler(final AjaxHandler ajaxHandler) {
|
||||
this.ajaxHandler = ajaxHandler;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void render(final Map<String, ?> model, final HttpServletRequest request, final HttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
|
||||
final AjaxHandler templateAjaxHandler = getAjaxHandler();
|
||||
|
||||
if (templateAjaxHandler == null) {
|
||||
throw new ConfigurationException("[THYMELEAF] AJAX Handler set into " +
|
||||
AjaxThymeleafView.class.getSimpleName() + " instance for template " +
|
||||
getTemplateName() + " is null.");
|
||||
}
|
||||
|
||||
if (templateAjaxHandler.isAjaxRequest(request, response)) {
|
||||
|
||||
final Set<String> fragmentsToRender = getRenderFragments(model, request, response);
|
||||
if (fragmentsToRender == null || fragmentsToRender.size() == 0) {
|
||||
vlogger.warn("[THYMELEAF] An Ajax request was detected, but no fragments were specified to be re-rendered. "
|
||||
+ "Falling back to full page render. This can cause unpredictable results when processing "
|
||||
+ "the ajax response on the client.");
|
||||
super.render(model, request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
super.renderFragment(fragmentsToRender, model, request, response);
|
||||
|
||||
} else {
|
||||
|
||||
super.render(model, request, response);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unused" })
|
||||
protected Set<String> getRenderFragments(
|
||||
final Map model, final HttpServletRequest request, final HttpServletResponse response) {
|
||||
final String fragmentsParam = request.getParameter(FRAGMENTS_PARAM);
|
||||
final String[] renderFragments = StringUtils.commaDelimitedListToStringArray(fragmentsParam);
|
||||
if (renderFragments.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (renderFragments.length == 1) {
|
||||
return Collections.singleton(renderFragments[0]);
|
||||
}
|
||||
return new HashSet<String>(Arrays.asList(renderFragments));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
*
|
||||
* Copyright (c) 2011-2018, The THYMELEAF team (http://www.thymeleaf.org)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
package org.thymeleaf.spring6.view;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.thymeleaf.exceptions.ConfigurationException;
|
||||
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
import org.springframework.webflow.context.servlet.AjaxHandler;
|
||||
import org.springframework.webflow.context.servlet.DefaultAjaxHandler;
|
||||
|
||||
|
||||
// Copied from thymeleaf-spring5.
|
||||
// Temporarily here until available in thymeleaf-spring6.
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Subclass of {@link ThymeleafViewResolver} adding compatibility with AJAX-based events
|
||||
* (redirects) in Spring WebFlow.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>Important</b>: Spring WebFlow dependencies are OPTIONAL. If you are not using WebFlow
|
||||
* in your application, then you should be using {@link ThymeleafViewResolver} directly.
|
||||
* </p>
|
||||
*
|
||||
* @author Daniel Fernández
|
||||
*
|
||||
* @since 3.0.3
|
||||
*
|
||||
*/
|
||||
public class AjaxThymeleafViewResolver
|
||||
extends ThymeleafViewResolver {
|
||||
|
||||
|
||||
private static final Logger vrlogger = LoggerFactory.getLogger(AjaxThymeleafViewResolver.class);
|
||||
|
||||
|
||||
private AjaxHandler ajaxHandler = new DefaultAjaxHandler();
|
||||
|
||||
|
||||
|
||||
public AjaxThymeleafViewResolver() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Return the AJAX handler (from Spring Javascript) used
|
||||
* to determine whether a request is an AJAX request or not
|
||||
* in views resolved by this resolver.
|
||||
* </p>
|
||||
* <p>
|
||||
* An instance of {@link DefaultAjaxHandler} is set by default.
|
||||
* </p>
|
||||
*
|
||||
* @return the AJAX handler.
|
||||
*/
|
||||
public AjaxHandler getAjaxHandler() {
|
||||
return this.ajaxHandler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the AJAX handler (from Spring Javascript) used
|
||||
* to determine whether a request is an AJAX request or not
|
||||
* in views resolved by this resolver.
|
||||
* </p>
|
||||
* <p>
|
||||
* An instance of {@link DefaultAjaxHandler} is set by default.
|
||||
* </p>
|
||||
*
|
||||
* @param ajaxHandler the AJAX handler.
|
||||
*/
|
||||
public void setAjaxHandler(final AjaxHandler ajaxHandler) {
|
||||
this.ajaxHandler = ajaxHandler;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected View createView(final String viewName, final Locale locale) throws Exception {
|
||||
|
||||
if (!canHandle(viewName, locale)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.ajaxHandler == null) {
|
||||
throw new ConfigurationException("[THYMELEAF] AJAX Handler set into " +
|
||||
AjaxThymeleafViewResolver.class.getSimpleName() + " instance is null.");
|
||||
}
|
||||
|
||||
// Check for special "redirect:" prefix.
|
||||
if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
|
||||
vrlogger.trace(
|
||||
"[THYMELEAF] View {} is a redirect. An AJAX-enabled RedirectView implementation will " +
|
||||
"be handling the request.", viewName);
|
||||
final String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
|
||||
return new AjaxRedirectView(
|
||||
this.ajaxHandler, redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());
|
||||
}
|
||||
|
||||
final View view = super.createView(viewName, locale);
|
||||
|
||||
if (view instanceof AjaxEnabledView) {
|
||||
// Set the AJAX handler into view, if it is an AjaxThymeleafView.
|
||||
|
||||
final AjaxEnabledView ajaxEnabledView = (AjaxEnabledView) view;
|
||||
|
||||
if (ajaxEnabledView.getAjaxHandler() == null && getAjaxHandler() != null) {
|
||||
ajaxEnabledView.setAjaxHandler(getAjaxHandler());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return view;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private static class AjaxRedirectView extends RedirectView {
|
||||
|
||||
private static final Logger vlogger = LoggerFactory.getLogger(AjaxRedirectView.class);
|
||||
|
||||
private AjaxHandler ajaxHandler = new DefaultAjaxHandler();
|
||||
|
||||
AjaxRedirectView(final AjaxHandler ajaxHandler, final String redirectUrl,
|
||||
final boolean redirectContextRelative, final boolean redirectHttp10Compatible) {
|
||||
super(redirectUrl, redirectContextRelative, redirectHttp10Compatible);
|
||||
this.ajaxHandler = ajaxHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendRedirect(final HttpServletRequest request, final HttpServletResponse response,
|
||||
final String targetUrl, final boolean http10Compatible)
|
||||
throws IOException {
|
||||
|
||||
if (this.ajaxHandler == null) {
|
||||
throw new ConfigurationException("[THYMELEAF] AJAX Handler set into " +
|
||||
AjaxThymeleafViewResolver.class.getSimpleName() + " instance is null.");
|
||||
}
|
||||
|
||||
if (this.ajaxHandler.isAjaxRequest(request, response)) {
|
||||
if (vlogger.isTraceEnabled()) {
|
||||
vlogger.trace(
|
||||
"[THYMELEAF] RedirectView for URL \"{}\" is an AJAX request. AjaxHandler of class {} " +
|
||||
"will be in charge of processing the request.", targetUrl, this.ajaxHandler.getClass().getName());
|
||||
}
|
||||
this.ajaxHandler.sendAjaxRedirect(targetUrl, request, response, false);
|
||||
} else {
|
||||
vlogger.trace(
|
||||
"[THYMELEAF] RedirectView for URL \"{}\" is not an AJAX request. Request will be handled " +
|
||||
"as a normal redirect", targetUrl);
|
||||
super.sendRedirect(request, response, targetUrl, http10Compatible);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
*
|
||||
* Copyright (c) 2011-2018, The THYMELEAF team (http://www.thymeleaf.org)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
package org.thymeleaf.spring6.view;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.execution.View;
|
||||
|
||||
|
||||
// Copied from thymeleaf-spring5.
|
||||
// Temporarily here until available in thymeleaf-spring6.
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Subclass of {@link AjaxThymeleafView} for Spring WebFlow,
|
||||
* designed for obtaining the fragments to be rendered via
|
||||
* AJAX in the way needed by Spring WebFlow.
|
||||
* </p>
|
||||
* <p>
|
||||
* Most people will need to use this class instead of
|
||||
* {@link AjaxThymeleafView} if you are using Spring WebFlow.
|
||||
* </p>
|
||||
*
|
||||
* @author Daniel Fernández
|
||||
*
|
||||
* @since 3.0.3
|
||||
*
|
||||
*/
|
||||
public class FlowAjaxThymeleafView extends AjaxThymeleafView {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public FlowAjaxThymeleafView() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected Set<String> getRenderFragments(
|
||||
final Map model, final HttpServletRequest request, final HttpServletResponse response) {
|
||||
|
||||
final RequestContext context = RequestContextHolder.getRequestContext();
|
||||
if (context == null) {
|
||||
return super.getRenderFragments(model, request, response);
|
||||
}
|
||||
|
||||
final String[] fragments = (String[]) context.getFlashScope().get(View.RENDER_FRAGMENTS_ATTRIBUTE);
|
||||
if (fragments == null || fragments.length == 0) {
|
||||
return super.getRenderFragments(model, request, response);
|
||||
}
|
||||
if (fragments.length == 1) {
|
||||
return Collections.singleton(fragments[0]);
|
||||
}
|
||||
return new HashSet<String>(Arrays.asList(fragments));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user