"url" macro in "spring.ftl" performs standard Servlet URL encoding automatically

This commit is contained in:
Juergen Hoeller 2009-02-18 23:55:32 +00:00
parent d3d0111439
commit 56bd995d9c
6 changed files with 51 additions and 20 deletions

View File

@ -19,6 +19,7 @@ package org.springframework.web.servlet.support;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext; import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.jstl.core.Config; import javax.servlet.jsp.jstl.core.Config;
@ -70,7 +71,8 @@ public class JspAwareRequestContext extends RequestContext {
throw new IllegalArgumentException("RequestContext only supports HTTP requests"); throw new IllegalArgumentException("RequestContext only supports HTTP requests");
} }
this.pageContext = pageContext; this.pageContext = pageContext;
initContext((HttpServletRequest) pageContext.getRequest(), pageContext.getServletContext(), model); initContext((HttpServletRequest) pageContext.getRequest(), (HttpServletResponse) pageContext.getResponse(),
pageContext.getServletContext(), model);
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,9 +20,9 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import javax.servlet.jsp.jstl.core.Config; import javax.servlet.jsp.jstl.core.Config;
@ -86,11 +86,13 @@ public class RequestContext {
protected static final boolean jstlPresent = ClassUtils.isPresent( protected static final boolean jstlPresent = ClassUtils.isPresent(
"javax.servlet.jsp.jstl.core.Config", JspAwareRequestContext.class.getClassLoader()); "javax.servlet.jsp.jstl.core.Config", RequestContext.class.getClassLoader());
private HttpServletRequest request; private HttpServletRequest request;
private HttpServletResponse response;
private Map<String, Object> model; private Map<String, Object> model;
private WebApplicationContext webApplicationContext; private WebApplicationContext webApplicationContext;
@ -119,7 +121,7 @@ public class RequestContext {
* @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.ServletContext) * @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.ServletContext)
*/ */
public RequestContext(HttpServletRequest request) { public RequestContext(HttpServletRequest request) {
initContext(request, null, null); initContext(request, null, null, null);
} }
/** /**
@ -137,7 +139,7 @@ public class RequestContext {
* @see org.springframework.web.servlet.DispatcherServlet * @see org.springframework.web.servlet.DispatcherServlet
*/ */
public RequestContext(HttpServletRequest request, ServletContext servletContext) { public RequestContext(HttpServletRequest request, ServletContext servletContext) {
initContext(request, servletContext, null); initContext(request, null, servletContext, null);
} }
/** /**
@ -154,7 +156,7 @@ public class RequestContext {
* @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.ServletContext, Map) * @see #RequestContext(javax.servlet.http.HttpServletRequest, javax.servlet.ServletContext, Map)
*/ */
public RequestContext(HttpServletRequest request, Map<String, Object> model) { public RequestContext(HttpServletRequest request, Map<String, Object> model) {
initContext(request, null, model); initContext(request, null, null, model);
} }
/** /**
@ -165,6 +167,7 @@ public class RequestContext {
* <p>If a ServletContext is specified, the RequestContext will also * <p>If a ServletContext is specified, the RequestContext will also
* work with a root WebApplicationContext (outside a DispatcherServlet). * work with a root WebApplicationContext (outside a DispatcherServlet).
* @param request current HTTP request * @param request current HTTP request
* @param response current HTTP response
* @param servletContext the servlet context of the web application * @param servletContext the servlet context of the web application
* (can be <code>null</code>; necessary for fallback to root WebApplicationContext) * (can be <code>null</code>; necessary for fallback to root WebApplicationContext)
* @param model the model attributes for the current view * @param model the model attributes for the current view
@ -172,8 +175,10 @@ public class RequestContext {
* @see org.springframework.web.context.WebApplicationContext * @see org.springframework.web.context.WebApplicationContext
* @see org.springframework.web.servlet.DispatcherServlet * @see org.springframework.web.servlet.DispatcherServlet
*/ */
public RequestContext(HttpServletRequest request, ServletContext servletContext, Map<String, Object> model) { public RequestContext(HttpServletRequest request, HttpServletResponse response,
initContext(request, servletContext, model); ServletContext servletContext, Map<String, Object> model) {
initContext(request, response, servletContext, model);
} }
/** /**
@ -199,8 +204,11 @@ public class RequestContext {
* @see org.springframework.web.servlet.DispatcherServlet#LOCALE_RESOLVER_ATTRIBUTE * @see org.springframework.web.servlet.DispatcherServlet#LOCALE_RESOLVER_ATTRIBUTE
* @see org.springframework.web.servlet.DispatcherServlet#THEME_RESOLVER_ATTRIBUTE * @see org.springframework.web.servlet.DispatcherServlet#THEME_RESOLVER_ATTRIBUTE
*/ */
protected void initContext(HttpServletRequest request, ServletContext servletContext, Map<String, Object> model) { protected void initContext(HttpServletRequest request, HttpServletResponse response,
ServletContext servletContext, Map<String, Object> model) {
this.request = request; this.request = request;
this.response = response;
this.model = model; this.model = model;
// Fetch WebApplicationContext, either from DispatcherServlet or the root context. // Fetch WebApplicationContext, either from DispatcherServlet or the root context.
@ -378,6 +386,20 @@ public class RequestContext {
return this.urlPathHelper.getOriginatingContextPath(this.request); return this.urlPathHelper.getOriginatingContextPath(this.request);
} }
/**
* Return a context-aware URl for the given relative URL.
* @param relativeUrl the relative URL part
* @return a URL that points back to the server with an absolute path
* (also URL-encoded accordingly)
*/
public String getContextUrl(String relativeUrl) {
String url = getContextPath() + relativeUrl;
if (this.response != null) {
url = this.response.encodeURL(url);
}
return url;
}
/** /**
* Return the request URI of the original request, that is, the invoked URL * Return the request URI of the original request, that is, the invoked URL
* without parameters. This is particularly useful as HTML form action target, * without parameters. This is particularly useful as HTML form action target,

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -159,7 +159,7 @@ public abstract class AbstractTemplateView extends AbstractUrlBasedView {
} }
// Expose RequestContext instance for Spring macros. // Expose RequestContext instance for Spring macros.
model.put(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE, model.put(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE,
new RequestContext(request, getServletContext(), model)); new RequestContext(request, response, getServletContext(), model));
} }
applyContentType(response); applyContentType(response);

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -243,7 +243,7 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement
// Expose RequestContext? // Expose RequestContext?
if (this.requestContextAttribute != null) { if (this.requestContextAttribute != null) {
mergedModel.put(this.requestContextAttribute, createRequestContext(request, mergedModel)); mergedModel.put(this.requestContextAttribute, createRequestContext(request, response, mergedModel));
} }
prepareResponse(request, response); prepareResponse(request, response);
@ -261,8 +261,10 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement
* @see #setRequestContextAttribute * @see #setRequestContextAttribute
* @see org.springframework.web.servlet.support.RequestContext * @see org.springframework.web.servlet.support.RequestContext
*/ */
protected RequestContext createRequestContext(HttpServletRequest request, Map<String, Object> model) { protected RequestContext createRequestContext(
return new RequestContext(request, getServletContext(), model); HttpServletRequest request, HttpServletResponse response, Map<String, Object> model) {
return new RequestContext(request, response, getServletContext(), model);
} }
/** /**

View File

@ -86,7 +86,7 @@
* Takes a relative URL and makes it absolute from the server root by * Takes a relative URL and makes it absolute from the server root by
* adding the context root for the web application. * adding the context root for the web application.
--> -->
<#macro url relativeUrl>${springMacroRequestContext.getContextPath()}${relativeUrl}</#macro> <#macro url relativeUrl>${springMacroRequestContext.getContextUrl(relativeUrl)}</#macro>
<#-- <#--
* bind * bind

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,10 +18,8 @@ package org.springframework.web.servlet.view;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.TestBean;
import org.springframework.web.servlet.support.BindStatus; import org.springframework.web.servlet.support.BindStatus;
import org.springframework.web.servlet.support.RequestContext; import org.springframework.web.servlet.support.RequestContext;
@ -129,6 +127,13 @@ public class DummyMacroRequestContext {
return this.contextPath; return this.contextPath;
} }
/**
* @see org.springframework.web.servlet.support.RequestContext#getContextUrl(String)
*/
public String getContextUrl(String relativeUrl) {
return getContextPath() + relativeUrl;
}
/** /**
* @see org.springframework.web.servlet.support.RequestContext#getBindStatus(String) * @see org.springframework.web.servlet.support.RequestContext#getBindStatus(String)
*/ */