|
|
|
@ -22,6 +22,7 @@ import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.function.Consumer; |
|
|
|
import java.util.function.Consumer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import jakarta.servlet.DispatcherType; |
|
|
|
import jakarta.servlet.FilterChain; |
|
|
|
import jakarta.servlet.FilterChain; |
|
|
|
import jakarta.servlet.ServletException; |
|
|
|
import jakarta.servlet.ServletException; |
|
|
|
import jakarta.servlet.http.HttpServletRequest; |
|
|
|
import jakarta.servlet.http.HttpServletRequest; |
|
|
|
@ -43,8 +44,8 @@ import org.springframework.web.util.pattern.PathPattern; |
|
|
|
import org.springframework.web.util.pattern.PathPatternParser; |
|
|
|
import org.springframework.web.util.pattern.PathPatternParser; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* {@link jakarta.servlet.Filter} that modifies the URL, and then redirects or |
|
|
|
* {@link jakarta.servlet.Filter} that modifies the URL, and then either |
|
|
|
* wraps the request to apply the change. |
|
|
|
* redirects or wraps the request to effect the change. |
|
|
|
* |
|
|
|
* |
|
|
|
* <p>To create an instance, you can use the following: |
|
|
|
* <p>To create an instance, you can use the following: |
|
|
|
* |
|
|
|
* |
|
|
|
@ -55,8 +56,8 @@ import org.springframework.web.util.pattern.PathPatternParser; |
|
|
|
* .build(); |
|
|
|
* .build(); |
|
|
|
* </pre> |
|
|
|
* </pre> |
|
|
|
* |
|
|
|
* |
|
|
|
* <p>This {@code Filter} should be ordered after {@link ForwardedHeaderFilter} |
|
|
|
* <p>This {@code Filter} should be ordered after {@link ForwardedHeaderFilter}, |
|
|
|
* and before any security filters. |
|
|
|
* before {@link ServletRequestPathFilter}, and before security filters. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
* @since 6.2 |
|
|
|
* @since 6.2 |
|
|
|
@ -74,43 +75,25 @@ public final class UrlHandlerFilter extends OncePerRequestFilter { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
protected boolean shouldNotFilterAsyncDispatch() { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
protected boolean shouldNotFilterErrorDispatch() { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) |
|
|
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) |
|
|
|
throws ServletException, IOException { |
|
|
|
throws ServletException, IOException { |
|
|
|
|
|
|
|
|
|
|
|
RequestPath previousPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE); |
|
|
|
RequestPath path = (ServletRequestPathUtils.hasParsedRequestPath(request) ? |
|
|
|
RequestPath path = previousPath; |
|
|
|
ServletRequestPathUtils.getParsedRequestPath(request) : |
|
|
|
try { |
|
|
|
ServletRequestPathUtils.parse(request)); |
|
|
|
if (path == null) { |
|
|
|
|
|
|
|
path = ServletRequestPathUtils.parseAndCache(request); |
|
|
|
for (Map.Entry<Handler, List<PathPattern>> entry : this.handlers.entrySet()) { |
|
|
|
|
|
|
|
if (!entry.getKey().supports(request, path)) { |
|
|
|
|
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
for (Map.Entry<Handler, List<PathPattern>> entry : this.handlers.entrySet()) { |
|
|
|
for (PathPattern pattern : entry.getValue()) { |
|
|
|
if (!entry.getKey().supports(request, path)) { |
|
|
|
if (pattern.matches(path)) { |
|
|
|
continue; |
|
|
|
entry.getKey().handle(request, response, chain); |
|
|
|
} |
|
|
|
return; |
|
|
|
for (PathPattern pattern : entry.getValue()) { |
|
|
|
|
|
|
|
if (pattern.matches(path)) { |
|
|
|
|
|
|
|
entry.getKey().handle(request, response, chain); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
finally { |
|
|
|
|
|
|
|
if (previousPath != null) { |
|
|
|
|
|
|
|
ServletRequestPathUtils.setParsedRequestPath(previousPath, request); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chain.doFilter(request, response); |
|
|
|
chain.doFilter(request, response); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -348,7 +331,16 @@ public final class UrlHandlerFilter extends OncePerRequestFilter { |
|
|
|
hasPathInfo ? servletPath : trimTrailingSlash(servletPath), |
|
|
|
hasPathInfo ? servletPath : trimTrailingSlash(servletPath), |
|
|
|
hasPathInfo ? trimTrailingSlash(pathInfo) : pathInfo); |
|
|
|
hasPathInfo ? trimTrailingSlash(pathInfo) : pathInfo); |
|
|
|
|
|
|
|
|
|
|
|
chain.doFilter(request, response); |
|
|
|
RequestPath previousPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE); |
|
|
|
|
|
|
|
ServletRequestPathUtils.clearParsedRequestPath(request); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
chain.doFilter(request, response); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
finally { |
|
|
|
|
|
|
|
if (previousPath != null) { |
|
|
|
|
|
|
|
ServletRequestPathUtils.setParsedRequestPath(previousPath, request); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -378,22 +370,30 @@ public final class UrlHandlerFilter extends OncePerRequestFilter { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String getRequestURI() { |
|
|
|
public String getRequestURI() { |
|
|
|
return this.requestURI; |
|
|
|
return (isForward() ? getDelegate().getRequestURI() : this.requestURI); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public StringBuffer getRequestURL() { |
|
|
|
public StringBuffer getRequestURL() { |
|
|
|
return this.requestURL; |
|
|
|
return (isForward() ? getDelegate().getRequestURL() : this.requestURL); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String getServletPath() { |
|
|
|
public String getServletPath() { |
|
|
|
return this.servletPath; |
|
|
|
return (isForward() ? getDelegate().getServletPath() : this.servletPath); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String getPathInfo() { |
|
|
|
public String getPathInfo() { |
|
|
|
return this.pathInfo; |
|
|
|
return (isForward() ? getDelegate().getPathInfo() : this.pathInfo); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isForward() { |
|
|
|
|
|
|
|
return (getDispatcherType() == DispatcherType.FORWARD); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private HttpServletRequest getDelegate() { |
|
|
|
|
|
|
|
return (HttpServletRequest) getRequest(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|