SPR-7354 - Added equivalent of JAX-RS @Consumes to Spring MVC
This commit is contained in:
parent
bf6693dbc5
commit
ff89c0e55a
|
|
@ -155,15 +155,19 @@ public final class RequestKey {
|
|||
* Combines this {@code RequestKey} with another. The typical use case for this is combining type
|
||||
* and method-level {@link RequestMapping @RequestMapping} annotations.
|
||||
*
|
||||
* @param other the method-level RequestKey
|
||||
* @param methodKey the method-level RequestKey
|
||||
* @param pathMatcher to {@linkplain PathMatcher#combine(String, String) combine} the patterns
|
||||
* @return the combined request key
|
||||
*/
|
||||
public RequestKey combine(RequestKey other, PathMatcher pathMatcher) {
|
||||
Set<String> patterns = combinePatterns(this.patterns, other.patterns, pathMatcher);
|
||||
Set<RequestMethod> methods = union(this.methods, other.methods);
|
||||
RequestCondition params = RequestConditionFactory.and(this.paramsCondition, other.paramsCondition);
|
||||
RequestCondition headers = RequestConditionFactory.and(this.headersCondition, other.headersCondition);
|
||||
public RequestKey combine(RequestKey methodKey, PathMatcher pathMatcher) {
|
||||
Set<String> patterns = combinePatterns(this.patterns, methodKey.patterns, pathMatcher);
|
||||
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()) {
|
||||
//
|
||||
// }
|
||||
|
||||
return new RequestKey(patterns, methods, params, headers, null);
|
||||
}
|
||||
|
|
@ -277,15 +281,6 @@ public final class RequestKey {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean checkConditions(Set<RequestCondition> conditions, HttpServletRequest request) {
|
||||
for (RequestCondition condition : conditions) {
|
||||
if (!condition.match(request)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
|
|
|||
|
|
@ -252,11 +252,11 @@ public class RequestMappingHandlerMethodMapping extends AbstractHandlerMethodMap
|
|||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
result = otherKey.getParams().weight() - key.getParams().weight();
|
||||
result = key.getParams().compareTo(otherKey.getParams());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
result = otherKey.getHeaders().weight() - key.getHeaders().weight();
|
||||
result = key.getHeaders().compareTo(otherKey.getHeaders());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
* @author Arjen Poutsma
|
||||
* @since 3.1
|
||||
*/
|
||||
abstract class AbstractNameValueCondition<T> implements RequestCondition {
|
||||
abstract class AbstractNameValueCondition<T> extends AbstractRequestCondition {
|
||||
|
||||
protected final String name;
|
||||
|
||||
|
|
@ -35,6 +35,7 @@ abstract class AbstractNameValueCondition<T> implements RequestCondition {
|
|||
protected final boolean isNegated;
|
||||
|
||||
AbstractNameValueCondition(String expression) {
|
||||
super(1);
|
||||
int separator = expression.indexOf('=');
|
||||
if (separator == -1) {
|
||||
this.isNegated = expression.startsWith("!");
|
||||
|
|
@ -65,11 +66,6 @@ abstract class AbstractNameValueCondition<T> implements RequestCondition {
|
|||
|
||||
protected abstract boolean matchValue(HttpServletRequest request);
|
||||
|
||||
public int weight() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = name.hashCode();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2002-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.mvc.method.condition;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link RequestCondition} that provides a standard {@link Comparable} implementation.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.1
|
||||
*/
|
||||
public abstract class AbstractRequestCondition implements RequestCondition {
|
||||
|
||||
private final int weight;
|
||||
|
||||
protected AbstractRequestCondition(int weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public int compareTo(RequestCondition o) {
|
||||
AbstractRequestCondition other = (AbstractRequestCondition) o;
|
||||
return other.weight - this.weight;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -24,11 +24,12 @@ import org.springframework.util.StringUtils;
|
|||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class ConsumesRequestCondition implements RequestCondition {
|
||||
class ConsumesRequestCondition extends AbstractRequestCondition {
|
||||
|
||||
private final MediaType mediaType;
|
||||
|
||||
ConsumesRequestCondition(String mediaType) {
|
||||
super(1);
|
||||
this.mediaType = MediaType.parseMediaType(mediaType);
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +42,4 @@ class ConsumesRequestCondition implements RequestCondition {
|
|||
return false;
|
||||
}
|
||||
|
||||
public int weight() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
* @see RequestConditionFactory
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface RequestCondition {
|
||||
public interface RequestCondition extends Comparable<RequestCondition> {
|
||||
|
||||
/**
|
||||
* Indicates whether this condition matches against the given servlet request.
|
||||
|
|
@ -39,11 +39,4 @@ public interface RequestCondition {
|
|||
*/
|
||||
boolean match(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* Indicates the relative weight of this condition. More important conditions have a higher weight than ones that are
|
||||
* less so.
|
||||
*
|
||||
* @return the weight of this condition
|
||||
*/
|
||||
int weight();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.web.servlet.mvc.method.condition;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -25,20 +26,24 @@ import java.util.List;
|
|||
* @author Arjen Poutsma
|
||||
* @since 3.1
|
||||
*/
|
||||
abstract class RequestConditionComposite implements RequestCondition {
|
||||
abstract class RequestConditionComposite extends AbstractRequestCondition {
|
||||
|
||||
protected final List<RequestCondition> conditions;
|
||||
|
||||
public RequestConditionComposite(List<RequestCondition> conditions) {
|
||||
this.conditions = conditions;
|
||||
protected RequestConditionComposite(List<RequestCondition> conditions) {
|
||||
super(getWeight(conditions));
|
||||
this.conditions = Collections.unmodifiableList(conditions);
|
||||
}
|
||||
|
||||
public int weight() {
|
||||
int size = 0;
|
||||
private static int getWeight(List<RequestCondition> conditions) {
|
||||
int weight = 0;
|
||||
for (RequestCondition condition : conditions) {
|
||||
size += condition.weight();
|
||||
if (condition instanceof AbstractRequestCondition) {
|
||||
AbstractRequestCondition abstractRequestCondition = (AbstractRequestCondition) condition;
|
||||
weight += abstractRequestCondition.getWeight();
|
||||
}
|
||||
}
|
||||
return size;
|
||||
return weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -33,41 +33,42 @@ import org.springframework.util.ObjectUtils;
|
|||
*/
|
||||
public abstract class RequestConditionFactory {
|
||||
|
||||
private static final RequestCondition TRUE_CONDITION = new RequestCondition() {
|
||||
private static final RequestCondition TRUE_CONDITION = new AbstractRequestCondition(0) {
|
||||
public boolean match(HttpServletRequest request) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int weight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TRUE";
|
||||
}
|
||||
};
|
||||
|
||||
private static final RequestCondition FALSE_CONDITION = new RequestCondition() {
|
||||
private static final RequestCondition FALSE_CONDITION = new AbstractRequestCondition(0) {
|
||||
public boolean match(HttpServletRequest request) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int weight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FALSE";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a condition that always returns {@code true} for {@link RequestCondition#match(HttpServletRequest)}.
|
||||
*
|
||||
* @return a condition that returns {@code true}
|
||||
*/
|
||||
public static RequestCondition trueCondition() {
|
||||
return TRUE_CONDITION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a condition that always returns {@code false} for {@link RequestCondition#match(HttpServletRequest)}.
|
||||
*
|
||||
* @return a condition that returns {@code false}
|
||||
*/
|
||||
public static RequestCondition falseCondition() {
|
||||
return FALSE_CONDITION;
|
||||
}
|
||||
|
|
@ -87,7 +88,12 @@ public abstract class RequestConditionFactory {
|
|||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return new LogicalConjunctionRequestCondition(filteredConditions);
|
||||
if (filteredConditions.isEmpty()) {
|
||||
return trueCondition();
|
||||
}
|
||||
else {
|
||||
return new LogicalConjunctionRequestCondition(filteredConditions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +114,12 @@ public abstract class RequestConditionFactory {
|
|||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return new LogicalDisjunctionRequestCondition(filteredConditions);
|
||||
if (filteredConditions.isEmpty()) {
|
||||
return trueCondition();
|
||||
}
|
||||
else {
|
||||
return new LogicalDisjunctionRequestCondition(filteredConditions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -120,7 +131,7 @@ public abstract class RequestConditionFactory {
|
|||
*/
|
||||
public static RequestCondition parseParams(String... params) {
|
||||
if (ObjectUtils.isEmpty(params)) {
|
||||
return TRUE_CONDITION;
|
||||
return trueCondition();
|
||||
}
|
||||
RequestCondition[] result = new RequestCondition[params.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
|
|
@ -138,7 +149,7 @@ public abstract class RequestConditionFactory {
|
|||
*/
|
||||
public static RequestCondition parseHeaders(String... headers) {
|
||||
if (ObjectUtils.isEmpty(headers)) {
|
||||
return TRUE_CONDITION;
|
||||
return trueCondition();
|
||||
}
|
||||
RequestCondition[] result = new RequestCondition[headers.length];
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
|
|
@ -157,9 +168,16 @@ public abstract class RequestConditionFactory {
|
|||
return "Accept".equalsIgnoreCase(name) || "Content-Type".equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given consumes, and returns them as a single request condition.
|
||||
*
|
||||
* @param consumes the consumes
|
||||
* @return the request condition
|
||||
* @see org.springframework.web.bind.annotation.RequestMapping#consumes()
|
||||
*/
|
||||
public static RequestCondition parseConsumes(String... consumes) {
|
||||
if (ObjectUtils.isEmpty(consumes)) {
|
||||
return TRUE_CONDITION;
|
||||
return trueCondition();
|
||||
}
|
||||
RequestCondition[] result = new RequestCondition[consumes.length];
|
||||
for (int i = 0; i < consumes.length; i++) {
|
||||
|
|
@ -168,8 +186,4 @@ public abstract class RequestConditionFactory {
|
|||
return or(result);
|
||||
}
|
||||
|
||||
//
|
||||
// Conditions
|
||||
//
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue