我正在编写部署在Tomcat上的Spring MVC应用程序。
public class Application extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { };
}
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { SpringServletConfig.class };
}
protected String[] getServletMappings() {
return new String[] { "/*" };
}
}
Where SpringServletConfig is
@Configuration
@ComponentScan("com.example.controllers")
@EnableWebMvc
public class SpringServletConfig {
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
}
最后,我@Controller
在包装里com.example.controllers
@Controller
public class ExampleController {
@RequestMapping(path = "/home", method = RequestMethod.GET)
public String example() {
return "index";
}
}
我的应用程序的上下文名称为Example
。当我发送请求给
http://localhost:8080/Example/home
该应用程序以HTTP Status 404响应并记录以下内容
WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI `[/Example/WEB-INF/jsps/index.jsp]` in `DispatcherServlet` with name 'dispatcher'
我/WEB-INF/jsps/index.jsp
希望Spring MVC 拥有一个JSP资源,以使用我的控制器来处理请求并转发给JSP,所以为什么它会响应404?
Spring MVC应用程序将通过DispatcherServlet
你在Servlet
容器中注册的来处理所有请求。
它DispatcherServlet
查看它的ApplicationContext
(如果有的话)并向其ApplicationContext
注册以注册ContextLoaderListener
特殊豆,它需要设置其请求服务逻辑。这些bean在文档中进行了描述。
可以说是最重要的HandlerMapping
map 类型的bean
根据某些条件向处理程序传入的请求以及一系列预处理程序和后处理程序(处理程序拦截器),具体标准因HandlerMapping
实现而异。最流行的实现支持带注释的控制器,但也存在其他实现。
javadocHandlerMapping
进一步描述了实现必须如何表现。
在DispatcherServlet
发现这种类型的所有豆类和以某种顺序将它们登记(可定制)。在处理请求时,DispatcherServlet
循环遍历这些HandlerMapping
对象并对其进行测试,getHandler
以找到可以处理传入请求的对象(表示为standard)HttpServletRequest
。从4.3.x版本开始,如果找不到任何内容,它将记录你看到的警告
没有找到映射与URI HTTP请求[/some/path]
中DispatcherServlet
使用的名字SomeName
并且要么抛出一个NoHandlerFoundException
或立即提交一个404 Not Found状态码的响应。
为什么DispatcherServlet找不到HandlerMapping可以处理我的请求的?
最常见的HandlerMapping
实现是RequestMappingHandlerMapping
,该实现将@ControllerBean
注册为处理程序(实际上是其带@RequestMapping
注释的方法)。你可以自己声明这种类型的bean(使用@Bean
或<bean>
或其他机制),也可以使用内置的options
。这些是:
@Configuration
班级@EnableWebMvc
。<mvc:annotation-driven />
在你的XML配置中声明一个成员。RequestMappingHandlerMappingbean
(以及其他一些东西)。但是,如果HandlerMapping
没有处理程序,a 并不是很有用。RequestMappingHandlerMapping
期望有一些@Controllerbean,因此你也需要通过@BeanJava
配置中的方法或<bean>XML
配置中的声明,或者通过@Controller
对其中任一带注释类的组件进行扫描来声明它们。确保这些豆存在。如果你收到警告消息和404,并且已经正确配置了上述所有内容,那么你会将请求发送到错误的URI,该错误未由检测到的带@RequestMapping注释的处理程序方法处理。
该spring-webmvc库提供了其他内置的HandlerMapping
实现。例如,BeanNameUrlHandlerMapping
地图
从URL到名称以斜杠(“ /”)开头的bean
而且你总是可以自己编写。显然,你必须确保要发送的请求至少与注册HandlerMapping对象的处理程序之一匹配。
如果你没有隐式或显式注册任何HandlerMapping
bean(或detectAllHandlerMappingsis true
),则DispatcherServlet
注册一些defaults
。这些DispatcherServlet.properties
在与DispatcherServlet
类相同的包中定义。它们是BeanNameUrlHandlerMapping
和DefaultAnnotationHandlerMapping
(类似于RequestMappingHandlerMapping
但已弃用)。
调试
Spring MVC将记录通过注册的处理程序RequestMappingHandlerMapping
。例如,@Controller
喜欢
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
将在INFO级别记录以下内容
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
这描述了注册的映射。当你看到未找到任何处理程序的警告时,请将消息中的URI与此处列出的映射进行比较。@RequestMapping必需中指定的所有限制都必须匹配,Spring MVC才能选择处理程序。
其他HandlerMapping实现记录他们自己的语句,这些语句应该提示它们的映射和相应的处理程序。
同样,在DEBUG级别启用Spring日志记录以查看Spring注册了哪些bean
。它应该报告找到的带注释的类,扫描的包以及初始化的bean
。如果没有你期望的ApplicationContext
配置,请检查你的配置。
其他常见错误
A DispatcherServlet
只是典型的Java EE Servlet
。你与你的典型进行注册<web.xml> <servlet-class>
和<servlet-mapping>
申报,或直接通过ServletContext#addServlet
在一个WebApplicationInitializer
或与任何机构弹簧开机使用。因此,你必须依赖Servlet规范中指定的url映射逻辑,请参阅第12章。另请参见
web.xml中的Servlet URL映射如何使用?
考虑到这一点,一个常见的错误是DispatcherServlet
使用的url映射注册/*
,从@RequestMapping
处理程序方法返回视图名称,并期望呈现JSP。例如,考虑一个类似的处理程序方法
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
InternalResourceViewResolver
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
你可能希望将请求转发到该路径处的JSP资源/WEB-INF/jsps/example-view-name.jsp。这不会发生。相反,假设上下文名称为Example,则DisaptcherServlet意志报告
没有映射发现HTTP请求的URI与[/Example/WEB-INF/jsps/example-view-name.jsp]在DispatcherServlet名为“调度”
由于DispatcherServlet被映射到/*
与/*
匹配的一切(除了精确匹配,其具有更高的优先级),则DispatcherServlet将被选择以处理forward来自JstlView(通过返回InternalResourceViewResolver)。在几乎每种情况下,DispatcherServlet都不会配置来处理此类请求。
相反,在这种简单的情况下,你应该注册DispatcherServlet
to /
,将其标记为默认servlet。默认servlet是请求的最后一个匹配项。这将允许你的典型servlet容器在尝试使用默认servlet之前,选择一个内部Servlet实现,该实现映射到*.jsp
,以处理JSP资源(例如Tomcat拥有JspServlet)。
我正在编写一个部署在Tomcat上的Spring MVC应用程序。请参阅以下最小、完整且可验证的示例 其中是 最后,我在包 我的应用程序的上下文名称是。当我向 应用程序以HTTP状态404响应,并记录以下内容 我在我希望SpringMVC使用我的控制器来处理请求并转发给jsp,那么为什么它会用404来响应呢? 这是一个关于这个警告信息的问题的规范帖子。
我正在编写一个部署在Tomcat上的Spring MVC应用程序。请参阅以下最小、完整和可验证的示例 我在上有一个JSP资源,我希望Spring MVC使用我的控制器来处理请求并转发到JSP,那么为什么它用404来响应呢? 这是一个关于这个警告信息的问题的规范帖子。
我在我的SpringMVC项目中得到了这个错误。我必须在浏览器中手动添加完整的路径来运行代码,但我不能直接运行它。 web.xml:
我想配置文件中缺少一些东西,但我看不到。 当我放入浏览器-->localhost:8080/procura/notifications-->我在控制台中得到的是-->org.springframework.web.servlet.DispatcherServlet noHandlerFound警告:在名为“DispatcherServlet”的DispatcherServlet中没有找到URI[/
这是我的代码。我不知道这有什么问题。
我的web.xml applicationContext as 调度器servlet作为 与包com中相同的控制器。思维边缘。特斯塔普 当我点击. 警告:在带名称的DispatcherServlet中找不到与URI[/TestApp/samp]的HTTP请求的映射 此外,当Spring开始时,我没有看到Testapp/示例加载的处理程序 我猜我的组件扫描不起作用。为什么?还有其他原因吗 编辑:调度