diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/Mapping.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/Mapping.java new file mode 100644 index 00000000000..afbd1f2e723 --- /dev/null +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/Mapping.java @@ -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 { + +} diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java index cd80754cf62..6adc9606d41 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/RequestMapping.java @@ -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). - *
Currently only supported in Servlet environments! - * To be supported for Portlet 2.0 resource requests in Spring 3.0 as well. + *
Supported for Servlet environments as well as Portlet 2.0 environments.
*/
RequestMethod[] method() default {};
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java
index 468e2f39fb7..ee350dfa27d 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java
@@ -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 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).
- * WARNING: 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() {
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/FrameworkServlet.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/FrameworkServlet.java
index 7e9f716f3a4..c71b5dcbef6 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/FrameworkServlet.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/FrameworkServlet.java
@@ -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}).
+ * 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).
+ * WARNING: 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.
* The default implementation takes the name of the UserPrincipal, if any.
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java
index d3e32e27d45..7e2a68499b8 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java
@@ -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 null if no variables found
* @return the final handler object
*/
- protected Object buildPathExposingHandler(Object rawHandler,
- String pathWithinMapping,
- Map