NativeWebRequest detects native MultipartRequest even when decorated (SPR-6594)

This commit is contained in:
Juergen Hoeller
2010-03-30 10:24:39 +00:00
parent 81e81ce77c
commit 2c9753ad25
12 changed files with 321 additions and 108 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2006 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.
@@ -19,16 +19,29 @@ package org.springframework.web.portlet.context;
import java.util.Locale;
import java.util.Map;
import junit.framework.TestCase;
import javax.portlet.PortletRequest;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.PortletResponse;
import javax.portlet.filter.PortletRequestWrapper;
import javax.portlet.filter.PortletResponseWrapper;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.mock.web.portlet.MockPortletRequest;
import org.springframework.mock.web.portlet.MockPortletResponse;
import org.springframework.mock.web.portlet.MockRenderRequest;
import org.springframework.mock.web.portlet.MockRenderResponse;
import org.springframework.web.multipart.MultipartRequest;
/**
* @author Juergen Hoeller
* @since 26.07.2006
*/
public class PortletWebRequestTests extends TestCase {
public class PortletWebRequestTests {
@Test
public void testParameters() {
MockPortletRequest portletRequest = new MockPortletRequest();
portletRequest.addParameter("param1", "value1");
@@ -53,6 +66,7 @@ public class PortletWebRequestTests extends TestCase {
assertEquals("value2a", ((String[]) paramMap.get("param2"))[1]);
}
@Test
public void testLocale() {
MockPortletRequest portletRequest = new MockPortletRequest();
portletRequest.addPreferredLocale(Locale.UK);
@@ -61,4 +75,40 @@ public class PortletWebRequestTests extends TestCase {
assertEquals(Locale.UK, request.getLocale());
}
@Test
public void testNativeRequest() {
MockRenderRequest portletRequest = new MockRenderRequest();
MockRenderResponse portletResponse = new MockRenderResponse();
PortletWebRequest request = new PortletWebRequest(portletRequest, portletResponse);
assertSame(portletRequest, request.getNativeRequest());
assertSame(portletRequest, request.getNativeRequest(PortletRequest.class));
assertSame(portletRequest, request.getNativeRequest(RenderRequest.class));
assertSame(portletRequest, request.getNativeRequest(MockRenderRequest.class));
assertNull(request.getNativeRequest(MultipartRequest.class));
assertSame(portletResponse, request.getNativeResponse());
assertSame(portletResponse, request.getNativeResponse(PortletResponse.class));
assertSame(portletResponse, request.getNativeResponse(RenderResponse.class));
assertSame(portletResponse, request.getNativeResponse(MockRenderResponse.class));
assertNull(request.getNativeResponse(MultipartRequest.class));
}
@Test
public void testDecoratedNativeRequest() {
MockRenderRequest portletRequest = new MockRenderRequest();
MockRenderResponse portletResponse = new MockRenderResponse();
PortletRequest decoratedRequest = new PortletRequestWrapper(portletRequest);
PortletResponse decoratedResponse = new PortletResponseWrapper(portletResponse);
PortletWebRequest request = new PortletWebRequest(decoratedRequest, decoratedResponse);
assertSame(decoratedRequest, request.getNativeRequest());
assertSame(decoratedRequest, request.getNativeRequest(PortletRequest.class));
assertSame(portletRequest, request.getNativeRequest(RenderRequest.class));
assertSame(portletRequest, request.getNativeRequest(MockRenderRequest.class));
assertNull(request.getNativeRequest(MultipartRequest.class));
assertSame(decoratedResponse, request.getNativeResponse());
assertSame(decoratedResponse, request.getNativeResponse(PortletResponse.class));
assertSame(portletResponse, request.getNativeResponse(RenderResponse.class));
assertSame(portletResponse, request.getNativeResponse(MockRenderResponse.class));
assertNull(request.getNativeResponse(MultipartRequest.class));
}
}

View File

@@ -701,18 +701,18 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
throws Exception {
return AnnotationMethodHandlerAdapter.this.createBinder(
(HttpServletRequest) webRequest.getNativeRequest(), target, objectName);
webRequest.getNativeRequest(HttpServletRequest.class), target, objectName);
}
@Override
protected void doBind(WebDataBinder binder, NativeWebRequest webRequest) throws Exception {
ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
servletBinder.bind((ServletRequest) webRequest.getNativeRequest());
servletBinder.bind(webRequest.getNativeRequest(ServletRequest.class));
}
@Override
protected HttpInputMessage createHttpInputMessage(NativeWebRequest webRequest) throws Exception {
HttpServletRequest servletRequest = (HttpServletRequest) webRequest.getNativeRequest();
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
return AnnotationMethodHandlerAdapter.this.createHttpInputMessage(servletRequest);
}
@@ -739,7 +739,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
protected Object resolveCookieValue(String cookieName, Class paramType, NativeWebRequest webRequest)
throws Exception {
HttpServletRequest servletRequest = (HttpServletRequest) webRequest.getNativeRequest();
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
Cookie cookieValue = WebUtils.getCookie(servletRequest, cookieName);
if (Cookie.class.isAssignableFrom(paramType)) {
return cookieValue;
@@ -757,7 +757,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
protected String resolvePathVariable(String pathVarName, Class paramType, NativeWebRequest webRequest)
throws Exception {
HttpServletRequest servletRequest = (HttpServletRequest) webRequest.getNativeRequest();
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
Map<String, String> uriTemplateVariables =
(Map<String, String>) servletRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
if (uriTemplateVariables == null || !uriTemplateVariables.containsKey(pathVarName)) {
@@ -769,8 +769,8 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
@Override
protected Object resolveStandardArgument(Class parameterType, NativeWebRequest webRequest) throws Exception {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
HttpServletResponse response = (HttpServletResponse) webRequest.getNativeResponse();
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
if (ServletRequest.class.isAssignableFrom(parameterType)) {
return request;

View File

@@ -110,11 +110,11 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
this.messageConverters = messageConverters;
}
@Override
protected ModelAndView doResolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
if (handler != null) {
Method handlerMethod = findBestExceptionHandlerMethod(handler, ex);
if (handlerMethod != null) {
@@ -137,7 +137,6 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
/**
* Finds the handler method that matches the thrown exception best.
*
* @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
@@ -145,7 +144,6 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
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>();
@@ -165,7 +163,6 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
"Ambiguous exception handler mapped for " + handledException + "]: {" +
oldMappedMethod + ", " + method + "}.");
}
}
}
}
@@ -176,10 +173,10 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
}
/**
* 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}.
*
* Returns all the exception classes handled by the given method.
* <p>The 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
*/
@@ -202,9 +199,12 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
return result;
}
/** Returns the best matching method. Uses the {@link DepthComparator}. */
/**
* Returns the best matching method. Uses the {@link DepthComparator}.
*/
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());
@@ -217,31 +217,26 @@ 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 {
/**
* Resolves the arguments for the given method. Delegates to {@link #resolveCommonArgument}.
*/
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;
@@ -250,15 +245,14 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
/**
* Resolves common method arguments. Delegates to registered {@link #setCustomArgumentResolver(WebArgumentResolver)
* argumentResolvers} first, then checking {@link #resolveStandardArgument}.
*
* @param methodParameter the method parameter
* @param webRequest the request
* @param thrownException the exception thrown
* @return the argument value, or {@link 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) {
@@ -282,25 +276,24 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
}
/**
* Resolves standard method arguments. 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}.
*
* 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 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;
}
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
HttpServletResponse response = (HttpServletResponse) webRequest.getNativeResponse();
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
if (ServletRequest.class.isAssignableFrom(parameterType)) {
return request;
@@ -416,7 +409,9 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
}
/** Comparator capable of sorting exceptions based on their depth from the thrown exception type. */
/**
* Comparator capable of sorting exceptions based on their depth from the thrown exception type.
*/
private static class DepthComparator implements Comparator<Class<? extends Throwable>> {
private final Class<? extends Throwable> handlerExceptionType;
@@ -443,6 +438,6 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
}
return getDepth(exceptionType.getSuperclass(), depth + 1);
}
}
}

View File

@@ -427,8 +427,9 @@ public class HandlerMethodInvoker {
paramName = getRequiredParameterName(methodParam);
}
Object paramValue = null;
if (webRequest.getNativeRequest() instanceof MultipartRequest) {
paramValue = ((MultipartRequest) webRequest.getNativeRequest()).getFile(paramName);
MultipartRequest multipartRequest = webRequest.getNativeRequest(MultipartRequest.class);
if (multipartRequest != null) {
paramValue = multipartRequest.getFile(paramName);
}
if (paramValue == null) {
String[] paramValues = webRequest.getParameterValues(paramName);

View File

@@ -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.
@@ -101,9 +101,9 @@ public class WebRequestDataBinder extends WebDataBinder {
public void bind(WebRequest request) {
MutablePropertyValues mpvs = new MutablePropertyValues(request.getParameterMap());
if (request instanceof NativeWebRequest) {
Object nativeRequest = ((NativeWebRequest) request).getNativeRequest();
if (nativeRequest instanceof MultipartRequest) {
bindMultipartFiles(((MultipartRequest) nativeRequest).getFileMap(), mpvs);
MultipartRequest multipartRequest = ((NativeWebRequest) request).getNativeRequest(MultipartRequest.class);
if (multipartRequest != null) {
bindMultipartFiles(multipartRequest.getFileMap(), mpvs);
}
}
doBind(mpvs);

View File

@@ -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.
@@ -51,6 +51,28 @@ public class FacesWebRequest extends FacesRequestAttributes implements NativeWeb
return getExternalContext().getResponse();
}
@SuppressWarnings("unchecked")
public <T> T getNativeRequest(Class<T> requiredType) {
if (requiredType != null) {
Object request = getExternalContext().getRequest();
if (requiredType.isInstance(request)) {
return (T) request;
}
}
return null;
}
@SuppressWarnings("unchecked")
public <T> T getNativeResponse(Class<T> requiredType) {
if (requiredType != null) {
Object response = getExternalContext().getResponse();
if (requiredType.isInstance(response)) {
return (T) response;
}
}
return null;
}
public String getHeader(String headerName) {
return getExternalContext().getRequestHeaderMap().get(headerName);

View File

@@ -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.
@@ -44,4 +44,26 @@ public interface NativeWebRequest extends WebRequest {
*/
Object getNativeResponse();
/**
* Return the underlying native request object, if available.
* @param requiredType the desired type of request object
* @return the matching request object, or <code>null</code> if none
* of that type is available
* @see javax.servlet.http.HttpServletRequest
* @see javax.portlet.ActionRequest
* @see javax.portlet.RenderRequest
*/
<T> T getNativeRequest(Class<T> requiredType);
/**
* Return the underlying native request object, if available.
* @param requiredType the desired type of response object
* @return the matching response object, or <code>null</code> if none
* of that type is available
* @see javax.servlet.http.HttpServletRequest
* @see javax.portlet.ActionRequest
* @see javax.portlet.RenderRequest
*/
<T> T getNativeResponse(Class<T> requiredType);
}

View File

@@ -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.
@@ -20,6 +20,10 @@ import java.security.Principal;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.ServletResponse;
import javax.servlet.ServletResponseWrapper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@@ -80,6 +84,44 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
return getResponse();
}
@SuppressWarnings("unchecked")
public <T> T getNativeRequest(Class<T> requiredType) {
if (requiredType != null) {
ServletRequest request = getRequest();
while (request != null) {
if (requiredType.isInstance(request)) {
return (T) request;
}
else if (request instanceof ServletRequestWrapper) {
request = ((ServletRequestWrapper) request).getRequest();
}
else {
request = null;
}
}
}
return null;
}
@SuppressWarnings("unchecked")
public <T> T getNativeResponse(Class<T> requiredType) {
if (requiredType != null) {
ServletResponse response = getResponse();
while (response != null) {
if (requiredType.isInstance(response)) {
return (T) response;
}
else if (response instanceof ServletResponseWrapper) {
response = ((ServletResponseWrapper) response).getResponse();
}
else {
response = null;
}
}
}
return null;
}
public String getHeader(String headerName) {
return getRequest().getHeader(headerName);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2006 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.
@@ -18,17 +18,27 @@ package org.springframework.web.context.request;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import junit.framework.TestCase;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.multipart.MultipartRequest;
/**
* @author Juergen Hoeller
* @since 26.07.2006
*/
public class ServletWebRequestTests extends TestCase {
public class ServletWebRequestTests {
@Test
public void testParameters() {
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
servletRequest.addParameter("param1", "value1");
@@ -53,6 +63,7 @@ public class ServletWebRequestTests extends TestCase {
assertEquals("value2a", ((String[]) paramMap.get("param2"))[1]);
}
@Test
public void testLocale() {
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
servletRequest.addPreferredLocale(Locale.UK);
@@ -61,4 +72,40 @@ public class ServletWebRequestTests extends TestCase {
assertEquals(Locale.UK, request.getLocale());
}
@Test
public void testNativeRequest() {
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
ServletWebRequest request = new ServletWebRequest(servletRequest, servletResponse);
assertSame(servletRequest, request.getNativeRequest());
assertSame(servletRequest, request.getNativeRequest(ServletRequest.class));
assertSame(servletRequest, request.getNativeRequest(HttpServletRequest.class));
assertSame(servletRequest, request.getNativeRequest(MockHttpServletRequest.class));
assertNull(request.getNativeRequest(MultipartRequest.class));
assertSame(servletResponse, request.getNativeResponse());
assertSame(servletResponse, request.getNativeResponse(ServletResponse.class));
assertSame(servletResponse, request.getNativeResponse(HttpServletResponse.class));
assertSame(servletResponse, request.getNativeResponse(MockHttpServletResponse.class));
assertNull(request.getNativeResponse(MultipartRequest.class));
}
@Test
public void testDecoratedNativeRequest() {
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
HttpServletRequest decoratedRequest = new HttpServletRequestWrapper(servletRequest);
HttpServletResponse decoratedResponse = new HttpServletResponseWrapper(servletResponse);
ServletWebRequest request = new ServletWebRequest(decoratedRequest, decoratedResponse);
assertSame(decoratedRequest, request.getNativeRequest());
assertSame(decoratedRequest, request.getNativeRequest(ServletRequest.class));
assertSame(decoratedRequest, request.getNativeRequest(HttpServletRequest.class));
assertSame(servletRequest, request.getNativeRequest(MockHttpServletRequest.class));
assertNull(request.getNativeRequest(MultipartRequest.class));
assertSame(decoratedResponse, request.getNativeResponse());
assertSame(decoratedResponse, request.getNativeResponse(ServletResponse.class));
assertSame(decoratedResponse, request.getNativeResponse(HttpServletResponse.class));
assertSame(servletResponse, request.getNativeResponse(MockHttpServletResponse.class));
assertNull(request.getNativeResponse(MultipartRequest.class));
}
}