2011-08-07 89 views
20

我正在使用Spring MVC編寫一個Web應用程序。我使用的註解控制器等一切工作正常,當涉及到應用程序中的實際鏈接(表單操作,<a>標籤等)目前除了,我有這個(顯然略):JSP中的Spring MVC請求URL

//In the controller 
@RequestMapping(value="/admin/listPeople", method=RequestMethod.GET) 

//In the JSP 
<a href="/admin/listPeople">Go to People List</a> 

當我直接輸入URL如「http:// localhost:8080/MyApp/admin/listPeople」時,頁面加載正確。但是,上面的鏈接不起作用。它丟失了應用程序名稱「MyApp」。

有誰知道是否有一種方法來配置Spring在那裏拋出應用程序名稱?

讓我知道你是否需要查看我的任何Spring配置。我正在使用具有視圖解析器的標準調度程序servlet等。

+1

這是可能在彈簧3.0 '">People' –

回答

43

您需要預先爲鏈接預留上下文路徑。

// somewhere on the top of your JSP 
<c:set var="contextPath" value="${pageContext.request.contextPath}"/> 

... 
<a href="${contextPath}/admin/listPeople">Go to People List</a> 
+0

+1謝謝,我想到了這個,但我寧願用Spring來做。 –

+2

沒有這樣做的「春天」方式:)只有將節點從$ {contextPath}預注到鏈接的選項是,您將應用程序部署爲root用戶,因此它的上下文路徑爲「/」(正如Kevin所描述的);但我不會推薦這種方法,因爲它會使您的應用程序依賴於其部署。 – craftsman

+0

如果我記得正確的話,還有一個server.xml的方法。 – Kevin

0

我通常配置tomcat使用「/」的上下文根或將war部署爲ROOT.war。無論哪種方式,戰爭名稱不會成爲URL的一部分。

6

我更喜歡使用BASE標籤:

<base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/" /> 

然後,所有的鏈接可以像:

<a href="admin/listPeople">Go to People List</a> 
+0

我建議閱讀之前使用基本標記:http://stackoverflow.com/questions/1889076/is-it-recommended-to-use-the-base-html-tag –

13

c:url標籤將追加上下文路徑到您的網址。例如:

<c:url value="/admin/listPeople"/> 

或者,我更喜歡在我的Spring MVC應用程序中儘可能使用相對URL。因此,如果頁面位於/MyApp/index,鏈接<a href="admin/listPeople">將帶我到listPeople頁面。

如果您在URL層次結構中更深入,這也適用。您可以使用..來遍歷一個級別。所以在頁面上/MyApp/admin/people/aPerson,使用<a href="../listPeople">會喜歡回到列表頁面

0

你可以使用servletRelativeAction。我不確定這是什麼版本(目前我使用的是4.0.x),我沒有看到這方面的文檔,但是如果你看看支持Spring表單的代碼,你可能會猜到。只要確保你傳遞的路徑以「/」開頭。

例子:

<form:form class="form-horizontal" name="form" servletRelativeAction="/j_spring_security_check" method="POST"> 

見org.springframework.web.servlet.tags.form.FormTag:

protected String resolveAction() throws JspException { 
    String action = getAction(); 
    String servletRelativeAction = getServletRelativeAction(); 
    if (StringUtils.hasText(action)) { 
     action = getDisplayString(evaluate(ACTION_ATTRIBUTE, action)); 
     return processAction(action); 
    } 
    else if (StringUtils.hasText(servletRelativeAction)) { 
     String pathToServlet = getRequestContext().getPathToServlet(); 
     if (servletRelativeAction.startsWith("/") && !servletRelativeAction.startsWith(getRequestContext().getContextPath())) { 
      servletRelativeAction = pathToServlet + servletRelativeAction; 
     } 
     servletRelativeAction = getDisplayString(evaluate(ACTION_ATTRIBUTE, servletRelativeAction)); 
     return processAction(servletRelativeAction); 
    } 
    else { 
     String requestUri = getRequestContext().getRequestUri(); 
     ServletResponse response = this.pageContext.getResponse(); 
     if (response instanceof HttpServletResponse) { 
      requestUri = ((HttpServletResponse) response).encodeURL(requestUri); 
      String queryString = getRequestContext().getQueryString(); 
      if (StringUtils.hasText(queryString)) { 
       requestUri += "?" + HtmlUtils.htmlEscape(queryString); 
      } 
     } 
     if (StringUtils.hasText(requestUri)) { 
      return processAction(requestUri); 
     } 
     else { 
      throw new IllegalArgumentException("Attribute 'action' is required. " + 
        "Attempted to resolve against current request URI but request URI was null."); 
     } 
    } 
} 
4

正如我剛纔一直在試圖尋找這個問題的答案,這是第一個谷歌結果。

這現在可以使用MvcUriComponentsBuilder

這是4的一部分來完成。0版本的Spring MVC的

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.html

所需的方法是fromMappingName

從文檔:

創建從Spring MVC控制器方法的請求映射名稱的URL。 配置的HandlerMethodMappingNamingStrategy確定啓動時控制器方法請求映射的名稱。默認情況下,所有映射都會根據類名的大寫字母進行分配,後跟「#」作爲分隔符,然後是方法名稱。例如,對於名爲PersonController的類使用getPerson方法的「PC#getPerson」。如果命名約定沒有產生唯一結果,則可以通過@RequestMapping註釋的name屬性指定顯式名稱。

這主要是爲了在視圖渲染技術和EL表達式中使用。 Spring URL標記庫將此方法註冊爲一個名爲「mvcUrl」的函數。

例如,給定該控制器:

@RequestMapping("/people") 
class PersonController { 

    @RequestMapping("/{id}") 
    public HttpEntity getPerson(@PathVariable String id) { ... } 

} 

甲JSP可以準備一個URL到控制器的方法如下:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %> 

<a href="${s:mvcUrl('PC#getPerson').arg(0,"123").build()}">Get Person</a>