有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java spring servlet URL模式映射不使用星号

web.xml中,如果我使用如下完整路径指定servlet映射:

<servlet-mapping>
      <servlet-name>spring</servlet-name>
      <url-pattern>/view/admin</url-pattern>
</servlet-mapping>

它工作正常,但是如果我根据the specification(第12.2章)使用星号(*):

In the Web application deployment descriptor, the following syntax is used to define mappings:

  • A string beginning with a ‘ / ’ character and ending with a ‘ /* ’ suffix is used for path mapping.
  • A string beginning with a ‘ *. ’ prefix is used as an extension mapping. The empty string ("") is a special URL pattern that exactly maps to the application's context root, i.e., requests of the form http://host:port//. In this case the path info is ’ / ’ and the servlet path and context path is empty string (““).
  • A string containing only the ’ / ’ character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
  • All other strings are used for exact matches only.

像这样:

<servlet-mapping>
      <servlet-name>spring</servlet-name>
      <url-pattern>/view/*</url-pattern>
</servlet-mapping>

地图规则不起作用,glassfish给出了如下日志:

[glassfish 4.0] [WARNING] [] [org.springframework.web.servlet.PageNotFound] [tid: _ThreadID=19 _ThreadName=http-listener-1(2)] [timeMillis: 1422503740955] [levelValue: 900] [[No mapping found for HTTP request with URI [/view/admin] in DispatcherServlet with name 'spring']]

怎么了?(我已经找到了原因,请继续阅读)


有关Spring MVC配置和控制器类的其他信息

以下是评论要求的更多信息

完整的web.xml是:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
       <servlet>
              <servlet-name>spring</servlet-name>
              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
              <load-on-startup>1</load-on-startup>
       </servlet>

       <servlet-mapping>
              <servlet-name>spring</servlet-name>
              <url-pattern>/view/*</url-pattern>
       </servlet-mapping>
</web-app>

下面是spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd ">

       <mvc:annotation-driven></mvc:annotation-driven>

       <context:component-scan base-package="com.ksider.service.searchserver.controller"></context:component-scan>


       <bean id="freemarkerSettings" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
              <property name="templateLoaderPath" value="/WEB-INF/view/" />
              <property name="freemarkerSettings">
                     <props>

                            <prop key="template_update_delay">0</prop>
                            <prop key="default_encoding">UTF-8</prop>
                            <prop key="locale">zh_CN</prop>
                            <prop key="url_escaping_charset">UTF-8</prop>
                            <prop key="whitespace_stripping">true</prop>
                            <prop key="date_format">yyyy-MM-dd</prop>
                            <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                            <prop key="number_format">0.##</prop>
                            <prop key="classic_compatible">true</prop>
                     </props>
              </property>
              <property name="freemarkerVariables">
                     <map>
                            <entry key="xml_escape" value-ref="fmXmlEscape" />
                     </map>
              </property>
       </bean>

       <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>


       <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
              <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>

              <!-- <property name="viewNames" value="*.ftl"/> -->
              <property name="contentType" value="text/html; charset=utf-8"/>
              <property name="cache" value="true" />
              <property name="prefix" value="" />
              <property name="suffix" value=".ftl" />
              <property name="order" value="1"/>
              <property name="exposeSpringMacroHelpers" value="true"/>
              <property name="requestContextAttribute" value="rc"/>
       </bean>
</beans>

这是控制器:

package com.ksider.service.searchserver.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class AdminController {
    @RequestMapping(value = "/view/admin", method = RequestMethod.GET)
    public String getAdminPage(ModelMap modelMap){
        modelMap.put("Msg","hello");
        return "admin/index";
    }
}

进度更新

如果我使用

 <servlet-mapping>
         <servlet-name>spring</servlet-name>
         <url-pattern>/view/*</url-pattern>
 </servlet-mapping>

而不是

 <servlet-mapping>
              <servlet-name>spring</servlet-name>
              <url-pattern>/view/admin</url-pattern>
 </servlet-mapping>

我应该如何在每个请求中添加前缀/view,如 如果我想查询http://localhost:8080/view/admin,我应该改为查询http://localhost:8080/view/view/admin

我认为这是一个非常令人困惑的问题:-(

我只是检查了servlet映射引用,不知道为什么会发生这种情况。也许是什么把戏导致了春季mvcenter image description here

因此,问题变成了:

  • 这是什么原因?我应该如何避免在每个查询中添加前缀

共 (1) 个答案

  1. # 1 楼答案

    有两个不同的问题

    首先是servlet容器如何映射到servlet。您已经正确地解释了:如果servlet被映射到/view/admin/view/*,它将同样地接收请求

    接下来是spring如何解码和处理请求。Servlet规范3.0(3.5请求路径元素)说:

    • 当servlet映射到/view/admin时,servlet路径为/view/admin,路径信息为空
    • 当servlet映射到/view/*时,servlet路径为/view,路径信息id为/admin

    DispatcherServlet找到空路径信息时,它会在其映射中查找servlet路径(并找到您的控制器),但如果路径信息不为空,它会假定servlet路径是映射中不存在的前缀

    这就是为什么在/view/view/admin下找到控制器的原因:首先/view被servlet路径吃掉,路径信息/view/admin是控制器的映射

    DispatcherServlet映射到/view/*时,控制器映射不能包含servlet路径=>;控制器映射应该是/admin