Spring MVC项目创建

什么是Spring MVC

Spring MVC是Spring内置的,实现了Web MVC设计模式的框架。

它解决了Web开发过程中很多的问题,例如参数接收、表单验证等。另外它采用松散耦合可插拔组件等结构,具有相对较高的灵活性和扩展性。

Spring MVC官方文档可参考 docs.spring.io

Spring MVC执行流程

按顺序可分为如下流程

  • 用户请求被DispatcherServlet进行拦截处理
  • DispatcherServlet收到请求调用HandlerMapping
  • HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器,再一起返回给DispatcherServlet
  • DispatcherServlet调用HandlerAdapter
  • HandlerAdapter经过适配调用具体的处理器
  • Controller执行完成返回ModelAndView对象
  • HandlerAdapterModelAndView返回给DispatcherServlet
  • DispatcherServletModelAndView传给ViewReslover
  • ViewReslover解析ModelAndView后返回View(给DispatcherServlet
  • DispatcherServlet根据View进行渲染
  • DispatcherServlet响应View给用户

通过上面流程可知,程序员需要配置DispatcherServlet,并开发ViewController/Handler

项目创建

即然如此,我们就来创建一个Spring MVC项目。

打开Eclipse,创建一个Maven项目(想必经过前面学习已经很熟了),项目名称top.cairbin.test7

但是需要注意,创建时请勾选下图的Add project(s) to working set

Select an Archetype这一步需要注意,我们不再用之前的maven-archetype-quickstart,而是maven-archetype-webapp,如下图所示

创建完成后项目目录结构大概如下

我们还需要引入Spring MVC的依赖包以及Servlet,这你很清楚应该在pom.xml里配置

<!-- 添加servlet依赖 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <scope>provided</scope>
    <version>3.1.0</version>
</dependency>
    
<!-- 添加spring依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.23</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.23</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.23</version>
</dependency>

最终效果看起来是这样

<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>top.cairbin</groupId>
  <artifactId>test7</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>test7 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    
    <!-- 添加servlet依赖 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <scope>provided</scope>
        <version>3.1.0</version>
    </dependency>
    
    <!-- 添加spring依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.23</version>
    </dependency>
    
  </dependencies>
  <build>
    <finalName>test7</finalName>
  </build>
</project>

相比于以往的项目,你会发现webapp已经为我们创建了一个resources资源文件夹,并且src/main下多了一个webapp目录。webapp它一般存放前端相关的文件。

webapp目录下有一个WEB-INF,里面有一个默认生成的web.xml配置文件。还记得我们刚才提到的Spring MVC执行流程吗,用户请求会被DispatcherServlet拦截,它叫前端控制器,而这个XML文件就是用来对它进行设置的。

我们对web.xml进行修改

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns="http://java.sun.com/xml/ns/javaee"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <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:springCtx.xml</param-value>
        </init-param>
        <!-- 表示容器在启动时立即加载Servlet -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern> 
    </servlet-mapping>
</web-app>

注意<param-value>classpath:springCtx.xml</param-value>这一段引入了一个文件,是用来配置Controller映射信息的。

我们再来看看,webapp下还有一个index.jsp文件,它正是你的前端代码文件,它的内容如下

<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

你可能对此表示疑惑,这不就是一个HTML文件,现实一个标题,标题内容为Hello World!吗。没错,但是对于传统的HTML来讲页面是静态的,而我们的JSP文件则能动态获取后端一些内容。

有了View来实现USL前台还不够,我们还要实现USL后台,接下来我们在src/main/java下创建包top.cairbin.test7.controller,并在这个包下创建控制器类TestController

package top.cairbin.test7.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;


public class TestController implements Controller{
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)  {
         // 创建ModelAndView对象
        ModelAndView mav = new ModelAndView();
         // 向模型对象中添加数据
        mav.addObject("message", "Hello Spring");
         // 设置逻辑视图名
        mav.setViewName("/WEB-INF/views/hello.jsp");
         // 返回ModelAndView对象
        return mav;
    }
}

还记得刚才说的<param-value>classpath:springCtx.xml</param-value>吗,我们创建了控制器,还要告诉Spring MVC控制器与View的映射关系。

springCtx.xml这个文件并不存在我们项目中,需要手动添加。在resources资源文件夹里创建它。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    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.xsd">
    <!-- 配置处理器Handle,映射“/hello”请求 -->
    <bean name="/hello" 
            class="top.cairbin.test7.controller.TestController" />
    <!-- 处理器映射器,将处理器Handle的name作为url进行查找 -->
    <bean class=
    "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!-- 处理器适配器,配置对处理器中handleRequest()方法的调用-->
    <bean class=
    "org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
    <!-- 视图解析器 -->
    <bean class=
    "org.springframework.web.servlet.view.InternalResourceViewResolver">
    </bean>
</beans> 

请务必注意<bean name="/hello" class="top.cairbin.test7.controller.TestController" />这一段的包名与你控制器一致。它告诉Spring MVC,将这个控制器映射到/hello路径上去,一会你就能在浏览器通过http://ip:port/项目名/hello的形式去访问它。

WEB-INF里创建views文件夹,请注意是WEB-INF下创建。

并在这个viewsview文件夹里新建jsp文件hello.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
<%@page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
     "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello SpringMvc</title>
</head>
<body>
     <h1>${message}</h1>
</body>
</html> 

我们在这里使用${...}的形式来使用后端提供的接口,以此获取后端返回的对象。

那么问题来了,我们这个项目该怎么运行呢?显然对于Web项目我们需要Http服务器。

还记得我们在配置环境的时候安装的Tomcat9吗,现在终于要到了使用它的时候了!

另外,我们注意之前编写的TestController这个控制器,它需要导入的包中可能有两个报错。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

如果出现这种情况,我们右键这个项目,打开属性

找到Java Build Path选项的Libraries选项卡,点击Add Library...

选择Server Runtime选项,然后下一步

选择之前配置好的服务器(就是在环境配置那篇文章里的)

保存并退出。

接下来我们尝试运行它,与以往不同的是,我们需要Run As里面的Run on server

如果你第一次这样做,会弹出个窗口

选择Apache里对应的服务器,我这里是Tomcat9.0

然后点击完成。很显然,你的浏览器已经打开了,说明你的项目跑成功了。并且在Eclipse的Package Explorer中多了个Servers文件夹。

我们在浏览器访问的是index.jsp所渲染的页面

在地址栏输入http://localhost:8080/test7/hello访问控制器和hello.jsp所渲染的页面

问题

在这一节其实有很多坑,一是Tomcat版本在10.0以上的话,包名变化问题。

另外如果当初配置环境的时候,Eclipse没选Web选项,这里有些配置是没有的。

上面这些问题请参考环境配置和此教程的问题模块。

如果你项目菜单里的Run as没有Run on server选项的话需要如下操作

打开项目属性

搜索project facets,勾选Dynamic Web Module选项

保存并退出。

接下来如果操作不当的话可能导致Servers文件夹下配置文件里有多个context,这时候需要打开server.xml进行就该

找到如下片段<Context>标签,把重复的删除

最后修改:2024 年 04 月 01 日
如果觉得我的文章对你有用,请随意赞赏