2012-08-29 41 views
2

我用我的項目春季MVC3,和我很困惑與請求映射模式(在url最後一個斜線)請求映射URL模式

就拿下面的控制器方法:

@RequestMapping(value = "/{id}/edit", method = RequestMethod.GET) 
public String edit(@PathVariable int id, Model model) { 
    model.addAttribute(postDao.query(id)); 
    return "posts/edit"; 
} 

它可以在得到url「http://localhsot/app/posts/3/edit」時起作用,但是如果得到url「http://localhsot/app/posts/3/edit/」,它就無法使用該方法。

我知道我可以設置請求映射值如下:

@RequestMapping(value = {"/{id}/edit","/{id}/edit/"}) 

但我不知道是否有任何其他的解決辦法嗎?看來,rails會忽略url中的最後一個斜槓。

UPDATE:

的servlet-context.xml中:

<mvc:annotation-driven /> 
<mvc:view-controller path="/" view-name="home" /> 
<context:component-scan base-package="com.king.controller" /> 
<mvc:resources mapping="/res/**" location="/res/" /> 
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> 
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> 
    <property name="prefix" value="/WEB-INF/jsp/" /> 
    <property name="suffix" value=".jsp" /> 
</bean> 

的web.xml

<filter> 
    <filter-name>httpMethodFilter</filter-name> 
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>httpMethodFilter</filter-name> 
    <servlet-name>modelServlet</servlet-name> 
</filter-mapping> 
<servlet> 
    <servlet-name>modelServlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring/servlet-context.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>modelServlet</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 
+0

我正在使用spring mvc3,當URL的末尾存在「/」時,我的映射將使用相同的控制器方法。我不記得使用任何特殊的東西來實現這一點。你使用什麼服務器?你可以發佈你的web.xml文件嗎? – jelies

回答

4

我認爲你正在試圖解決錯誤的問題。

如果您匹配的網址既有或沒有結尾斜槓,您將因爲duplicate content而從搜索引擎中收到差評。

我會做什麼是添加發送所有請求,而尾隨斜線使用狀態代碼HttpServletResponse.SC_MOVED_PERMANENTLY

這裏斜線(反之亦然)重定向一個過濾器是一個最小的實現這樣一個過濾器:

public class CanonicalUrlFilter implements Filter { 
    @Override 
    public void init(final FilterConfig filterConfig) throws ServletException { } 

    @Override 
    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, 
      final FilterChain filterChain) throws IOException, ServletException { 
     if (servletRequest instanceof HttpServletRequest) { 
      HttpServletRequest hsr = (HttpServletRequest) servletRequest; 
      if (hsr.getMethod().equals("GET") && !hsr.getRequestURI().endsWith("/") && (hsr.getQueryString() == null)) { 
       HttpServletResponse response = (HttpServletResponse) servletResponse; 
       response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); 
       response.sendRedirect(hsr.getRequestURI() + "/"); 
       return; 
      } 
     } 

     filterChain.doFilter(servletRequest, servletResponse); 
    } 

    @Override 
    public void destroy() { } 
} 
+0

感謝您的回覆和不錯的代碼。但是我不知道這是否會導致性能問題?因爲重定向是另一個請求。 – hguser

+0

開銷很小,您將在所有使用的網站上始終重定向。但它當然在那裏。 –

+0

並且這個問題在post方法中也存在。 – hguser