2

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>
1
  • I'm using spring mvc3 and my mappings are going to the same controller method when "/" exists at the end of URL or not. I don't remember to use anything special to accomplish this. What server are you using? could you post your web.xml file? Commented Aug 29, 2012 at 11:22

1 Answer 1

4

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() { }
}
Sign up to request clarification or add additional context in comments.

4 Comments

thanks for your reply and nice code. however I wonder if this will cause performance problem?since the redirect is another request.
the overhead is minimal, you are redirected all the time on all sites you are using. But it is there of course.
and this problem also exist in post method.
@hguser POST requests seldom originate from third party sites. So when you create forms, you need to pay attention to the format links on your site have. Also, it's good practice to redirect to a GET request after a post request anyway, so the end user will probably not even be aware of your POST URL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.