从标题不难看出,框架搭建号后,编译部署并启动项目一切正常,并没有报任何的错误,但是从页面访问controller时缺报404[Not Found]的错误。
解决方案:
1、在这需要说明的是,由于后台从始至终没有报任何的错误,故我的文章里不会有出错的贴图,有人就会说了,为什么不把自己的配置文件贴给大家看呢,我认为没有必要, 因为接下来我会给大家讲解排错方法,并且贴上已经访问成功的完整代码贴图。其实刚开始一遇见这样的错误,自己也排查了一边没有任何的发现,于是就网上百度各种搜索,其中也搜到一些结果,按照提示操作一通都没有成功。这里我总结一下网上各种帖子的解决方案:
1、大量文章都是千篇一律的说处理器映射器和处理器适配器以及视图解析器没有配置好,于是教你怎么去配置处理器映射器,这里我总结一个处理器映射器和适配器以及视图解析器的配置
1.1、非注解的处理器映射器和适配器配置,注意:在这里处理器映射器的配置必须和处理器适配器的配置是成对的,还有必须在配置文件里声明注入你的controller,并且这个controller必须实现Controller接口。非注解的配置访问是根据声明注入的bean name来进行映射处理的,必须有name,而且name的值必须有根符号(“/”)。
1.2、注解的处理器映射器和适配器配置。注解的controller类必须使用@Controller进行注解,类中的方法使用@RequestMapping("")进行注解。注解的配置方式还有一种,即<mvc:annotation-driven/>注解驱动配置,这样更方便,实际项目也是这样使用的。
1.3、视图解析器的配置。
至此,springmvc的controller需要的处理器映射器和处理器适配器以及视图解析器的配置已经完成,当然实际要运行的时候还必须要有Controller包扫描,不然你的程序在实例化完sqlSessionFactory后会一直卡在那里,不做任何操作,页面也不会有任何的反映。
2、这网上的第二种解决方法说的最多的就是我上面说的Controller的包扫描没有加或者包扫描的配置是错误的,这如果说其他配置都OK的话,如果没有加包扫描,那么他不回报任何的错误,但是会输出日志,创建SqlSessionFactory的日志是有的,不会什么信息都没有。有的人将Controller的包扫描加成这样
<context:component-scan base-package="com.springmvc.ssm.controller.*"/>也是什么都没有的。正确的包扫描是这样的:
3、当然也有说jar包没有,这也有可能是有的,没有jar包报404很正常的。这里要说的是如果出现404,你的判断是jar包没有,那你就得去你的项目发布路径下的WEB-INF下的lib文件夹去找jar包,而不是你的eclipse里看有没有。更需要注意的是,有人在tomcat运行设置过发布路径,那就必须在你设置的发布路径下找,我的设置为tomcat的安装目录下的webapps下了。
4、其实忘了一个最多的说法,那就是说你的请求地址是错误的,这个只能说自己认真排查,一般人在出现404的时候第一反应就是请求地址的核对,所以这个我也不说了。但是在这里我强调一个现象,就是你的请求地址是正确的,但是你的目录里没有Controller里的方法返回的页面,这样也会出现404,但是这个404和之前的404是不一样的。比如我在我的testController的items映射的方法里返回的itemsLists,实际我的jsp下的JSP文件没有一个itemsLists.jsp,那么页面的错误就会是这样的:
5、还有一种解决办法说web.xml配置DispatcherServlet的时候servlet的映射关系<url-pattern>配置不正确,应该将<url-pattern>/*</url-pattern>改为<url-pattern>/*</url-pattern>,去掉根号后面的星号,当然如果确实这样写了,那这也是一种解决办法。
以上就是网上所说的解决这一问题的办法,其实也是我遇到这样的问题,在网上一通乱搜,挨个试了个遍。那么网上这么多的解决方法,我们到底应该去按哪个方法执行,像我一样挨个试一遍?就跟我一样,全部试完也不见得能解决你的问题,因为每个人的问题发生的原因都不一样,但是结果都一样,访问Controller失败,返回404。这也就是我写这篇文章的真正原因,我在这里不会贴出我解决该问题的代码,没有用对你,也许你的问题按照我的方法解决不了。那么我在这里将这个问题的解决思路抽取出来,这样大家就不用在网上搜各种解决方案还不一定适合你,只要按着这个思路找问题的根源,就不会有多大的问题。
解决方案思路:
1、分析问题原因
我们既然知道是404,那就肯定是路径的问题,至少在现有的开发环境中大多数404都是各种路径的问题,不管是没有对应的文件还是路径写错了。既然404是路径问题,那么我们再细化这个路径问题,把这个路径可以分为前台访问路径和后台映射路径。
1.1、前台访问路径:前台访问路径不用说就是我们在地址栏输入的路径,即http请求路径。
1.2、后台映射路径:那么后台映射路径就多了,分析这个问题其实也很简单,既然是映射路径,那么他是怎么映射的,从哪里映射的,映射到哪里去,完成这三个问题也就解决了这个问题了。
1.2.1、在哪里映射、映射到哪里去:其中从哪里映射和映射到那里去,这个问题很好回答,既然是springmvc,那么这个问题肯定在Controller里了,当然这里的映射到那里去也要根据你自己配置视图解析器的规则去写。
1.2.2、怎么映射:然后我们分析这个路径是怎么映射的,这里就有人说了,一个刚学的就去研究spring源码吗?其实我们一般情况下没必要去翻源码查看他的实现原理,但是你如果有能力看他的源码,会加深你对springmvc的理解,对你也是有益无害的。虽然说我们没有必要翻源码但是必须知道他的映射关系是怎么配置的,弄清楚这些,我相信你的问题也就解决了。
2、解决问题步骤
我们已经把这个问题细化了,那么就一步步来解决就行了,在这里我会穿插的将我的完整代码贴出来,大家可以参考,初学者直接拿去也是可以运行的。在这里我先把我的工程目录给大家放在这里。
2.1、前台访问路径:这个没有什么,只能是仔细的比对的你的请求路径是否正确,从项目工程名到到映射的方法名,再到返回的jsp名称。
2.2、从哪里映射,映射到哪里去:这个问题我们就考虑Controller类中映射是不是不正确,查看@RequestMapping("/映射地址")中的映射地址是否与访问地址对应。
返回路径是否正确,例如返回consigner,在视图解析器配置的路径规则下能不能找到consigner.jsp文件。
2.3、这里是重点,看他是怎么映射的。我们知道springmvc是有前端控制器来调配映射器和适配器去工作的,那么我们首先要确保前端控制器配置正确。前端控制器配置好了,还需要处理器映射器和适配器以及视图解析器都配置好才可以。那么我们就得一个一个得排查这些所谓的各种器都配置好了吗?我把我的配置贴出来给大家参考。
映射器、适配器和视图解析器:spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<mvc:annotation-driven/>
<!-- 扫描controller(controller层注入) -->
<context:component-scan base-package="com.springmvc.ssm.controller"/>
<!-- 非注解的bean声明注入 -->
<!-- <bean name="/testController" class="com.springmvc.ssm.controller.TestController"/> -->
<!-- 非注解处理器映射器 -->
<!-- <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> -->
<!-- 非注解处理器适配器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> -->
<!-- 注解映射器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> -->
<!-- 注解适配器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> -->
<!-- 避免IE在ajax请求时,返回json出现下载 -->
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 对模型视图添加前后缀 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
</beans>
前端控制器配置:web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<context-param>
<param-name>ssm-logistics</param-name>
<param-value>ssm-logistics.root</param-value>
</context-param>
<!-- 配置 Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring.xml;classpath:conf/spring-mybatis.xml</param-value>
</context-param>
<!-- 日志记录 -->
<context-param>
<!-- 日志配置文件路径 -->
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:conf/log4j.properties</param-value>
</context-param>
<context-param>
<!-- 日志页面的刷新间隔 -->
<param-name>log4jRefreshInterval</param-name>
<param-value>6000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 防止Spring内存溢出监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- springMVC核心配置 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 错误跳转页面 -->
<error-page>
<!-- 路径不正确 -->
<error-code>404</error-code>
<location>/WEB-INF/errorpage/404.jsp</location>
</error-page>
<error-page>
<!-- 没有访问权限,访问被禁止 -->
<error-code>405</error-code>
<location>/WEB-INF/errorpage/405.jsp</location>
</error-page>
<error-page>
<!-- 内部错误 -->
<error-code>500</error-code>
<location>/WEB-INF/errorpage/500.jsp</location>
</error-page>
<!-- 字符集过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2.4、如果说前面这些都配置好了,问题还是存在,我们就得去查看配置的这些器都起作用了没有,即这些配置文件有没有一步步的都加载到spring容器中。那么我们要在web.xml里面加载那些东西呢?因为我是SSM框架,所以spring的配置文件,springmvc的配置文件,mybatis的配置文件,mysql数据库的配置文件,spring和mybatis整合的配置文件等都要加载到spring容器中。当然每个人写配置文件的方式不一样,加载的方式也不一样,但是都有一定的约定必须遵循。我是这样加载的:大家可以看的web.xml配置文件,我在这里面加载了spring配置文件和springmvc的配置文件以及spring和mybatis整合的配置文件。现在将另外两个配置文件贴出来:
spring.xml
spring这里我引入了jdbc的配置文件,还加了service包的自动扫描,将service层注入到容器中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 引入jdbc配置文件 -->
<context:property-placeholder location="classpath:conf/jdbc.properties"/>
<!-- 扫描文件(自动将servicec层注入) -->
<context:component-scan base-package="com.springmvc.ssm.service"/>
</beans>
spring-mybatis.xml
这里我设置了连接池和事务管理,引入了mybatis的配置文件,加了mapper.xml及dao文件的自动扫描注入
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"
destroy-method="close" >
<property name="driverClassName">
<value>${jdbc_driverClassName}</value>
</property>
<property name="url">
<value>${jdbc_url}</value>
</property>
<property name="username">
<value>${jdbc_username}</value>
</property>
<property name="password">
<value>${jdbc_password}</value>
</property>
<!-- 连接池最大使用连接数 -->
<property name="maxActive">
<value>20</value>
</property>
<!-- 初始化连接大小 -->
<property name="initialSize">
<value>1</value>
</property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait">
<value>60000</value>
</property>
<!-- 连接池最大空闲 -->
<property name="maxIdle">
<value>20</value>
</property>
<!-- 连接池最小空闲 -->
<property name="minIdle">
<value>3</value>
</property>
<!-- 自动清除无用连接 -->
<property name="removeAbandoned">
<value>true</value>
</property>
<!-- 清除无用连接的等待时间 -->
<property name="removeAbandonedTimeout">
<value>180</value>
</property>
<!-- 连接属性 -->
<property name="connectionProperties">
<value>clientEncoding=UTF-8</value>
</property>
</bean>
<!-- mybatis文件配置,扫描所有mapper文件 -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="dataSource"
p:configLocation="classpath:conf/mybatis-config.xml"
p:mapperLocations="classpath:mapper/*.xml"/><!-- configLocation为mybatis属性 mapperLocations为所有mapper-->
<!-- spring与mybatis整合配置,扫描所有dao -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:basePackage="com.springmvc.ssm.dao"
p:sqlSessionFactoryBeanName="sqlSessionFactory"/>
<!-- 对数据源进行事务管理 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>
</beans>
2.5、如果以上都配置好了,还是不成功,那么就得在看看这些自动化的东西到底有没有自动化成功,例如service的自动扫描有没有起作用,Controller的自动扫描有没有起作用或者说是配置正确不正确。我的Controller的自动扫描是在spring.xml文件完成的。
2.6、如果说controller配置没有错误,那就看看是不是jar包的问题,记得在工程发布的路径下查看。
2.7、如果说还不成功,那就只能继续深入看源码了。还有一个方法就是启动的时候使用DEBUG模式,且在发布时去掉autoloading enabled,这样如果是源码问题就会卡出来,可以看到提示。不过相信走到这一步基本也就把错误排查出来了,一般不会去看源码提示,因为除非导包的问题,源码不会有错。
至此我将我的思路和错误排除的方法告诉大家,希望可以帮助到一些人。这篇文章是一个错误处理的排查思路分析及解决的文档,不是教大家怎么构建工程的文档,所以文件不是很全,但是配置文件都是没有问题的,只要更改目录和名称就可以只在项目中使用了。有什么问题希望留言大家共同探讨。我将其他的文件贴出来,以便大家可以直接复制去调试。
附件:
1、jdbc.properties
jdbc_driverClassName=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/SSYS_LOGISTICS?useUnicode=true&characterEncoding=utf-8
jdbc_username=root
jdbc_password=root
2、log4j.properties
### set log levels ###
#log4j.rootLogger = debug , stdout , D , E
log4j.rootLogger = debug , stdout , D
### output to the console ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
#log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n
log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
### Output to the log file ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = /home/workspace/logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### Save exception information to separate file ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = /home/workspace/logs/error.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
3、mybatis-cofig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 命名空间 -->
<typeAliases>
<!-- <typeAlias alias="User" type="com.springmvc.model.User"/> -->
<package name="com.springmvc.ssm.model"/>
<package name="com.springmvc.ssm.pojo"/>
</typeAliases>
<!-- 映射map -->
<mappers>
</mappers>
</configuration>
好了在这里说下我的错误吧,我是在复制web.xml配置文件的时候,没有将mybatis和spring的整合文件加载进来,所以大多数的错误都是人为的,而且是不起眼的小问题,可就是这些不起眼的小问题,总是折腾人。我们还是要认真排查每一行代码,认真对待每一件事。事无大小事,人无贵贱人!哈哈!
---------------------
作者:ITwelision
来源:CSDN
原文:https://blog.csdn.net/baidu_15275441/article/details/73930961
版权声明:本文为博主原创文章,转载请附上博文链接!