NativeWebRequest detects native MultipartRequest even when decorated (SPR-6594)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
@@ -23,6 +23,8 @@ import java.util.Map;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.filter.PortletRequestWrapper;
|
||||
import javax.portlet.filter.PortletResponseWrapper;
|
||||
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -75,6 +77,44 @@ public class PortletWebRequest extends PortletRequestAttributes implements Nativ
|
||||
return getResponse();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getNativeRequest(Class<T> requiredType) {
|
||||
if (requiredType != null) {
|
||||
PortletRequest request = getRequest();
|
||||
while (request != null) {
|
||||
if (requiredType.isInstance(request)) {
|
||||
return (T) request;
|
||||
}
|
||||
else if (request instanceof PortletRequestWrapper) {
|
||||
request = ((PortletRequestWrapper) request).getRequest();
|
||||
}
|
||||
else {
|
||||
request = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getNativeResponse(Class<T> requiredType) {
|
||||
if (requiredType != null) {
|
||||
PortletResponse response = getResponse();
|
||||
while (response != null) {
|
||||
if (requiredType.isInstance(response)) {
|
||||
return (T) response;
|
||||
}
|
||||
else if (response instanceof PortletResponseWrapper) {
|
||||
response = ((PortletResponseWrapper) response).getResponse();
|
||||
}
|
||||
else {
|
||||
response = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String getHeader(String headerName) {
|
||||
return getRequest().getProperty(headerName);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
@@ -534,13 +534,13 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator
|
||||
throws Exception {
|
||||
|
||||
return AnnotationMethodHandlerAdapter.this.createBinder(
|
||||
(PortletRequest) webRequest.getNativeRequest(), target, objectName);
|
||||
webRequest.getNativeRequest(PortletRequest.class), target, objectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBind(WebDataBinder binder, NativeWebRequest webRequest) throws Exception {
|
||||
PortletRequestDataBinder portletBinder = (PortletRequestDataBinder) binder;
|
||||
portletBinder.bind((PortletRequest) webRequest.getNativeRequest());
|
||||
portletBinder.bind(webRequest.getNativeRequest(PortletRequest.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -560,7 +560,7 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator
|
||||
protected Object resolveCookieValue(String cookieName, Class paramType, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
PortletRequest portletRequest = (PortletRequest) webRequest.getNativeRequest();
|
||||
PortletRequest portletRequest = webRequest.getNativeRequest(PortletRequest.class);
|
||||
Cookie cookieValue = PortletUtils.getCookie(portletRequest, cookieName);
|
||||
if (Cookie.class.isAssignableFrom(paramType)) {
|
||||
return cookieValue;
|
||||
@@ -577,8 +577,8 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator
|
||||
protected Object resolveStandardArgument(Class parameterType, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
PortletRequest request = (PortletRequest) webRequest.getNativeRequest();
|
||||
PortletResponse response = (PortletResponse) webRequest.getNativeResponse();
|
||||
PortletRequest request = webRequest.getNativeRequest(PortletRequest.class);
|
||||
PortletResponse response = webRequest.getNativeResponse(PortletResponse.class);
|
||||
|
||||
if (PortletRequest.class.isAssignableFrom(parameterType)) {
|
||||
return request;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
@@ -61,6 +61,7 @@ import org.springframework.web.servlet.View;
|
||||
/**
|
||||
* Implementation of the {@link org.springframework.web.portlet.HandlerExceptionResolver} interface that handles
|
||||
* exceptions through the {@link ExceptionHandler} annotation.
|
||||
*
|
||||
* <p>This exception resolver is enabled by default in the {@link org.springframework.web.portlet.DispatcherPortlet}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
@@ -70,6 +71,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
|
||||
private WebArgumentResolver[] customArgumentResolvers;
|
||||
|
||||
|
||||
/**
|
||||
* Set a custom ArgumentResolvers to use for special method parameter types. Such a custom ArgumentResolver will kick
|
||||
* in first, having a chance to resolve an argument value before the standard argument handling kicks in.
|
||||
@@ -86,11 +88,11 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
this.customArgumentResolvers = argumentResolvers;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ModelAndView doResolveException(PortletRequest request,
|
||||
MimeResponse response,
|
||||
Object handler,
|
||||
Exception ex) {
|
||||
protected ModelAndView doResolveException(PortletRequest request, MimeResponse response,
|
||||
Object handler, Exception ex) {
|
||||
|
||||
if (handler != null) {
|
||||
Method handlerMethod = findBestExceptionHandlerMethod(handler, ex);
|
||||
if (handlerMethod != null) {
|
||||
@@ -113,15 +115,13 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
|
||||
/**
|
||||
* Finds the handler method that matches the thrown exception best.
|
||||
*
|
||||
* @param handler the handler object
|
||||
* @param handler the handler object
|
||||
* @param thrownException the exception to be handled
|
||||
* @return the best matching method; or <code>null</code> if none is found
|
||||
*/
|
||||
private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) {
|
||||
final Class<?> handlerType = handler.getClass();
|
||||
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
|
||||
|
||||
final Map<Class<? extends Throwable>, Method> resolverMethods =
|
||||
new LinkedHashMap<Class<? extends Throwable>, Method>();
|
||||
|
||||
@@ -145,16 +145,15 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return getBestMatchingMethod(thrownException, resolverMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the exception classes handled by the given method.
|
||||
*
|
||||
* <p>Default implementation looks for exceptions in the {@linkplain ExceptionHandler#value() annotation}, or -
|
||||
* if that annotation element is empty - any exceptions listed in the method parameters if the method is annotated
|
||||
* with {@code @ExceptionHandler}.
|
||||
*
|
||||
* <p>Default implementation looks for exceptions in the {@linkplain ExceptionHandler#value() annotation},
|
||||
* or - if that annotation element is empty - any exceptions listed in the method parameters if the
|
||||
* method is annotated with {@code @ExceptionHandler}.
|
||||
* @param method the method
|
||||
* @return the handled exceptions
|
||||
*/
|
||||
@@ -182,6 +181,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
*/
|
||||
private Method getBestMatchingMethod(Exception thrownException,
|
||||
Map<Class<? extends Throwable>, Method> resolverMethods) {
|
||||
|
||||
if (!resolverMethods.isEmpty()) {
|
||||
List<Class<? extends Throwable>> handledExceptions =
|
||||
new ArrayList<Class<? extends Throwable>>(resolverMethods.keySet());
|
||||
@@ -197,47 +197,40 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
/**
|
||||
* Resolves the arguments for the given method. Delegates to {@link #resolveCommonArgument}.
|
||||
*/
|
||||
private Object[] resolveHandlerArguments(Method handlerMethod,
|
||||
Object handler,
|
||||
NativeWebRequest webRequest,
|
||||
Exception thrownException) throws Exception {
|
||||
private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
|
||||
NativeWebRequest webRequest, Exception thrownException) throws Exception {
|
||||
|
||||
Class[] paramTypes = handlerMethod.getParameterTypes();
|
||||
Object[] args = new Object[paramTypes.length];
|
||||
|
||||
Class<?> handlerType = handler.getClass();
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
MethodParameter methodParam = new MethodParameter(handlerMethod, i);
|
||||
GenericTypeResolver.resolveParameterType(methodParam, handlerType);
|
||||
|
||||
Class paramType = methodParam.getParameterType();
|
||||
|
||||
Object argValue = resolveCommonArgument(methodParam, webRequest, thrownException);
|
||||
if (argValue != WebArgumentResolver.UNRESOLVED) {
|
||||
args[i] = argValue;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Unsupported argument [" + paramType.getName() + "] for @ExceptionHandler method: " +
|
||||
handlerMethod);
|
||||
throw new IllegalStateException("Unsupported argument [" + paramType.getName() +
|
||||
"] for @ExceptionHandler method: " + handlerMethod);
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves common method arguments. Delegates to registered {@link #setCustomArgumentResolver(org.springframework.web.bind.support.WebArgumentResolver) argumentResolvers} first,
|
||||
* Resolves common method arguments. Delegates to registered
|
||||
* {@link #setCustomArgumentResolver argumentResolvers} first,
|
||||
* then checking {@link #resolveStandardArgument}.
|
||||
*
|
||||
* @param methodParameter the method parameter
|
||||
* @param webRequest the request
|
||||
* @param webRequest the request
|
||||
* @param thrownException the exception thrown
|
||||
* @return the argument value, or {@link org.springframework.web.bind.support.WebArgumentResolver#UNRESOLVED}
|
||||
*/
|
||||
protected Object resolveCommonArgument(MethodParameter methodParameter,
|
||||
NativeWebRequest webRequest,
|
||||
protected Object resolveCommonArgument(MethodParameter methodParameter, NativeWebRequest webRequest,
|
||||
Exception thrownException) throws Exception {
|
||||
|
||||
// Invoke custom argument resolvers if present...
|
||||
if (this.customArgumentResolvers != null) {
|
||||
for (WebArgumentResolver argumentResolver : this.customArgumentResolvers) {
|
||||
@@ -261,25 +254,24 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves standard method arguments. Default implementation handles {@link org.springframework.web.context.request.NativeWebRequest},
|
||||
* {@link javax.servlet.ServletRequest}, {@link javax.servlet.ServletResponse}, {@link javax.servlet.http.HttpSession}, {@link java.security.Principal}, {@link java.util.Locale},
|
||||
* request {@link java.io.InputStream}, request {@link java.io.Reader}, response {@link java.io.OutputStream}, response {@link java.io.Writer},
|
||||
* and the given {@code thrownException}.
|
||||
*
|
||||
* @param parameterType the method parameter type
|
||||
* @param webRequest the request
|
||||
* Resolves standard method arguments. The default implementation handles {@link NativeWebRequest},
|
||||
* {@link ServletRequest}, {@link ServletResponse}, {@link HttpSession}, {@link Principal},
|
||||
* {@link Locale}, request {@link InputStream}, request {@link Reader}, response {@link OutputStream},
|
||||
* response {@link Writer}, and the given {@code thrownException}.
|
||||
* @param parameterType the method parameter type
|
||||
* @param webRequest the request
|
||||
* @param thrownException the exception thrown
|
||||
* @return the argument value, or {@link org.springframework.web.bind.support.WebArgumentResolver#UNRESOLVED}
|
||||
*/
|
||||
protected Object resolveStandardArgument(Class parameterType,
|
||||
NativeWebRequest webRequest,
|
||||
protected Object resolveStandardArgument(Class parameterType, NativeWebRequest webRequest,
|
||||
Exception thrownException) throws Exception {
|
||||
|
||||
if (WebRequest.class.isAssignableFrom(parameterType)) {
|
||||
return webRequest;
|
||||
}
|
||||
|
||||
PortletRequest request = (PortletRequest) webRequest.getNativeRequest();
|
||||
PortletResponse response = (PortletResponse) webRequest.getNativeResponse();
|
||||
PortletRequest request = webRequest.getNativeRequest(PortletRequest.class);
|
||||
PortletResponse response = webRequest.getNativeResponse(PortletResponse.class);
|
||||
|
||||
if (PortletRequest.class.isAssignableFrom(parameterType)) {
|
||||
return request;
|
||||
@@ -382,6 +374,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Comparator capable of sorting exceptions based on their depth from the thrown exception type.
|
||||
*/
|
||||
@@ -413,4 +406,5 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user