【问题标题】:Why doesn't this Java servlet url-pattern/RequestMapping work?为什么这个 Java servlet url-pattern/RequestMapping 不起作用?
【发布时间】:2013-12-13 22:43:01
【问题描述】:

我已经定义了这个 RequestMapping/方法:

@RequestMapping( value={"/ViewReport/json", "/ViewReport/*/json"} , method = RequestMethod.GET)
public ModelAndView TestJson(final Model model, HttpServletRequest request){
    JSONObject json = new JSONObject();
    json.put("Hello", "Goodbye");
    json.put("request", request.getRequestURL());
    model.addAttribute("fnord", json.toJSONString());   
    return new ModelAndView("reportViewJson");  
}    

在我的web.xml 文件中,我有以下内容:

  <servlet-mapping>
    <servlet-name>autoreport</servlet-name>
    <url-pattern>/ViewReport/*/json</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>autoreport</servlet-name>
    <url-pattern>/ViewReport/json</url-pattern>
  </servlet-mapping>

现在,当我导航到 /ViewReport/json 时,我得到了预期的 JSON。但是,当我导航到 /ViewReport/42/json 时,我得到了 404。

我的服务器启动时有以下日志:

[ INFO] 23:51(AbstractUrlHandlerMapping.java:registerHandler:315)
Mapped URL path [/ViewReport/] onto handler 'reportViewController'

[DEBUG] 23:51(AbstractBeanFactory.java:doGetBean:246)
Returning cached instance of singleton bean 'reportViewController'

[ INFO] 23:51(AbstractUrlHandlerMapping.java:registerHandler:315)
Mapped URL path [/ViewReport/json] onto handler 'reportViewController'

[DEBUG] 23:51(AbstractBeanFactory.java:doGetBean:246)
Returning cached instance of singleton bean 'reportViewController'

[ INFO] 23:51(AbstractUrlHandlerMapping.java:registerHandler:315)
Mapped URL path [/ViewReport/json.*] onto handler 'reportViewController'

[DEBUG] 23:51(AbstractBeanFactory.java:doGetBean:246)
Returning cached instance of singleton bean 'reportViewController'

[ INFO] 23:51(AbstractUrlHandlerMapping.java:registerHandler:315)
Mapped URL path [/ViewReport/json/] onto handler 'reportViewController'

[DEBUG] 23:51(AbstractBeanFactory.java:doGetBean:246)
Returning cached instance of singleton bean 'reportViewController'

[ INFO] 23:51(AbstractUrlHandlerMapping.java:registerHandler:315)
Mapped URL path [/ViewReport/*/json] onto handler 'reportViewController'

[DEBUG] 23:51(AbstractBeanFactory.java:doGetBean:246)
Returning cached instance of singleton bean 'reportViewController'

[ INFO] 23:51(AbstractUrlHandlerMapping.java:registerHandler:315)
Mapped URL path [/ViewReport/*/json.*] onto handler 'reportViewController'

[DEBUG] 23:51(AbstractBeanFactory.java:doGetBean:246)
Returning cached instance of singleton bean 'reportViewController'

[ INFO] 23:51(AbstractUrlHandlerMapping.java:registerHandler:315)
Mapped URL path [/ViewReport/*/json/] onto handler 'reportViewController'

更新 2

在我的autoreport-servlet.xml 我有这个:

<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property
        name="webBindingInitializer">
        <!-- Configures Spring MVC DataBinder instances -->
        <bean
            class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="validator" ref="validator" />
        </bean>
    </property>
</bean>

【问题讨论】:

  • 您要映射的autoreport servlet 是什么? DispatcherServlet?如果是这样,请尝试将其映射到 /

标签: java servlets


【解决方案1】:

由于Servlet Specification (Section 11),以下映射无效:

<servlet-mapping>
    <servlet-name>autoreport</servlet-name>
    <url-pattern>/ViewReport/*/json</url-pattern>
</servlet-mapping>

路径映射之间不允许有*。对于路径映射,它只允许以/* 结尾。 (好吧,在吹毛求疵时,它实际上是有效且允许的,但它没有按预期被视为通配符。)

引用自 Servlet 规范:

在 Web 应用程序部署描述符中,以下语法是 用于定义映射:

  • 以“/”字符开头并以“/*”后缀结尾的字符串用于路径映射。
  • 以“*.”前缀开头的字符串用作扩展映射。
  • 仅包含“/”字符的字符串表示应用程序的“默认”servlet。在这种情况下,servlet 路径是请求 URI 减去上下文路径,并且路径信息为空。
  • 所有其他字符串仅用于完全匹配。

所以你的模式/ViewReport/*/json 是一个没有通配符的完全匹配模式。 这就是/ViewReport/42/json 给出HTTP 404 的原因,因为它不匹配任何模式。

【讨论】:

  • 那么我如何在那里获得映射?根据this document,这是可能的——“一个方法可以有任意数量的@PathVariable注解”——对吧?
  • 是的,这就是支持它的 Spring 注解。但不支持 web.xml 中的 servlet 映射。 Spring 有一个 dispatcher servlet,它必须根据 Servlet Specifiaction 映射到 web.xml 中。但是 Dispatcher Servlet 可以评估来自 Spring 注释的路径(在 web.xml 中定义的范围内)。
  • 好的 - 那么如何让 Spring 注释工作呢?因为现在不是 - 反正我有 @PathVariable 时也不是
【解决方案2】:

因为在使用 spring MVC 时,您不会在 web.xml 中为每个控制器方法配置映射,这就是 @RequestMapping 注释的用途。

您将 spring 调度程序 servlet 配置为一个 URL,然后 @RequestMapping 注释处理映射,相对于 spring 调度程序 servlet URL。

例如spring dispatcher servlet 映射到/mvc/*,你用@RequestMapping("/xyz")声明了一个方法,这个方法的URL就是&lt;contextPath&gt;/mvc/xyz。如果您将 Spring Dispatcher servlet 配置为 /*,则 URL 将为 &lt;contextPath&gt;/xyz

【讨论】:

  • 那么在这种情况下是什么意思?
  • 这意味着您需要从web.xml中删除您显示的URL映射,然后如果您想使用URL'/ViewReport/json'访问您的方法,您需要配置spring servlet模式“/*”。
  • 这似乎不起作用 - 我刚刚删除了 servlet-mapping 部分,现在只有一个带有 /* 的部分,但我无法访问 /ViewReport/json。不过,访问那个从来都不是问题。可以访问/ViewReport/{id}/json
猜你喜欢
  • 2011-05-12
  • 2023-03-04
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 2015-11-15
  • 2017-06-07
相关资源
最近更新 更多