From f0e23b66f32055b6ad9515955d9dd2902d38366e Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Wed, 11 May 2022 14:54:00 +0100 Subject: [PATCH] The "consumes" condition compares MediaType parameters Closes gh-9257 --- .../web/bind/annotation/RequestMapping.java | 11 +++-- .../AbstractMediaTypeExpression.java | 17 ++++++- .../condition/ConsumesRequestCondition.java | 4 +- .../condition/ProducesRequestCondition.java | 14 +----- .../ConsumesRequestConditionTests.java | 48 +++++++++++++------ .../ProducesRequestConditionTests.java | 10 ++-- .../AbstractMediaTypeExpression.java | 17 ++++++- .../condition/ConsumesRequestCondition.java | 4 +- .../condition/ProducesRequestCondition.java | 14 +----- .../ConsumesRequestConditionTests.java | 23 ++++++++- .../ProducesRequestConditionTests.java | 10 ++-- 11 files changed, 112 insertions(+), 60 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java index 6d59dd4aec..97fe725024 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -169,7 +169,12 @@ public @interface RequestMapping { * consumes = {"text/plain", "application/*"} * consumes = MediaType.TEXT_PLAIN_VALUE * - * Expressions can be negated by using the "!" operator, as in + *

If a declared media type contains a parameter, and if the + * {@code "content-type"} from the request also has that parameter, then + * the parameter values must match. Otherwise, if the media type from the + * request {@code "content-type"} does not contain the parameter, then the + * parameter is ignored for matching purposes. + *

Expressions can be negated by using the "!" operator, as in * "!text/plain", which matches all requests with a {@code Content-Type} * other than "text/plain". *

Supported at the type level as well as at the method level! @@ -194,7 +199,7 @@ public @interface RequestMapping { * *

If a declared media type contains a parameter (e.g. "charset=UTF-8", * "type=feed", "type=entry") and if a compatible media type from the request - * has that parameter too, then the parameter values must match. Otherwise + * has that parameter too, then the parameter values must match. Otherwise, * if the media type from the request does not contain the parameter, it is * assumed the client accepts any value. *

Expressions can be negated by using the "!" operator, as in "!text/plain", diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/AbstractMediaTypeExpression.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/AbstractMediaTypeExpression.java index 82e8bfb9aa..33ab997d3b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/AbstractMediaTypeExpression.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/AbstractMediaTypeExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -16,8 +16,11 @@ package org.springframework.web.reactive.result.condition; +import java.util.Map; + import org.springframework.http.MediaType; import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; @@ -78,6 +81,18 @@ abstract class AbstractMediaTypeExpression implements Comparable entry : getMediaType().getParameters().entrySet()) { + if (StringUtils.hasText(entry.getValue())) { + String value = contentType.getParameter(entry.getKey()); + if (StringUtils.hasText(value) && !entry.getValue().equals(value)) { + return false; + } + } + } + return true; + } + @Override public int compareTo(AbstractMediaTypeExpression other) { MediaType mediaType1 = this.getMediaType(); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/ConsumesRequestCondition.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/ConsumesRequestCondition.java index 5fd28ab5a3..ea42c2008f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/ConsumesRequestCondition.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/ConsumesRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -274,7 +274,7 @@ public final class ConsumesRequestCondition extends AbstractRequestCondition entry : getMediaType().getParameters().entrySet()) { + if (StringUtils.hasText(entry.getValue())) { + String value = contentType.getParameter(entry.getKey()); + if (StringUtils.hasText(value) && !entry.getValue().equals(value)) { + return false; + } + } + } + return true; + } + @Override public boolean equals(@Nullable Object other) { if (this == other) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ConsumesRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ConsumesRequestCondition.java index 430fe9fbd4..999d0cb290 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ConsumesRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ConsumesRequestCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -285,7 +285,7 @@ public final class ConsumesRequestCondition extends AbstractRequestCondition