SpringMVC

本文是我的学习过程,但是我认为学习过程中并不适合写给别人看。所以本文只是一个临时的笔记,待以后进行深入整合。

SpringMVCSpring的关系是什么?
SpringMVC是依托Spring框架开发的一个Web MVC框架,天生与Spring集成,也就是使用了Spring的依赖注入和切面编程。

上一篇中讲解了Web.xml,这是Java Web的基础,也就是Servlet容器的工作方式,那个也作为本文的基础。

SpringMVC整体可以看成是一个Servlet,事实上它就是一个Servlet。我们配置web.xml来启动这个Servlet,然后这个Servlet来负责处理每个请求。每个处理请求的类都是我们遵照SpringMVC的格式来写的类,由SpringMVC这个框架来调用完成整个请求的处理。

与原本粗放的原生Java Web的开发模式相比,做了一个聚合。原本是每个请求你都写一个Servlet去处理,在web.xml中配置好一个请求与处理类的映射关系,由容器来完成调用。然后SpringMVC是分担了容器的压力,将容器的工作交给他来做,它利用Spring框架的依赖注入的特性,以及bean的工厂模式重新实现后端的实际处理流程。

有好处也有坏处,我也不太清楚这样做的具体目的是什么,可能会有性能上的提升,因为毕竟工厂模式等特性的加入会提升一些性能和开发便利。坏处感觉也挺明显,首当其冲就是学习栈又深了,还不是深了一个单位是好几个单位。加入了新的配置等,开发过程的脑力成本又增加了。

多说也没用,也是要以后逐步深入才能参透其中的奥妙。

maven 配置项目

命令行使用mvn构建项目很简单。

1
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp  -DarchetypeVersion=1.0   -DgroupId=com.demo  -DartifactId=demo   -Dversion=1.0

生成的目录如下:

1
2
3
4
5
6
7
8
9
.
├── pom.xml
└── src
└── main
├── resources
└── webapp
├── index.jsp
└── WEB-INF
└── web.xml

配置一下项目所需依赖关系pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>demo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>demo Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
<jdk.version>1.8</jdk.version>
<spring.version>4.3.9.RELEASE</spring.version>
<jstl.version>1.2</jstl.version>
<servletapi.version>3.1.0</servletapi.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>

<!-- compile only, deployed container will provide this -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servletapi.version}</version>
<scope>provided</scope>
</dependency>

</dependencies>

<build>
<finalName>demo</finalName>
<plugins>
<!-- Eclipse project -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<!-- Always download and attach dependencies source code -->
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
<!-- Avoid type mvn eclipse:eclipse -Dwtpversion=2.0 -->
<wtpversion>2.0</wtpversion>
</configuration>
</plugin>

<!-- Set JDK Compiler Level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>

<!-- For Maven Tomcat Plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat8-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/CounterWebApp</path>
</configuration>
</plugin>

</plugins>

</build>
</project>

web.xml 配置

下面就是要在这里配置启动SpringMVC,需要配置两个东西。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>learning springMVC</display-name>

<!-- 配置该监听器,使得其在容器启动时就去加载SpringMVC的配置文件 -->
<!-- 如果没有配置下面的这个contextConfigLocation参数,则默认加载同目录下的applicationContext.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-configuration/*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 配置SpringMVC的请求分发处理Servlet -->
<!-- 在项目启动的时候就启动该Servlet -->
<servlet>
<servlet-name>Dispatch</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Dispatch</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>


</web-app>

可以配置多个Dispatch来拦截不同格式的请求,不同的Dispatch要使用不同的配置文件,没错,又来一个配置。
这就是个前端请求拦截器,然后那过来到自己的配置文件里重新路由到要到达的Handler。所以每配置一个就要一个配置文件。默认的配置文件是/WEB-INF/<servlet-name>-servlet.xml

url-pattern:表示哪些请求交给Spring Web MVC处理, / 是用来定义默认servlet映射的。也可以如*.html表示拦截所有以html为扩展名的请求。

这样拦截请求会将静态文件的请求都拦截掉,所以我们在配置DispatchServlet之前加上一个配置, 这个配置是使用tomcat容器的默认Servlet来处理静态文件请求,让这个servlet先拦截请求就不会被SpringMVC拦截掉了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<servlet-mapping>  
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.swf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.gif</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.xml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.map</url-pattern>
</servlet-mapping>

还有一种方式就是将静态文件全部放在CDN结点服务器上,也可以分担服务器压力,速度还快,就是要花钱。

除了上面的这些基础配置,我们还会配置一些过滤器,比较典型的就是字符过滤,防止乱码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<filter>  
<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

还有一些错误页的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<welcome-file-list><!--指定欢迎页面-->  
<welcome-file>login.html</welcome-file>
</welcome-file-list>
<error-page> <!--当系统出现404错误,跳转到页面nopage.html-->
<error-code>404</error-code>
<location>/nopage.html</location>
</error-page>
<error-page> <!--当系统出现java.lang.NullPointerException,跳转到页面error.html-->
<exception-type>java.lang.NullPointerException</exception-type>
<location>/error.html</location>
</error-page>
<session-config><!--会话超时配置,单位分钟-->
<session-timeout>360</session-timeout>
</session-config>

applicationContext.xml

spring配置文件是用于指导Spring工厂进行Bean生产、依赖关系注入(装配)及Bean实例分发的”图纸”。Java EE程序员必须学会并灵活应用这份”图纸”准确地表达自己的”生产意图”。Spring配置文件是一个或多个标准的XML文档,applicationContext.xml是Spring的默认配置文件,当容器启动时找不到指定的配置文档时,将会尝试加载这个默认的配置文件。

这个是Spring 的全局配置文件,并不是SpringMVC的。

1
 
Talk is not cheap.