【问题标题】:request mapping url pattern in spring mvc3spring mvc3中的请求映射url模式
【发布时间】:2012-08-23 19:44:23
【问题描述】:

我在我的项目中使用 spring mvc3,我对请求映射模式(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中的最后一个斜杠。

更新:

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>

【问题讨论】:

  • 我正在使用 spring mvc3,当 URL 末尾是否存在“/”时,我的映射将转到相同的控制器方法。我不记得使用任何特殊的东西来实现这一点。你用的是什么服务器?你能发布你的 web.xml 文件吗?

标签: spring spring-mvc


【解决方案1】:

我认为您正在尝试解决错误的问题。

如果你匹配一个带有和不带斜杠的 URL,你会因为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() { }
}

【讨论】:

  • 感谢您的回复和漂亮的代码。但是我想知道这是否会导致性能问题?因为重定向是另一个请求。
  • 开销极小,您在使用的所有站点上始终被重定向。但它当然存在。
  • 这个问题也存在于post方法中。
  • @hguser POST 请求很少来自第三方站点。所以当你创建表单时,你需要注意你网站上链接的格式。此外,无论如何,在发布请求之后重定向到 GET 请求是一种很好的做法,因此最终用户可能甚至不会知道您的 POST URL。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
  • 1970-01-01
  • 2019-11-13
  • 2014-05-01
  • 2023-03-09
  • 2018-11-12
相关资源
最近更新 更多