Refactor String#replaceAll (#3199)

If we repeatedly call String#replaceAll, we internally repeatedly call the regular expression pattern compilation every time as following:

```java
    public String replaceAll(String regex, String replacement) {
        return Pattern.compile(regex).matcher(this).replaceAll(replacement);
    }
```
The modifications are to keep the compiled pattern.
Therefore, compiling a relatively expensive regular expression pattern does not have to be done every time.
This commit is contained in:
durigon
2018-09-20 09:40:39 +09:00
committed by Ryan Baxter
parent 6e8ef02a14
commit cd70fb5023
4 changed files with 19 additions and 6 deletions

View File

@@ -27,6 +27,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
@@ -63,6 +64,10 @@ public class ProxyRequestHelper {
*/
public static final String IGNORED_HEADERS = "ignoredHeaders";
public static final Pattern FORM_FEED_PATTERN = Pattern.compile("\f");
public static final Pattern COLON_PATTERN = Pattern.compile(":");
private Set<String> ignoredHeaders = new LinkedHashSet<>();
private Set<String> sensitiveHeaders = new LinkedHashSet<>();
@@ -283,11 +288,11 @@ public class ProxyRequestHelper {
// if form feed is already part of param name double
// since form feed is used as the colon replacement below
if (key.contains("\f")) {
key = (key.replaceAll("\f", "\f\f"));
key = (FORM_FEED_PATTERN.matcher(key).replaceAll("\f\f"));
}
// colon is special to UriTemplate
if (key.contains(":")) {
key = key.replaceAll(":", "\f");
key = COLON_PATTERN.matcher(key).replaceAll("\f");
}
key = key + i;
singles.put(key, value);

View File

@@ -21,6 +21,8 @@ import org.springframework.util.StringUtils;
*/
public class PatternServiceRouteMapper implements ServiceRouteMapper {
private static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("/{2,}");
/**
* A RegExp Pattern that extract needed information from a service ID. Ex :
* "(?<name>.*)-(?<version>v.*$)"
@@ -60,7 +62,7 @@ public class PatternServiceRouteMapper implements ServiceRouteMapper {
* @return
*/
private String cleanRoute(final String route) {
String routeToClean = route.replaceAll("/{2,}", "/");
String routeToClean = MULTIPLE_SLASH_PATTERN.matcher(route).replaceAll("/");
if (routeToClean.startsWith("/")) {
routeToClean = routeToClean.substring(1);
}

View File

@@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.zuul.filters.pre;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
@@ -70,6 +71,8 @@ public class PreDecorationFilter extends ZuulFilter {
@Deprecated
public static final int FILTER_ORDER = PRE_DECORATION_FILTER_ORDER;
public static final Pattern DOUBLE_SLASH = Pattern.compile("//");
private RouteLocator routeLocator;
private String dispatcherServletPath;
@@ -185,7 +188,7 @@ public class PreDecorationFilter extends ZuulFilter {
fallBackUri = "/" + fallBackUri;
}
String forwardURI = fallbackPrefix + fallBackUri;
forwardURI = forwardURI.replaceAll("//", "/");
forwardURI = DOUBLE_SLASH.matcher(forwardURI).replaceAll("/");
ctx.set(FORWARD_TO_KEY, forwardURI);
}
return null;

View File

@@ -22,6 +22,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.Timer;
import java.util.TimerTask;
@@ -85,6 +86,8 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
private static final Log log = LogFactory.getLog(SimpleHostRoutingFilter.class);
private static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("/{2,}");
private final Timer connectionManagerTimer = new Timer(
"SimpleHostRoutingFilter.connectionManagerTimer", true);
@@ -286,7 +289,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
requestEntity);
URL host = RequestContext.getCurrentContext().getRouteHost();
HttpHost httpHost = getHttpHost(host);
uri = StringUtils.cleanPath((host.getPath() + uri).replaceAll("/{2,}", "/"));
uri = StringUtils.cleanPath(MULTIPLE_SLASH_PATTERN.matcher(host.getPath() + uri).replaceAll("/"));
long contentLength = getContentLength(request);
ContentType contentType = null;
@@ -449,4 +452,4 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
}
return request.getContentLength();
}
}
}