Reputation: 36068
I am using spring mvc3 in my project,and I am confused with the request mapping pattern (the last slash in the url)
Take the following controller method for example:
@RequestMapping(value = "/{id}/edit", method = RequestMethod.GET)
public String edit(@PathVariable int id, Model model) {
model.addAttribute(postDao.query(id));
return "posts/edit";
}
It works when get the url "http://localhsot/app/posts/3/edit
",however it can not the method if get the url "http://localhsot/app/posts/3/edit/
".
I know I can set the request mapping value like this:
@RequestMapping(value = {"/{id}/edit","/{id}/edit/"})
But I wonder if there is any other solution? It seems that rails will ignore the last slash in the 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>
Upvotes: 2
Views: 4721
Reputation: 299138
I think you are trying to solve the wrong problem.
If you match a URL both with and without a trailing slash, you will get a bad rating from search engines because of duplicate content.
What I would do is to add a Filter that sends all requests without trailing slash a redirect with trailing slash (or vice-versa) using status code HttpServletResponse.SC_MOVED_PERMANENTLY
Here is a minimal implementation of such a filter:
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() { }
}
Upvotes: 4