From fc406430331b1c681193b087998e8336e4a61445 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 31 May 2016 14:55:50 -0400 Subject: [PATCH] Optimize Consumes/ProducesRequestCondition Before this change Consumes/ProducesRequestCondition shared a common match method in the package private AbstractMediaTypeExpression. The benefit, two lines of code, was negligible but was forcing each condition into parsing the content type of the request body or evaluating the content type for the response respectively. This change removes the shared match method and brings it down into each sub-class resulting in a performance improvement as well as in simpler code including exception handling. Issue: SPR-14299 --- .../AbstractMediaTypeExpression.java | 17 ---------- .../condition/AbstractRequestCondition.java | 2 +- .../condition/ConsumesRequestCondition.java | 29 ++++++++--------- .../condition/ProducesRequestCondition.java | 31 ++++++++++++------- 4 files changed, 36 insertions(+), 43 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractMediaTypeExpression.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractMediaTypeExpression.java index e6708f279d..eb1257aa56 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractMediaTypeExpression.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractMediaTypeExpression.java @@ -16,13 +16,10 @@ package org.springframework.web.servlet.mvc.condition; -import javax.servlet.http.HttpServletRequest; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.MediaType; -import org.springframework.web.HttpMediaTypeException; import org.springframework.web.bind.annotation.RequestMapping; /** @@ -69,20 +66,6 @@ abstract class AbstractMediaTypeExpression implements Comparable result = new LinkedHashSet(expressions); + MediaType contentType; + try { + contentType = StringUtils.hasLength(request.getContentType()) ? + MediaType.parseMediaType(request.getContentType()) : + MediaType.APPLICATION_OCTET_STREAM; + } + catch (InvalidMediaTypeException ex) { + return null; + } + Set result = new LinkedHashSet(this.expressions); for (Iterator iterator = result.iterator(); iterator.hasNext();) { ConsumeMediaTypeExpression expression = iterator.next(); - if (!expression.match(request)) { + if (!expression.match(contentType)) { iterator.remove(); } } @@ -221,18 +231,9 @@ public final class ConsumesRequestCondition extends AbstractRequestCondition MEDIA_TYPE_ALL_LIST = Collections.singletonList(new ProduceMediaTypeExpression("*/*")); @@ -187,25 +189,29 @@ public final class ProducesRequestCondition extends AbstractRequestCondition acceptedMediaTypes; + try { + acceptedMediaTypes = getAcceptedMediaTypes(request); + } + catch (HttpMediaTypeException ex) { + return null; + } Set result = new LinkedHashSet(expressions); for (Iterator iterator = result.iterator(); iterator.hasNext();) { ProduceMediaTypeExpression expression = iterator.next(); - if (!expression.match(request)) { + if (!expression.match(acceptedMediaTypes)) { iterator.remove(); } } if (!result.isEmpty()) { return new ProducesRequestCondition(result, this.contentNegotiationManager); } - try { - if (getAcceptedMediaTypes(request).contains(MediaType.ALL)) { - return new ProducesRequestCondition(); - } + else if (acceptedMediaTypes.contains(MediaType.ALL)) { + return EMPTY_CONDITION; } - catch (HttpMediaTypeException ex) { - // Ignore + else { + return null; } - return null; } /** @@ -314,9 +320,12 @@ public final class ProducesRequestCondition extends AbstractRequestCondition acceptedMediaTypes = getAcceptedMediaTypes(request); + public final boolean match(List acceptedMediaTypes) { + boolean match = matchMediaType(acceptedMediaTypes); + return (!isNegated() ? match : !match); + } + + private boolean matchMediaType(List acceptedMediaTypes) { for (MediaType acceptedMediaType : acceptedMediaTypes) { if (getMediaType().isCompatibleWith(acceptedMediaType)) { return true;