为什么运行了java文件老是404_java – 为什么Spring MVC用404响应并报告“在...

您的标准Spring MVC应用程序将通过您在Servlet容器中注册的DispatcherServlet提供所有请求.

DispatcherServlet查看其ApplicationContext,如果可用,则使用ContextLoaderListener注册的ApplicationContext用于设置其请求服务逻辑的特殊bean. These beans are described in the documentation.

incoming requests to handlers and a list of pre- and post-processors

(handler interceptors) based on some criteria the details of which

vary by HandlerMapping implementation. The most popular implementation

supports annotated controllers but other implementations exists as

well.

DispatcherServlet查找此类型的所有bean并按某种顺序注册它们(可以自定义).在提供请求时,DispatcherServlet循环遍历这些HandlerMapping对象并使用getHandler测试每个对象,以找到可以处理传入请求的对象,表示为标准HttpServletRequest.从4.3.x开始,如果没有找到任何,你看到的是logs the warning

No mapping found for HTTP request with URI [/some/path] in DispatcherServlet with name SomeName

和either抛出NoHandlerFoundException或立即提交404 Not Found状态代码的响应.

为什么DispatcherServlet找不到可以处理我的请求的HandlerMapping?

最常见的HandlerMapping实现是RequestMappingHandlerMapping,它处理将@Controller bean注册为处理程序(实际上是他们的@RequestMapping注释方法).您可以自己声明这种类型的bean(使用@Bean或< bean>或其他机制),也可以使用the built-in options.这些是:

>使用@EnableWebMvc注释您的@Configuration类.

>声明一个< mvc:annotation-driven /> XML配置中的成员.

正如上面的链接所描述的,这两个都将注册一个RequestMappingHandlerMapping bean(以及一堆其他的东西).但是,没有处理程序,HandlerMapping不是很有用. RequestMappingHandlerMapping需要一些@Controller bean,所以你需要通过Java配置中的@Bean方法或< bean>来声明它们. XML配置中的声明或通过@Controller注释类的组件扫描.确保这些豆子存在.

如果您收到警告消息和404,并且您已正确配置了上述所有内容,则您将请求发送到错误的URI,该URI不会被检测到的@RequestMapping带注释的处理程序方法处理.

spring-webmvc库提供了其他内置的HandlerMapping实现.例如,BeanNameUrlHandlerMapping地图

from URLs to beans with names that start with a slash (“/”)

而你总是可以自己写.显然,您必须确保您发送的请求至少匹配一个已注册的HandlerMapping对象的处理程序.

如果您没有隐式或显式注册任何HandlerMapping bean(或者如果detectAllHandlerMappings为真),则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配置.

其他常见错误

DispatcherServlet只是一个典型的Java EE Servlet.您可以使用典型的< web.xml>注册它. &LT; servlet的类&GT;和< servlet-mapping>声明,或直接通过WebApplicationInitializer中的ServletContext#addServlet,或Spring引导使用的任何机制.因此,您必须依赖于Servlet specification中指定的url映射逻辑,请参阅第12章.另请参阅

考虑到这一点,一个常见的错误是使用/ *的url映射注册DispatcherServlet,从@RequestMapping处理程序方法返回视图名称,并期望呈现JSP.例如,考虑一个像这样的处理程序方法

@RequestMapping(path = "/example", method = RequestMethod.GET)

public String example() {

return "example-view-name";

}

@Bean

public InternalResourceViewResolver resolver() {

InternalResourceViewResolver vr = new InternalResourceViewResolver();

vr.setPrefix("/WEB-INF/jsps/");

vr.setSuffix(".jsp");

return vr;

}

您可能希望请求是forwarded到路径为/WEB-INF/jsps/example-view-name.jsp的JSP资源.这不会发生.相反,假设上下文名称为Example,DisaptcherServlet将报告

No mapping found for HTTP request with URI [/Example/WEB-INF/jsps/example-view-name.jsp] in DispatcherServlet with name ‘dispatcher’

因为DispatcherServlet映射到/ *和/ *匹配所有内容(具有更高优先级的完全匹配除外),所以将选择DispatcherServlet来处理JstlView中的转发(由InternalResourceViewResolver返回).几乎在所有情况下,DispatcherServlet都不会配置为处理这样??的请求.

相反,在这种简单的情况下,您应该将DispatcherServlet注册到/,将其标记为默认servlet.默认servlet是请求的最后一个匹配项.这将允许您的典型servlet容器在尝试使用默认servlet之前选择映射到* .jsp的内部Servlet实现来处理JSP资源(例如,Tomcat具有JspServlet).

这就是你在你的例子中看到的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值