背景
之前所讲的程序,都是普通的Java Project,也就是说输出都是从控制台输出的,比较简单。
SpringMVC是web应用,所以需要部署到web服务器(本文采用Tomcat)上运行,项目结构与Java Project也不同。
所以本文会从头到尾详细的说明下使用SpringMVC开发web项目的过程。
注意本文依然使用导入jar包的形式进行操作,而不使用mavan,还是因为觉得会maven的应该都会导jar包,而会导jar包的不一定会maven,此处还是最大限度的照顾基础比较薄弱的小弟弟小妹妹们。
开发环境
本系列文章已经讲过开发环境了,此处再次提示下:
- 安装JDK,并配置环境变量
- 下载解压eclipse
- 下载解压tomcat
- 将JDK和tomcat配置到eclipse中
- 下载spring相应的jar包准备使用
具体步骤详见下面链接,此处不再赘述
Spring之路(2)–绕不过去的开发环境配置
创建web项目
打开Eclipse,然后点击菜单栏【File】-【New】-【Other】,选择Dynamic Web Project,即创建一个动态的web网站,如下图:
第二步直接默认,然后第三步按下图中操作:
点击Finish后已经为我们创建了一个web项目,项目名称为SpringMvcFirst
项目结构
如下图,我们需要关注的目录如下:
- src目录存放我们编写的java源代码
- WebContent目录存放web网站内容
- WEB-INF下的lib目录可以存放我们需要引用的jar包
- WEB-INF下的web.xml是整个项目的配置文件
我们先在src下建立org.maoge.first包存放代码,然后将spring相关的jar包放入lib目录下,准备就绪开始开发。
配置web.xml文件
作为一个web项目,它的配置是由web.xml定义的,所以我们先来配置下web.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>SpringMvcFirst</display-name>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
理解这个配置文件非常重要,所以我们逐一剖析里面的内容。
1、<?xml version="1.0" encoding="UTF-8"?>
这一行表示本文件是xml文件,没啥意思,xml配置文件都是这样开头的。
2、<web-app>
该标签表示这是一个web应用的配置文件,对web应用的配置都在这个标签内部。这个是自动生成的不用管。
3、<display-name>SpringMvcFirst</display-name>
此书是项目的显示名称,没啥大意思,可以删掉。
4、<servlet>
与<servlet-mapping>
注意这两个标签是成对存在的,可以看到servlet-name都是springmvc,所以这两个标签是一对。<servlet>
包含了对servlet的配置,而servlet-mapping
说明了指定名称的servlet接受请求的url匹配。上面的配置说明以.do
结尾的请求都交给名字是springmvc的servlet处理,注意*是通配符,表示所有。
5、<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
通过上面的配置,我们已经确定xxxxx.do这样的请求,都会交给名字为springmvc的servlet处理,然后该servlet具体的实现类是DispatcherServlet
,也就是说从此处开始我们将传统的servlet替换为了SpringMVC封装的DispatcherServlet
,所以相关请求会由DispatcherServlet
处理。
6、<load-on-startup>1</load-on-startup>
该标签的意思是已启动容器就加载该servlet,这个不用说,应用启动了就该马上加载servlet,不然谁来处理请求?
7、<init-param>
这个表示初始化参数,此处是理解整个web项目的关键我们要好好琢磨琢磨。
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-config.xml</param-value>
</init-param>
我们详细的看下这个配置,我们配置了一个名字叫contextConfigLocation
的参数,它的值为/WEB-INF/springmvc-config.xml
。
参数是啥意思呢,context之前我们多次遇到了,一般表示Spring容器,config表示配置,location表示位置,那么我们可以推测出该参数指定了spring容器所使用的配置文件的位置。
OK,从此处我们就可以知道了,web项目运行时首先会加载web.xml
,根据web.xml
对项目的配置启动整个web项目,然后发现了contextConfigLocation
,根据/WEB-INF/springmvc-config.xml
的配置对spring相关容器进行配置和加载。从而实现了web项目与spring的结合。
配置springmvc-config.xml文件
然后我们看下springmvc-config.xml
文件的配置内容,是不是非常简单,就是一个完全遵循Spring中xml配置规则普通配置文件啊。
稍微值得我们注意的是开启了对org.maoge.first
包的扫描,如果该包下有相应的bean配置,会被Spring容器发现并纳入容器管理。
<?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"
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-4.0.xsd">
<context:component-scan base-package="org.maoge.first" />
</beans>
编写具体控制器处理请求
现在已经配置了DispatcherServlet
接受用户请求,此时我们需要编写控制器具体处理用户的请求,代码如下:
package org.maoge.first;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class HelloController {
@RequestMapping("/hello")
public ModelAndView hello() {
ModelAndView mv=new ModelAndView();
mv.setViewName("hello.jsp");
return mv;
}
}
如果曾经写过SSM或者SpringBoot相关的项目,看到这段代码应会倍感亲切。此处我还是要详细介绍下这段代码。
@Controller
注解将HelloController类注册为容器管理的bean,不同于@Componet
注册的普通bean,@Controller
注册的bean具备处理器的功能,可以接受DispatcherServlet
传递过来的请求并进行处理返回,所以叫控制器么。
@RequestMapping("/hello")
表示该方法接受请求路径为/hello
的请求,也就是说一个请求经过DispatcherServlet
后,如果其请求url中匹配了/hello
,则该请求由hello()方法处理。
ModelAndView
是一个封装好的类,表示模型和视图,我们可以看到上述代码返回了一个含有视图名称为hello.jsp的mv对象,意思就是返回hello.jsp页面
编写视图页面
最后简单的编写一个hello.jsp下,放入WebContent目录下,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF8"
pageEncoding="UTF8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF8">
<title></title>
</head>
<body>
hello:springmvcfisrt
</body>
</html>
运行验证
将项目部署到tomcat并运行,打开浏览器输入路径http://127.0.0.1:8080/SpringMvcFirst/hello.do
,其中SpringMvcFirst是我们在新建项目时配置的项目context root,hello是控制器配置的访问路径,而.do是xml中配置的DispatcherServlet
匹配的请求路径。
注意此时报错
More than one fragment with the name [spring_web] was found. This is not legal with relative ordering.
在web.xml的<display-name>
后添加<absolute-ordering />
接近该问题。
再次运行,浏览器访问成功!