Browse Source

SPR-7354 - Added equivalent of JAX-RS @Consumes to Spring MVC

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4197 50f2f4bb-b051-0410-bef5-90022cba6387
pull/1/merge
Arjen Poutsma 15 years ago
parent
commit
a37c85f4fc
  1. 21
      org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestKey.java
  2. 16
      org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ConsumesRequestCondition.java
  3. 10
      org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionFactory.java
  4. 28
      org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestKeyTests.java

21
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestKey.java

@ -164,12 +164,9 @@ public final class RequestKey { @@ -164,12 +164,9 @@ public final class RequestKey {
Set<RequestMethod> methods = union(this.methods, methodKey.methods);
RequestCondition params = RequestConditionFactory.and(this.paramsCondition, methodKey.paramsCondition);
RequestCondition headers = RequestConditionFactory.and(this.headersCondition, methodKey.headersCondition);
RequestCondition consumes;
// if (methodKey.consumesCondition.weight() > this.consumesCondition.weight()) {
//
// }
RequestCondition consumes = RequestConditionFactory.mostSpecific(methodKey.consumesCondition, this.consumesCondition);
return new RequestKey(patterns, methods, params, headers, null);
return new RequestKey(patterns, methods, params, headers, consumes);
}
private static Set<String> combinePatterns(Collection<String> typePatterns,
@ -213,14 +210,16 @@ public final class RequestKey { @@ -213,14 +210,16 @@ public final class RequestKey {
* @return a new request key that contains all matching attributes
*/
public RequestKey getMatchingKey(HttpServletRequest request, PathMatcher pathMatcher, UrlPathHelper urlPathHelper) {
if (!checkMethod(request) || !checkParams(request) || !checkHeaders(request)) {
if (!checkMethod(request) || !paramsCondition.match(request) || !headersCondition.match(request) ||
!consumesCondition.match(request)) {
return null;
}
else {
List<String> matchingPatterns = getMatchingPatterns(request, pathMatcher, urlPathHelper);
if (!matchingPatterns.isEmpty()) {
Set<RequestMethod> matchingMethods = getMatchingMethods(request);
return new RequestKey(matchingPatterns, matchingMethods, this.paramsCondition, this.headersCondition, null);
return new RequestKey(matchingPatterns, matchingMethods, this.paramsCondition, this.headersCondition,
this.consumesCondition);
}
else {
return null;
@ -259,14 +258,6 @@ public final class RequestKey { @@ -259,14 +258,6 @@ public final class RequestKey {
return methods.isEmpty() || methods.contains(RequestMethod.valueOf(request.getMethod()));
}
private boolean checkParams(HttpServletRequest request) {
return paramsCondition.match(request);
}
private boolean checkHeaders(HttpServletRequest request) {
return headersCondition.match(request);
}
private String getMatchingPattern(String pattern, String lookupPath, PathMatcher pathMatcher) {
if (pattern.equals(lookupPath) || pathMatcher.match(pattern, lookupPath)) {
return pattern;

16
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ConsumesRequestCondition.java

@ -22,8 +22,8 @@ import org.springframework.http.MediaType; @@ -22,8 +22,8 @@ import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
/**
* @author Arjen Poutsma
*/
* @author Arjen Poutsma
*/
class ConsumesRequestCondition extends AbstractRequestCondition {
private final MediaType mediaType;
@ -33,12 +33,14 @@ class ConsumesRequestCondition extends AbstractRequestCondition { @@ -33,12 +33,14 @@ class ConsumesRequestCondition extends AbstractRequestCondition {
}
public boolean match(HttpServletRequest request) {
String contentTypeString = request.getContentType();
if (StringUtils.hasLength(contentTypeString)) {
MediaType contentType = MediaType.parseMediaType(contentTypeString);
return this.mediaType.includes(contentType);
MediaType contentType;
if (StringUtils.hasLength(request.getContentType())) {
contentType = MediaType.parseMediaType(request.getContentType());
}
else {
contentType = MediaType.APPLICATION_OCTET_STREAM;
}
return false;
return this.mediaType.includes(contentType);
}
@Override

10
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionFactory.java

@ -84,6 +84,16 @@ public abstract class RequestConditionFactory { @@ -84,6 +84,16 @@ public abstract class RequestConditionFactory {
return FALSE_CONDITION;
}
public static RequestCondition mostSpecific(RequestCondition... conditions) {
if (ObjectUtils.isEmpty(conditions)) {
return trueCondition();
}
RequestCondition[] copy = new RequestCondition[conditions.length];
System.arraycopy(conditions, 0, copy, 0, conditions.length);
Arrays.sort(copy);
return copy[0];
}
/**
* Combines the given conditions into a logical AND, i.e. the returned condition will return {@code true} for {@link
* RequestCondition#match(HttpServletRequest)} if all of the given conditions do so.

28
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestKeyTests.java

@ -147,7 +147,7 @@ public class RequestKeyTests { @@ -147,7 +147,7 @@ public class RequestKeyTests {
}
@Test
public void testMatchingKeyContent() {
public void matchingKeyContent() {
UrlPathHelper urlPathHelper = new UrlPathHelper();
PathMatcher pathMatcher = new AntPathMatcher();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
@ -167,7 +167,7 @@ public class RequestKeyTests { @@ -167,7 +167,7 @@ public class RequestKeyTests {
}
@Test
public void testParamConditions() {
public void paramsCondition() {
UrlPathHelper urlPathHelper = new UrlPathHelper();
PathMatcher pathMatcher = new AntPathMatcher();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
@ -185,7 +185,7 @@ public class RequestKeyTests { @@ -185,7 +185,7 @@ public class RequestKeyTests {
}
@Test
public void testHeaderConditions() {
public void headersCondition() {
UrlPathHelper urlPathHelper = new UrlPathHelper();
PathMatcher pathMatcher = new AntPathMatcher();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
@ -203,7 +203,27 @@ public class RequestKeyTests { @@ -203,7 +203,27 @@ public class RequestKeyTests {
}
@Test
public void testCreateFromServletRequest() {
public void consumesCondition() {
UrlPathHelper urlPathHelper = new UrlPathHelper();
PathMatcher pathMatcher = new AntPathMatcher();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
request.setContentType("text/plain");
RequestKey key = new RequestKey(singleton("/foo"), null, null, null, RequestConditionFactory.parseConsumes(
"text/plain"));
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
assertNotNull(match);
key = new RequestKey(singleton("/foo"), null, null, null, RequestConditionFactory.parseConsumes(
"application/xml"));
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
assertNull(match);
}
@Test
public void createFromServletRequest() {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
RequestKey key = RequestKey.createFromServletRequest(request, new UrlPathHelper());
assertEquals(new RequestKey(singleton("/foo"), singleton(RequestMethod.GET), null, null, null), key);

Loading…
Cancel
Save