提交 34663300 编写于 作者: J Juergen Hoeller

Avoid regex pattern matching for simple String replacement steps

Issue: SPR-17279
上级 cc87fbcb
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -183,7 +183,7 @@ public class DateTimeFormatterFactory {
// Using strict parsing to align with Joda-Time and standard DateFormat behavior:
// otherwise, an overflow like e.g. Feb 29 for a non-leap-year wouldn't get rejected.
// However, with strict parsing, a year digit needs to be specified as 'u'...
String patternToUse = this.pattern.replace("yy", "uu");
String patternToUse = StringUtils.replace(this.pattern, "yy", "uu");
dateTimeFormatter = DateTimeFormatter.ofPattern(patternToUse).withResolverStyle(ResolverStyle.STRICT);
}
else if (this.iso != null && this.iso != ISO.NONE) {
......
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -24,6 +24,7 @@ import java.util.List;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* ClassFileTransformer-based weaver, allowing for a list of transformers to be
......@@ -73,7 +74,7 @@ public class WeavingTransformer {
* @return (possibly transformed) class byte definition
*/
public byte[] transformIfNecessary(String className, byte[] bytes) {
String internalName = className.replace(".", "/");
String internalName = StringUtils.replace(className, ".", "/");
return transformIfNecessary(className, internalName, bytes, null);
}
......
......@@ -19,6 +19,7 @@ package org.springframework.expression.spel.ast;
import org.springframework.asm.MethodVisitor;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.CodeFlow;
import org.springframework.util.StringUtils;
/**
* Expression language AST node that represents a string literal.
......@@ -33,9 +34,13 @@ public class StringLiteral extends Literal {
public StringLiteral(String payload, int pos, String value) {
super(payload,pos);
value = value.substring(1, value.length() - 1);
this.value = new TypedValue(value.replaceAll("''", "'").replaceAll("\"\"", "\""));
super(payload, pos);
String valueWithinQuotes = value.substring(1, value.length() - 1);
valueWithinQuotes = StringUtils.replace(valueWithinQuotes, "''", "'");
valueWithinQuotes = StringUtils.replace(valueWithinQuotes, "\"\"", "\"");
this.value = new TypedValue(valueWithinQuotes);
this.exitTypeDescriptor = "Ljava/lang/String";
}
......
......@@ -36,6 +36,7 @@ import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* A SpelCompiler will take a regular parsed expression and create (and load) a class
......@@ -132,9 +133,9 @@ public final class SpelCompiler implements Opcodes {
@Nullable
private Class<? extends CompiledExpression> createExpressionClass(SpelNodeImpl expressionToCompile) {
// Create class outline 'spel/ExNNN extends org.springframework.expression.spel.CompiledExpression'
String clazzName = "spel/Ex" + getNextSuffix();
String className = "spel/Ex" + getNextSuffix();
ClassWriter cw = new ExpressionClassWriter();
cw.visit(V1_5, ACC_PUBLIC, clazzName, null, "org/springframework/expression/spel/CompiledExpression", null);
cw.visit(V1_5, ACC_PUBLIC, className, null, "org/springframework/expression/spel/CompiledExpression", null);
// Create default constructor
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
......@@ -152,7 +153,7 @@ public final class SpelCompiler implements Opcodes {
new String[ ]{"org/springframework/expression/EvaluationException"});
mv.visitCode();
CodeFlow cf = new CodeFlow(clazzName, cw);
CodeFlow cf = new CodeFlow(className, cw);
// Ask the expression AST to generate the body of the method
try {
......@@ -181,7 +182,7 @@ public final class SpelCompiler implements Opcodes {
byte[] data = cw.toByteArray();
// TODO need to make this conditionally occur based on a debug flag
// dump(expressionToCompile.toStringAST(), clazzName, data);
return loadClass(clazzName.replaceAll("/", "."), data);
return loadClass(StringUtils.replace(className, "/", "."), data);
}
/**
......
......@@ -292,7 +292,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
for (int index = 1; index <= columnCount; index++) {
String column = JdbcUtils.lookupColumnName(rsmd, index);
String field = lowerCaseName(column.replaceAll(" ", ""));
String field = lowerCaseName(StringUtils.delete(column, " "));
PropertyDescriptor pd = (this.mappedFields != null ? this.mappedFields.get(field) : null);
if (pd != null) {
try {
......
......@@ -38,6 +38,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* {@code HttpMessageWriter} for {@code "text/event-stream"} responses.
......@@ -135,7 +136,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
writeField("retry", retry.toMillis(), sb);
}
if (comment != null) {
sb.append(':').append(comment.replaceAll("\\n", "\n:")).append("\n");
sb.append(':').append(StringUtils.replace(comment, "\n", "\n:")).append("\n");
}
if (data != null) {
sb.append("data:");
......@@ -164,7 +165,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
if (data instanceof String) {
String text = (String) data;
return Flux.from(encodeText(text.replaceAll("\\n", "\ndata:") + "\n", mediaType, factory));
return Flux.from(encodeText(StringUtils.replace(text, "\n", "\ndata:") + "\n", mediaType, factory));
}
if (this.encoder == null) {
......
......@@ -287,13 +287,15 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
// We will perform this validation...
etag = padEtagIfNecessary(etag);
if (etag.startsWith("W/")) {
etag = etag.substring(2);
}
while (ifNoneMatch.hasMoreElements()) {
String clientETags = ifNoneMatch.nextElement();
Matcher etagMatcher = ETAG_HEADER_VALUE_PATTERN.matcher(clientETags);
// Compare weak/strong ETags as per https://tools.ietf.org/html/rfc7232#section-2.3
while (etagMatcher.find()) {
if (StringUtils.hasLength(etagMatcher.group()) &&
etag.replaceFirst("^W/", "").equals(etagMatcher.group(3))) {
if (StringUtils.hasLength(etagMatcher.group()) && etag.equals(etagMatcher.group(3))) {
this.notModified = true;
break;
}
......
......@@ -126,8 +126,7 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter {
String responseETag = generateETagHeaderValue(responseWrapper.getContentInputStream(), this.writeWeakETag);
rawResponse.setHeader(HEADER_ETAG, responseETag);
String requestETag = request.getHeader(HEADER_IF_NONE_MATCH);
if (requestETag != null && ("*".equals(requestETag) || responseETag.equals(requestETag) ||
responseETag.replaceFirst("^W/", "").equals(requestETag.replaceFirst("^W/", "")))) {
if (requestETag != null && ("*".equals(requestETag) || compareETagHeaderValue(requestETag, responseETag))) {
rawResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
else {
......@@ -184,6 +183,16 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter {
return builder.toString();
}
private boolean compareETagHeaderValue(String requestETag, String responseETag) {
if (requestETag.startsWith("W/")) {
requestETag = requestETag.substring(2);
}
if (responseETag.startsWith("W/")) {
responseETag = responseETag.substring(2);
}
return requestETag.equals(responseETag);
}
/**
* This method can be used to disable the content caching response wrapper
......
......@@ -318,12 +318,19 @@ public class DefaultServerWebExchange implements ServerWebExchange {
}
// We will perform this validation...
etag = padEtagIfNecessary(etag);
for (String clientETag : ifNoneMatch) {
if (etag.startsWith("W/")) {
etag = etag.substring(2);
}
for (String clientEtag : ifNoneMatch) {
// Compare weak/strong ETags as per https://tools.ietf.org/html/rfc7232#section-2.3
if (StringUtils.hasLength(clientETag) &&
clientETag.replaceFirst("^W/", "").equals(etag.replaceFirst("^W/", ""))) {
this.notModified = true;
break;
if (StringUtils.hasLength(clientEtag)) {
if (clientEtag.startsWith("W/")) {
clientEtag = clientEtag.substring(2);
}
if (clientEtag.equals(etag)) {
this.notModified = true;
break;
}
}
}
return true;
......
......@@ -38,7 +38,7 @@ import org.springframework.web.util.TagUtils;
import org.springframework.web.util.UriUtils;
/**
* The {@code <url>} tag creates URLs. Modeled after the JSTL c:url tag with
* The {@code <url>} tag creates URLs. Modeled after the JSTL {@code c:url} tag with
* backwards compatibility in mind.
*
* <p>Enhancements to the JSTL functionality include:
......@@ -361,7 +361,8 @@ public class UrlTag extends HtmlEscapingAwareTag implements ParamAware {
usedParams.add(param.getName());
String value = param.getValue();
try {
uri = uri.replace(template, (value != null ? UriUtils.encodePath(value, encoding) : ""));
uri = StringUtils.replace(uri, template,
(value != null ? UriUtils.encodePath(value, encoding) : ""));
}
catch (UnsupportedCharsetException ex) {
throw new JspException(ex);
......@@ -373,7 +374,7 @@ public class UrlTag extends HtmlEscapingAwareTag implements ParamAware {
usedParams.add(param.getName());
String value = param.getValue();
try {
uri = uri.replace(template,
uri = StringUtils.replace(uri, template,
(value != null ? UriUtils.encodePathSegment(param.getValue(), encoding) : ""));
}
catch (UnsupportedCharsetException ex) {
......
......@@ -194,7 +194,7 @@ public class GroovyMarkupConfigurer extends TemplateConfiguration
protected URL resolveTemplate(ClassLoader classLoader, String templatePath) throws IOException {
MarkupTemplateEngine.TemplateResource resource = MarkupTemplateEngine.TemplateResource.parse(templatePath);
Locale locale = LocaleContextHolder.getLocale();
URL url = classLoader.getResource(resource.withLocale(locale.toString().replace("-", "_")).toString());
URL url = classLoader.getResource(resource.withLocale(StringUtils.replace(locale.toString(), "-", "_")).toString());
if (url == null) {
url = classLoader.getResource(resource.withLocale(locale.getLanguage()).toString());
}
......
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -22,6 +22,7 @@ import java.util.UUID;
import org.springframework.lang.Nullable;
import org.springframework.util.IdGenerator;
import org.springframework.util.JdkIdGenerator;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.sockjs.transport.TransportType;
import org.springframework.web.util.UriComponentsBuilder;
......@@ -68,7 +69,7 @@ public class SockJsUrlInfo {
public String getSessionId() {
if (this.sessionId == null) {
this.sessionId = getUuid().toString().replace("-","");
this.sessionId = StringUtils.delete(getUuid().toString(), "-");
}
return this.sessionId;
}
......
......@@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Represents a SockJS frame. Provides factory methods to create SockJS frames.
......@@ -142,7 +143,9 @@ public class SockJsFrame {
if (result.length() > 80) {
result = result.substring(0, 80) + "...(truncated)";
}
return "SockJsFrame content='" + result.replace("\n", "\\n").replace("\r", "\\r") + "'";
result = StringUtils.replace(result, "\n", "\\n");
result = StringUtils.replace(result, "\r", "\\r");
return "SockJsFrame content='" + result + "'";
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册