/*
* Copyright 2002-2018 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.method.annotation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
An abstract base class adapting a WebArgumentResolver
to the HandlerMethodArgumentResolver
contract. Note: This class is provided for backwards compatibility. However it is recommended to re-write a WebArgumentResolver
as HandlerMethodArgumentResolver
. Since supportsParameter
can only be implemented by actually resolving the value and then checking the result is not WebArgumentResolver#UNRESOLVED
any exceptions raised must be absorbed and ignored since it's not clear whether the adapter doesn't support the parameter or whether it failed for an internal reason. The HandlerMethodArgumentResolver
contract also provides access to model attributes and to WebDataBinderFactory
(for type conversion).
Author: Arjen Poutsma, Rossen Stoyanchev Since: 3.1
/**
* An abstract base class adapting a {@link WebArgumentResolver} to the
* {@link HandlerMethodArgumentResolver} contract.
*
* <p><strong>Note:</strong> This class is provided for backwards compatibility.
* However it is recommended to re-write a {@code WebArgumentResolver} as
* {@code HandlerMethodArgumentResolver}. Since {@link #supportsParameter}
* can only be implemented by actually resolving the value and then checking
* the result is not {@code WebArgumentResolver#UNRESOLVED} any exceptions
* raised must be absorbed and ignored since it's not clear whether the adapter
* doesn't support the parameter or whether it failed for an internal reason.
* The {@code HandlerMethodArgumentResolver} contract also provides access to
* model attributes and to {@code WebDataBinderFactory} (for type conversion).
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @since 3.1
*/
public abstract class AbstractWebArgumentResolverAdapter implements HandlerMethodArgumentResolver {
private final Log logger = LogFactory.getLog(getClass());
private final WebArgumentResolver adaptee;
Create a new instance.
/**
* Create a new instance.
*/
public AbstractWebArgumentResolverAdapter(WebArgumentResolver adaptee) {
Assert.notNull(adaptee, "'adaptee' must not be null");
this.adaptee = adaptee;
}
Actually resolve the value and check the resolved value is not WebArgumentResolver.UNRESOLVED
absorbing _any_ exceptions. /**
* Actually resolve the value and check the resolved value is not
* {@link WebArgumentResolver#UNRESOLVED} absorbing _any_ exceptions.
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
try {
NativeWebRequest webRequest = getWebRequest();
Object result = this.adaptee.resolveArgument(parameter, webRequest);
if (result == WebArgumentResolver.UNRESOLVED) {
return false;
}
else {
return ClassUtils.isAssignableValue(parameter.getParameterType(), result);
}
}
catch (Exception ex) {
// ignore (see class-level doc)
logger.debug("Error in checking support for parameter [" + parameter + "], message: " + ex.getMessage());
return false;
}
}
Delegate to the WebArgumentResolver
instance. Throws: - IllegalStateException – if the resolved value is not assignable
to the method parameter.
/**
* Delegate to the {@link WebArgumentResolver} instance.
* @throws IllegalStateException if the resolved value is not assignable
* to the method parameter.
*/
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
Class<?> paramType = parameter.getParameterType();
Object result = this.adaptee.resolveArgument(parameter, webRequest);
if (result == WebArgumentResolver.UNRESOLVED || !ClassUtils.isAssignableValue(paramType, result)) {
throw new IllegalStateException(
"Standard argument type [" + paramType.getName() + "] in method " + parameter.getMethod() +
"resolved to incompatible value of type [" + (result != null ? result.getClass() : null) +
"]. Consider declaring the argument type in a less specific fashion.");
}
return result;
}
Required for access to NativeWebRequest in supportsParameter
. /**
* Required for access to NativeWebRequest in {@link #supportsParameter}.
*/
protected abstract NativeWebRequest getWebRequest();
}