前言:今天会通过IDEA建立一个SpringMVC的demo项目,在其中会涉及到一些基础模块和相关知识,然后结合这个具体的知识点,理解清楚SpringMVC的框架原理(以图的形式展示),顺藤摸瓜分析源码

一、新建项目

通过File-New-Project,在下方页面勾选:Spring MVC + Web Application

点击Next填上:ProjectName和Project Location,之后会进入下载依赖包的过程:

完成之后,在窗口中打开的工程目录如下:其中lib中所放的是依赖的jar包,src中根据自己的需求添加package+class,其中IDEA已经自动帮助在WEB-INF中默认配置了applicationContext.xml、dispatcher-servlet.xml、web.xml

至此,基础工程也包含IDEA自动配置的都已经建好

二、确认配置文件内容

梳理清楚WEB-INF下的三个xml文件的作用和其中所配置内容的具体含义

直接通过官网介绍:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html 查看

具体介绍如下:

1、web.xml

作用:用来对DispatcherServlet进行注册和初始化(web.xml configuration registers and initializes the DispatcherServlet)

内容示例:

 <?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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.form</url-pattern>
</servlet-mapping>
</web-app>

重点关注的内容,如图中黄色底色的<context-param>的<param-value>部分,这个是WebApplicationContext的配置文件,如上所示就代表只配置了一个WebApplicationContext,一般情况下是足够的,也可以有Context的层次结构:其中一个根WebApplicationContext在多个DispatcherServlet(或其他servlet)实例之间共享,每个实例都有自己的子WebApplicationContext配置:(注:如下图为从官网截图内容)

2、applicationContext.xml

作用:这里的名字就是上面黄色底色标注出的xml文件的路径,这个WebApplicationContext具有指向ServletContext及其关联的Servlet的链接;

内容:

 <?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.xsd

        http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context.xsd

        http://www.springframework.org/schema/mvc

        http://www.springframework.org/schema/cache/spring-mvc.xsd">

     <context:component-scan base-package="cn.lx.controller" />

     <mvc:annotation-driven />

     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

         <property name="prefix" value="/WEB-INF/"/>

         <property name="suffix" value=".jsp"/>

     </bean>

 </beans>
备注:其中<context:component-scan base-package="cn.lx.controller" />
    <mvc:annotation-driven />以及下面的bean都是自己添加的
其中,context添加之后,上面的beans中的xmlns和xsi中都会添加上对应的项,mvc的也一样;但是IDEA在自动补齐mvc的内容时会出现cache字样,如下所示,导致出现bug,具体问题及bug解决方案在(三)中

3、dispatcher-servlet.xml:

作用:dispatcher-servlet.xml与applicationContext.xml是孩子与父亲的上下文的关系,在applicationContext.xml中可以定义全局的Spring的特性,dispatcher-servlet.xml就是在Context Hierarchy中定义的子WebapplicationContext.xml的内容,在其中具体定义属于当前Servlet的处理分发逻辑等

三、xml配置问题解决 && 模块功能实现

在applicationContext.xml中添加<mvc:annotation-driven>出现了问题,一共两个问题:

第一次是:输入<mvc:annotation-driven/>的时候,IDEA会自动生成xmlns:mvc=”http://www.spingframework.org/schema/cache”,下面的xsi:schemaLocation=的内容也会增加:http://www.spingframework.org/schema/cache   http://www.spingframework.org/schema/cache/spring-cache.xsd

在自动生成这样之后,运行的时候会出现错误提示:

21-Feb-2019 14:50:30.345 严重 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.ContextLoader.initWebApplicationContext Context initialization failed

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.interceptor.CacheInterceptor#0': Cannot resolve reference to bean 'cacheManager' while setting bean property 'cacheManager'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cacheManager' available

         at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)

         at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)

         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1537)

         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1284)

         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)

         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)

         at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)

         at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)

         at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)

         at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)

         at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)

         at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)

         at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)

         at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)

         at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)

         at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)

         at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4668)

         at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5136)

         at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

         at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:713)

         at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)

         at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)

         at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1729)

         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

         at java.lang.reflect.Method.invoke(Method.java:498)

[2019-02-21 02:50:30,383] Artifact demo:war exploded: Error during artifact deployment. See server log for details.

         at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:289)

         at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)

         at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)

         at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:457)

         at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:406)

         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

         at java.lang.reflect.Method.invoke(Method.java:498)

         at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:289)

         at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)

         at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)

         at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)

         at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)

         at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)

         at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)

         at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)

         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

         at java.lang.reflect.Method.invoke(Method.java:498)

         at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:324)

         at sun.rmi.transport.Transport$1.run(Transport.java:200)

         at sun.rmi.transport.Transport$1.run(Transport.java:197)

         at java.security.AccessController.doPrivileged(Native Method)

         at sun.rmi.transport.Transport.serviceCall(Transport.java:196)

         at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)

         at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)

         at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)

         at java.security.AccessController.doPrivileged(Native Method)

         at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)

         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

         at java.lang.Thread.run(Thread.java:745)

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cacheManager' available

         at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)

         at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1213)

         at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)

         at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)

         at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)

         ... 60 more

以上错误中的cacheManager,我并没有用到,但是很奇怪,为什么会抛出这个错误,搜索全局找跟cache相关的内容,发现在xml文件中出现了xmlns和schemaLocation中有cache的内容出现,基于此继续追查(后面会补一篇xml解析和schema的内容),发现可能是这里配置的问题,而且因为实际上还没有走到具体逻辑中,是在启动过程中就已经抛出错误,出现cache的xmlns的内容如下:xmlns:mvc=http://www.springframework.org/schema/cache

然后找到这个mvc是在下面定义的:<mvc:annotation-driven />相匹配,重新输入内容自动联想发现:红色框线内基本都是annotation-driven,只是来源不同,默认点击enter会自动选择cache的路径,导致出现这个错误

接下来,对这个异常进行初步分析的过程(这里不包含CacheManager运行原理和源码解析,后面会有一篇文章进行介绍),查官网资料,https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/integration.html#cache-plug

8.5章节中有如下内容描述:

The cache abstraction provides several storage integration options. To use them, you need to declare an appropriate CacheManager (an entity that controls and manages Cache instances and that can be used to retrieve these for storage).

之后官网详细的基于不同方式的cache需要配置的xml内容做了demo样例,也查询了一些其他文档,本地添加bean的声明之后,异常消失:

至此,这个基于自动补齐的<annotation-driven>的问题解决,但实际上,我需要的是:mvc的namespace和对应的xsd,修改程序将:namespace和schemaLocations中的cache都改成mvc:

在applicationContext.xml中继续添加bean配置:

<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
在src下建包名/类,testController.java的实现,如下:
@Controller

public class TestController {

    @RequestMapping("/test.form")

    public void execute(){

        return ;

    }

}

test.jsp的内容如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>

<head>

    <title>test</title>

</head>

<body>

    Hello Spring MVC Test

</body>

</html>

四、运行
点击run之后会提示进行Edit Configurations,进入页面,将相应内容填入(需要启动TomcatServer并设置路径)

设置Demployment:

之后点击run按钮,运行提示ClassNotFound:

严重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [org.springframework.web.context.ContextLoaderListener]

 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1363)

at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1186)

at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:540)

at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:521)

at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:150)

at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4590)

但工程的lib目录下的jar都引入了,那就是Tomcat运行的时候加载不到这个jar包的原因,通过File-Project Structure打开进入到工程设置页面,如下图所示,将右侧点击之后选择Put into output Root,

之后查看左侧output root的按钮,可以看到:WEB-INF下有SpringMVC的jar包:

以上问题都解决以后,就能够运行成功整个项目了~
备注:在运行过程中,下方窗口中出现运行日志会有中文乱码的情况:可以参考该篇文章:https://blog.csdn.net/qq_41264674/article/details/80945140

【Spring学习】SpringMVC demo搭建的更多相关文章

  1. Spring+Druid+SpringMVC的搭建(附Demo)

    最近公司事情比较少,便想利用这段空闲时间做一个自己的博客. 前端界面已经搞好,感谢杨姐的模板,自己稍微把模板没有的模块给补全了. 今天便开始自己的SSM框架搭建,数据库链接是采用数据库连接池.先上个项 ...

  2. Java 系列之spring学习--springmvc搭建(四)

    一.建立java web 项目 二.添加jar包 spring jar包下载地址http://repo.spring.io/release/org/springframework/spring/ 2. ...

  3. spring+hibernate项目demo搭建

    之前用maven+spring+mybatis+spring mvc搭建了一个web项目,用于学习spring及相关知识,现在打算将mybatis换成hibernate,一样搭建一个框架. 其实myb ...

  4. springMVC demo搭建

    1.使用idea新建一个基于maven的web项目,参考 http://www.cnblogs.com/winkey4986/p/5279820.html 2.采取了比较偷懒的配置方法,只配置了一个D ...

  5. Spring学习笔记--环境搭建和初步理解IOC

    Spring框架是一个轻量级的框架,不依赖容器就能够运行,像重量级的框架EJB框架就必须运行在JBoss等支持EJB的容器中,核心思想是IOC,AOP,Spring能够协同Struts,hiberna ...

  6. Hibernate4+Spring JPA+SpringMVC+Volecity搭建web应用(二)

    SpringMVC.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&qu ...

  7. Hibernate4+Spring JPA+SpringMVC+Volecity搭建web应用(一)

    pom.xml配置 <dependencies> <!-- hibernate begin --> <dependency> <groupId>org. ...

  8. Java 系列之spring学习--springmvc注解方式(五)

    一.springmvc注解方式 注解方式使用的更多,更加灵活.在上一篇的博客的基础上修改springmvc-servlet.xml配置文件. <?xml version="1.0&qu ...

  9. 联系 管理 Hibernate4+Spring JPA+SpringMVC+Volecity搭建web应用(三)

    hibernate注解实体类示例 package cn.bdqn.smvc.entity; import java.io.Serializable; import javax.persistence. ...

随机推荐

  1. AES和RSA的加密过程通过面向对象的方式写成一个类,封装起来

    # 面向对象的方式 实现加密方法 from Crypto.Cipher import AES from Crypto import Random from binascii import b2a_he ...

  2. java 读取外部和source下配置文件

    import java.io.File; import java.io.FileInputStream; import java.net.URL; import java.util.Map; impo ...

  3. realm清空所有数据库的数据

    /* *清空数据库 */ public int clearDatabase() { Realm realm = Realm.getDefaultInstance(); try { realm.begi ...

  4. 棒槌的工作第八天-----------------------早会-------三次握手四次挥手(转载https://www.cnblogs.com/zmlctt/p/3690998.html)尚待了解,下班补充

    TCP三次握手 所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包. 三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方 ...

  5. js打印页面指定区域,并去掉页眉上的时间和请求路径

    需要通过js打印指定页面的内容 <style media=print type="text/css"> .noprint{visibility:hidden} < ...

  6. 使用K-means进行聚类,用calinski_harabaz_score评价聚类效果

    代码如下: """ 下面的方法是用kmeans方法进行聚类,用calinski_harabaz_score方法评价聚类效果的好坏 大概是类间距除以类内距,因此这个值越大越 ...

  7. Thinkphp整合阿里云OSS图片上传实例

    Thinkphp3.2整合阿里云OSS图片上传实例,图片上传至OSS可减少服务器压力,节省宽带,安全又稳定,阿里云OSS对于做负载均衡非常方便,不用传到各个服务器了 首先引入阿里云OSS类库 < ...

  8. leetcode每日刷题计划-简单篇day11

    Num 121 买卖股票的最佳时期 Best Time to Buy and Sell Stock class Solution { public: int maxProfit(vector<i ...

  9. 稀疏矩阵 part 2

    ▶ 各种稀疏矩阵数据结构之间的转化 ● MAT ←→ CSR CSR * MATToCSR(const MAT *in) // MAT 转 CSR { checkNULL(in); CSR * out ...

  10. Python爬虫与数据分析之模块:内置模块、开源模块、自定义模块

    专栏目录: Python爬虫与数据分析之python教学视频.python源码分享,python Python爬虫与数据分析之基础教程:Python的语法.字典.元组.列表 Python爬虫与数据分析 ...