revised common handler method processing for Portlet 2.0 update
This commit is contained in:
parent
464c7eedf2
commit
d950b56999
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.bind.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Meta annotation that indicates a web mapping annotation.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see RequestMapping
|
||||
*/
|
||||
@Target({ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Mapping {
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -165,6 +165,7 @@ import java.lang.annotation.Target;
|
|||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Mapping
|
||||
public @interface RequestMapping {
|
||||
|
||||
/**
|
||||
|
|
@ -202,8 +203,7 @@ public @interface RequestMapping {
|
|||
* When used at the type level, all method-level mappings inherit
|
||||
* this HTTP method restriction (i.e. the type-level restriction
|
||||
* gets checked before the handler method is even resolved).
|
||||
* <p><b>Currently only supported in Servlet environments!</b>
|
||||
* To be supported for Portlet 2.0 resource requests in Spring 3.0 as well.
|
||||
* <p>Supported for Servlet environments as well as Portlet 2.0 environments.
|
||||
*/
|
||||
RequestMethod[] method() default {};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -53,9 +53,9 @@ public class HandlerMethodResolver {
|
|||
|
||||
private final Set<Method> modelAttributeMethods = new LinkedHashSet<Method>();
|
||||
|
||||
private final RequestMapping typeLevelMapping;
|
||||
private RequestMapping typeLevelMapping;
|
||||
|
||||
private final boolean sessionAttributesFound;
|
||||
private boolean sessionAttributesFound;
|
||||
|
||||
private final Set<String> sessionAttributeNames = new HashSet<String>();
|
||||
|
||||
|
|
@ -65,13 +65,13 @@ public class HandlerMethodResolver {
|
|||
|
||||
|
||||
/**
|
||||
* Create a new HandlerMethodResolver for the specified handler type.
|
||||
* Initialize a new HandlerMethodResolver for the specified handler type.
|
||||
* @param handlerType the handler class to introspect
|
||||
*/
|
||||
public HandlerMethodResolver(final Class<?> handlerType) {
|
||||
public void init(final Class<?> handlerType) {
|
||||
ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
if (method.isAnnotationPresent(RequestMapping.class)) {
|
||||
if (isHandlerMethod(method)) {
|
||||
handlerMethods.add(ClassUtils.getMostSpecificMethod(method, handlerType));
|
||||
}
|
||||
else if (method.isAnnotationPresent(InitBinder.class)) {
|
||||
|
|
@ -91,6 +91,10 @@ public class HandlerMethodResolver {
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean isHandlerMethod(Method method) {
|
||||
return method.isAnnotationPresent(RequestMapping.class);
|
||||
}
|
||||
|
||||
|
||||
public final boolean hasHandlerMethods() {
|
||||
return !this.handlerMethods.isEmpty();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -42,7 +42,6 @@ import org.springframework.beans.factory.BeanInitializationException;
|
|||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.i18n.LocaleContext;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.OrderComparator;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.support.PropertiesLoaderUtils;
|
||||
|
|
@ -50,9 +49,6 @@ import org.springframework.ui.context.ThemeSource;
|
|||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.multipart.MultipartException;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.multipart.MultipartResolver;
|
||||
|
|
@ -282,9 +278,6 @@ public class DispatcherServlet extends FrameworkServlet {
|
|||
/** Perform cleanup of request attributes after include request? */
|
||||
private boolean cleanupAfterInclude = true;
|
||||
|
||||
/** Expose LocaleContext and RequestAttributes as inheritable for child threads? */
|
||||
private boolean threadContextInheritable = false;
|
||||
|
||||
|
||||
/** MultipartResolver used by this servlet */
|
||||
private MultipartResolver multipartResolver;
|
||||
|
|
@ -372,22 +365,6 @@ public class DispatcherServlet extends FrameworkServlet {
|
|||
this.cleanupAfterInclude = cleanupAfterInclude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to expose the LocaleContext and RequestAttributes as inheritable
|
||||
* for child threads (using an {@link java.lang.InheritableThreadLocal}).
|
||||
* <p>Default is "false", to avoid side effects on spawned background threads.
|
||||
* Switch this to "true" to enable inheritance for custom child threads which
|
||||
* are spawned during request processing and only used for this request
|
||||
* (that is, ending after their initial task, without reuse of the thread).
|
||||
* <p><b>WARNING:</b> Do not use inheritance for child threads if you are
|
||||
* accessing a thread pool which is configured to potentially add new threads
|
||||
* on demand (e.g. a JDK {@link java.util.concurrent.ThreadPoolExecutor}),
|
||||
* since this will expose the inherited context to such a pooled thread.
|
||||
*/
|
||||
public void setThreadContextInheritable(boolean threadContextInheritable) {
|
||||
this.threadContextInheritable = threadContextInheritable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This implementation calls {@link #initStrategies}.
|
||||
|
|
@ -815,19 +792,6 @@ public class DispatcherServlet extends FrameworkServlet {
|
|||
HandlerExecutionChain mappedHandler = null;
|
||||
int interceptorIndex = -1;
|
||||
|
||||
// Expose current LocaleResolver and request as LocaleContext.
|
||||
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
|
||||
LocaleContextHolder.setLocaleContext(buildLocaleContext(request), this.threadContextInheritable);
|
||||
|
||||
// Expose current RequestAttributes to current thread.
|
||||
RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Bound request context to thread: " + request);
|
||||
}
|
||||
|
||||
try {
|
||||
ModelAndView mv = null;
|
||||
boolean errorView = false;
|
||||
|
|
@ -917,16 +881,6 @@ public class DispatcherServlet extends FrameworkServlet {
|
|||
if (processedRequest != request) {
|
||||
cleanupMultipart(processedRequest);
|
||||
}
|
||||
|
||||
// Reset thread-bound context.
|
||||
RequestContextHolder.setRequestAttributes(previousRequestAttributes, this.threadContextInheritable);
|
||||
LocaleContextHolder.setLocaleContext(previousLocaleContext, this.threadContextInheritable);
|
||||
|
||||
// Clear request attributes.
|
||||
requestAttributes.requestCompleted();
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Cleared thread-bound request context: " + request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -973,6 +927,7 @@ public class DispatcherServlet extends FrameworkServlet {
|
|||
* @param request current HTTP request
|
||||
* @return the corresponding LocaleContext
|
||||
*/
|
||||
@Override
|
||||
protected LocaleContext buildLocaleContext(final HttpServletRequest request) {
|
||||
return new LocaleContext() {
|
||||
public Locale getLocale() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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,7 +18,6 @@ package org.springframework.web.servlet;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
|
@ -32,8 +31,14 @@ import org.springframework.context.ApplicationListener;
|
|||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.SourceFilteringListener;
|
||||
import org.springframework.context.i18n.LocaleContext;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.context.i18n.SimpleLocaleContext;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.context.support.ServletRequestHandledEvent;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.springframework.web.context.support.XmlWebApplicationContext;
|
||||
|
|
@ -129,6 +134,9 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
|
|||
/** Should we publish a ServletRequestHandledEvent at the end of each request? */
|
||||
private boolean publishEvents = true;
|
||||
|
||||
/** Expose LocaleContext and RequestAttributes as inheritable for child threads? */
|
||||
private boolean threadContextInheritable = false;
|
||||
|
||||
/** Should we dispatch an HTTP OPTIONS request to {@link #doService}? */
|
||||
private boolean dispatchOptionsRequest = false;
|
||||
|
||||
|
|
@ -230,6 +238,22 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
|
|||
this.publishEvents = publishEvents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to expose the LocaleContext and RequestAttributes as inheritable
|
||||
* for child threads (using an {@link java.lang.InheritableThreadLocal}).
|
||||
* <p>Default is "false", to avoid side effects on spawned background threads.
|
||||
* Switch this to "true" to enable inheritance for custom child threads which
|
||||
* are spawned during request processing and only used for this request
|
||||
* (that is, ending after their initial task, without reuse of the thread).
|
||||
* <p><b>WARNING:</b> Do not use inheritance for child threads if you are
|
||||
* accessing a thread pool which is configured to potentially add new threads
|
||||
* on demand (e.g. a JDK {@link java.util.concurrent.ThreadPoolExecutor}),
|
||||
* since this will expose the inherited context to such a pooled thread.
|
||||
*/
|
||||
public void setThreadContextInheritable(boolean threadContextInheritable) {
|
||||
this.threadContextInheritable = threadContextInheritable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this servlet should dispatch an HTTP OPTIONS request to
|
||||
* the {@link #doService} method.
|
||||
|
|
@ -574,6 +598,19 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
|
|||
long startTime = System.currentTimeMillis();
|
||||
Throwable failureCause = null;
|
||||
|
||||
// Expose current LocaleResolver and request as LocaleContext.
|
||||
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
|
||||
LocaleContextHolder.setLocaleContext(buildLocaleContext(request), this.threadContextInheritable);
|
||||
|
||||
// Expose current RequestAttributes to current thread.
|
||||
RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Bound request context to thread: " + request);
|
||||
}
|
||||
|
||||
try {
|
||||
doService(request, response);
|
||||
}
|
||||
|
|
@ -591,6 +628,16 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
|
|||
}
|
||||
|
||||
finally {
|
||||
// Reset thread-bound context.
|
||||
RequestContextHolder.setRequestAttributes(previousRequestAttributes, this.threadContextInheritable);
|
||||
LocaleContextHolder.setLocaleContext(previousLocaleContext, this.threadContextInheritable);
|
||||
|
||||
// Clear request attributes.
|
||||
requestAttributes.requestCompleted();
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Cleared thread-bound request context: " + request);
|
||||
}
|
||||
|
||||
if (failureCause != null) {
|
||||
this.logger.debug("Could not complete request", failureCause);
|
||||
}
|
||||
|
|
@ -610,6 +657,16 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a LocaleContext for the given request, exposing the request's
|
||||
* primary locale as current locale.
|
||||
* @param request current HTTP request
|
||||
* @return the corresponding LocaleContext
|
||||
*/
|
||||
protected LocaleContext buildLocaleContext(HttpServletRequest request) {
|
||||
return new SimpleLocaleContext(request.getLocale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the username for the given request.
|
||||
* <p>The default implementation takes the name of the UserPrincipal, if any.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -245,9 +245,9 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
|
|||
* @param uriTemplateVariables the URI template variables, can be <code>null</code> if no variables found
|
||||
* @return the final handler object
|
||||
*/
|
||||
protected Object buildPathExposingHandler(Object rawHandler,
|
||||
String pathWithinMapping,
|
||||
Map<String, String> uriTemplateVariables) {
|
||||
protected Object buildPathExposingHandler(
|
||||
Object rawHandler, String pathWithinMapping, Map<String, String> uriTemplateVariables) {
|
||||
|
||||
// Bean name or resolved handler?
|
||||
if (rawHandler instanceof String) {
|
||||
String handlerName = (String) rawHandler;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -428,7 +428,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
|
|||
private class ServletHandlerMethodResolver extends HandlerMethodResolver {
|
||||
|
||||
private ServletHandlerMethodResolver(Class<?> handlerType) {
|
||||
super(handlerType);
|
||||
init(handlerType);
|
||||
}
|
||||
|
||||
public Method resolveHandlerMethod(HttpServletRequest request) throws ServletException {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -36,18 +36,15 @@ abstract class ServletAnnotationMappingUtils {
|
|||
* @param request the current HTTP request to check
|
||||
*/
|
||||
public static boolean checkRequestMethod(RequestMethod[] methods, HttpServletRequest request) {
|
||||
if (!ObjectUtils.isEmpty(methods)) {
|
||||
boolean match = false;
|
||||
for (RequestMethod method : methods) {
|
||||
if (method.name().equals(request.getMethod())) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
return false;
|
||||
if (ObjectUtils.isEmpty(methods)) {
|
||||
return true;
|
||||
}
|
||||
for (RequestMethod method : methods) {
|
||||
if (method.name().equals(request.getMethod())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue