在web.xml
中,如果我用这样的完整路径指定servlet映射:
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/view/admin</url-pattern>
</servlet-mapping>
它工作正常,但如果我根据the specification使用星号(*)(第12.2章):
在Web应用程序部署描述符中,使用以下语法进行定义 映射:
- 以“/”字符开头并以“/ *”后缀结尾的字符串用于路径映射。
- 以'*开头的字符串。 '前缀用作扩展名映射。 空字符串(&#34;&#34;)是一个特殊的URL模式,它完全映射到 应用程序的上下文根,即http://host:port/ /形式的请求。在这种情况下,路径信息是'/',servlet路径和上下文路径是 空字符串(“”)。
- 仅包含'/'字符的字符串表示&#34;默认&#34; servlet的 应用。在这种情况下,servlet路径是请求URI减去上下文路径 并且路径信息为空。
- 所有其他字符串仅用于完全匹配。
像这样:
<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映射参考,并且无法弄清楚为什么会发生这种情况。也许一些技巧 Spring mvc 应该受到指责?
所以,问题变成了:
答案 0 :(得分:1)
有两个不同的问题。
首先是servlet容器如何映射到servlet。您已正确解释:如果servlet映射到/view/admin
或/view/*
,它将同等地接收请求。
接下来是spring DispatcherServlet
如何解码和处理请求。 Servlet规范3.0(3.5请求路径元素)说:
/view/admin
servlet路径为/view/admin
且路径信息为空时/view/*
servlet路径为/view
且路径信息为/admin
当DispatcherServlet
找到空路径信息时,它会在其映射中查找servlet路径(并找到您的控制器),但如果路径信息不为空,则它假定servlet路径是不是前缀的前缀在映射中。
这就是为什么你在/view/view/admin
下找到你的控制器的原因:第一个/view
被servlet路径吃掉而路径信息/view/admin
是控制器的映射。
将DispatcherServlet
映射到/view/*
时,控制器映射不得包含servlet path =&gt;你的控制器映射应该是/admin