Skip to content

Commit e77faf7

Browse files
yuzawa-sanrstoyanchev
authored andcommitted
Improve performance of canRead() in HttpMessageReader's
Use MimeType.WILDCARD_TYPE for faster String.equals(). Move cheaper checks to the front of the canRead implementations. See gh-30192
1 parent b23cc01 commit e77faf7

File tree

6 files changed

+31
-26
lines changed

6 files changed

+31
-26
lines changed

spring-core/src/main/java/org/springframework/util/MimeType.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -268,7 +268,8 @@ public boolean isWildcardType() {
268268
* @return whether the subtype is a wildcard
269269
*/
270270
public boolean isWildcardSubtype() {
271-
return WILDCARD_TYPE.equals(getSubtype()) || getSubtype().startsWith("*+");
271+
String subtype = getSubtype();
272+
return WILDCARD_TYPE.equals(subtype) || subtype.startsWith("*+");
272273
}
273274

274275
/**

spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public abstract class MimeTypeUtils {
181181

182182
static {
183183
// Not using "parseMimeType" to avoid static init cost
184-
ALL = new MimeType("*", "*");
184+
ALL = new MimeType(MimeType.WILDCARD_TYPE, MimeType.WILDCARD_TYPE);
185185
APPLICATION_GRAPHQL = new MimeType("application", "graphql+json");
186186
APPLICATION_JSON = new MimeType("application", "json");
187187
APPLICATION_OCTET_STREAM = new MimeType("application", "octet-stream");

spring-web/src/main/java/org/springframework/http/MediaType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -435,7 +435,7 @@ public class MediaType extends MimeType implements Serializable {
435435

436436
static {
437437
// Not using "valueOf' to avoid static init cost
438-
ALL = new MediaType("*", "*");
438+
ALL = new MediaType(MimeType.WILDCARD_TYPE, MimeType.WILDCARD_TYPE);
439439
APPLICATION_ATOM_XML = new MediaType("application", "atom+xml");
440440
APPLICATION_CBOR = new MediaType("application", "cbor");
441441
APPLICATION_FORM_URLENCODED = new MediaType("application", "x-www-form-urlencoded");

spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,14 @@ public int getMaxInMemorySize() {
104104

105105
@Override
106106
public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType) {
107-
boolean multiValueUnresolved =
108-
elementType.hasUnresolvableGenerics() &&
109-
MultiValueMap.class.isAssignableFrom(elementType.toClass());
110-
111-
return ((MULTIVALUE_STRINGS_TYPE.isAssignableFrom(elementType) || multiValueUnresolved) &&
112-
(mediaType == null || MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType)));
107+
if (mediaType == null || MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType)) {
108+
if (MultiValueMap.class.isAssignableFrom(elementType.toClass()) &&
109+
elementType.hasUnresolvableGenerics()) {
110+
return true;
111+
}
112+
return MULTIVALUE_STRINGS_TYPE.isAssignableFrom(elementType);
113+
}
114+
return false;
113115
}
114116

115117
@Override

spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -97,15 +97,15 @@ public int getMaxInMemorySize() {
9797

9898
@Override
9999
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
100+
// Skip String: CharSequenceDecoder + "*/*" comes after
101+
if (CharSequence.class.isAssignableFrom(elementType.toClass()) || !supportsMimeType(mimeType)) {
102+
return false;
103+
}
100104
ObjectMapper mapper = selectObjectMapper(elementType, mimeType);
101105
if (mapper == null) {
102106
return false;
103107
}
104108
JavaType javaType = mapper.constructType(elementType.getType());
105-
// Skip String: CharSequenceDecoder + "*/*" comes after
106-
if (CharSequence.class.isAssignableFrom(elementType.toClass()) || !supportsMimeType(mimeType)) {
107-
return false;
108-
}
109109
if (!logger.isDebugEnabled()) {
110110
return mapper.canDeserialize(javaType);
111111
}

spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartHttpMessageReader.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -81,21 +81,23 @@ public List<MediaType> getReadableMediaTypes() {
8181
return MIME_TYPES;
8282
}
8383

84-
@Override
85-
public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType) {
86-
if (MULTIPART_VALUE_TYPE.isAssignableFrom(elementType)) {
87-
if (mediaType == null) {
84+
private boolean supportsMediaType(@Nullable MediaType mediaType) {
85+
if (mediaType == null) {
86+
return true;
87+
}
88+
for (MediaType supportedMediaType : MIME_TYPES) {
89+
if (supportedMediaType.isCompatibleWith(mediaType)) {
8890
return true;
8991
}
90-
for (MediaType supportedMediaType : MIME_TYPES) {
91-
if (supportedMediaType.isCompatibleWith(mediaType)) {
92-
return true;
93-
}
94-
}
9592
}
9693
return false;
9794
}
9895

96+
@Override
97+
public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType) {
98+
return supportsMediaType(mediaType) && MULTIPART_VALUE_TYPE.isAssignableFrom(elementType);
99+
}
100+
99101

100102
@Override
101103
public Flux<MultiValueMap<String, Part>> read(ResolvableType elementType,

0 commit comments

Comments
 (0)