【JavaWeb学习笔记之Spring MVC快速入门】

目录:
1. WebMVC介绍
2. Spring MVC体系结构
3. DispatcherServlet类
4. 一个简单的Spring MVC实例(使用IDEA实现)

1. WebMVC介绍
MVC是一种使用MVC(Model View Controller 模型-视图-控制器)设计创建Web应用程序的模式:

  • Model(模型) 应用程序核心(比如数据库记录列表)
  • View(视图)显示数据
  • Controller(控制器)处理输入

MVC模式流程描述
常用的MVC框架有Struts和SpringMVC。
Struts是MVC框架中不争的王者,但是其在某些技术特性上落后新兴的MVC框架。
Spring MVC框架是一个MVC框架,通过实现Model-View-Controller模式来很好地将数据、业务与展现进行分离。

MVC模式的优缺点:
优点:

  • 耦合性低
  • 重用性高
  • 生命周期成本低
  • 部署快
  • 可维护性高
  • 有利于软件工程化管理

缺点:

  • 没有明确的定义
  • 不适合小型,中等规模的应用程序
  • 增加系统结构和实现的复杂性
  • 视图与控制器间的过于紧密的连接
  • 视图对模型数据的低效率访问

Spring MVC框架
Spring MVC,基于MVC设计理念,此外,还采用了送上耦合可插拔组件结构,比其他MVC框架更具扩展性和灵活性。

Spring MVC在数据绑定、视图解析、本地化处理及静态资源处理上都有不俗的表现。

Spring3.0版本中,定义控制器类,必须以@Controller注解进行标注。当控制器接收到一个请求时,它会在自己内部寻找一个合适的方法来处理请求。使用@RequestMapping注解,可以将方法映射都某个特定请求上,用于对该请求的处理。

Spring MVC处理流程
Spring MVC的设计是围绕DispatcherServlet展开的,DispatcherServlet负责将请求派发到特定的handler。通过可配置的handler mappings、view resolution完成Web请求,并且转到对应的视图。

Spring MVC请求处理的整体流程如图。

2.Spring MVC体系结构
SpringMVC是基于Model2实现的技术框架。
在这里插入图片描述
Spring MVC框架整个处理响应的步骤如下:

第一步:客户端发送HTTP请求;
第二步:DispatcherServlet接受请求后,将请求委托给具体的处理器Handler,后者将处理请求并执行响相应的业务逻辑;DispatcherServlet根据请求信息(URL或请求参数等)找到请求对应的Handler,通过查找HandlerMapping完成这一工作;
第三步:Dispatcher找到请求对应的Handler后,将请求分配给这个处理器,执行相应的业务逻辑;
第四步:Handler处理完业务逻辑后,将返回ModelAndView对象,给DispatcheServlet,ModelAndView中包含了视图逻辑名和渲染视图时需要用到的模型数据对象;
第五步:进行视图解析,调用Viewresolver,知道视图逻辑名对应的真实视图对象;
第六步:得到真实的视图对象后,DispatcherServlet将请求分配给这个对象,由其完成VModel数据的渲染工作;
第七步:最终客户端得到返回的响应,可能是HTML,Excel,PDF等形式。

3. DispatcherServlet类

  • 配置DispatcherServlet

DispatcherServlet的父类继承了HTTPServlet类,所以DispatcherServlet核心本质是一个Servlet
要使用Spring MVC,必须在web.xml中配置DispatcherServlet类:

下面是web.xml的具体配置:

<!-- 加载spring上下文 -->  
<!-- 1 配置Spring,指定applicationContext.xml为业务层和持久层的Spring配置文件,这些配置文件被父Spring容器使用 -->
<context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value classpath:applicationContext.xml</param-value>  
</context-param>  
 <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener> 

<!-- 2 声明DispatcherServlet -->
    <servlet>
    	<servlet-name>myDispatcherServlet</servlet-name>
    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	<init-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>/WEB-INF/spring-servlet.xml</param-value> <!-- SpringMVC配置文件 -->
    	</init-param>
    	<load-on-startup>1</load-on-startup>       <!—Web应用启动时优先加载 -->
    </servlet>
    <servlet-mapping>
    	<servlet-name>myDispatcherServlet</servlet-name>
    	<url-pattern>/</url-pattern>            	<!-- 3 请求后缀 -->
    </servlet-mapping>
  • DispatcherServlet类的继承体系:
    – DispatcherServlet类的运行体系:
    — DispatcherServlet的核心本质:是一个Servlet
    — init方法在整个系统启动时运行,且只运行一次,在init方法中,对整个应用程序进行初始化操作;
    — service()方法在系统运行的过程中处于侦听模式,侦听并处理所有的Web请求;
    对于Spring MVC而言,用于对不同的逻辑职责进行划分,形成两条互不相关的逻辑运行主线:初始化主线,负责对Spring MVC的运行要素进行初始化;HTTP请求处理主线,负责对Spring MVC中的组件进行逻辑调度,完成HTTP请求的处理。
    Spring MVC运行主线的划分,依据Servlet对象中不同方法的生命周期进行划分,几乎所有MVC框架都是根据这一原理进行划分。

– DispatcherServlet类的继承体系:
— 依次继承FrameworkServlet和HTTPServletBean
— HTTPServletBean是Spring对于Servlet最底层的抽象
— FrameworkServlet则是在HTTPServletBean的基础上的进一步抽象,通过FrameworkServlet真正初始化了一个Spring的容器(WebApplicationContext)并引入到Servlet对象中
— DispatcherServlet通过initStrategies方法查找并装配Spring容器中用户定义的组件Bean

4. 一个简单的Spring MVC实例

如下图所示,实现一个简单的登录系统:

开发环境如下:IntelliJ IDEA,Tomcat8.5,Maven,JDK1.8。
在创建项目前,确保maven,jdk都已安装好。
1 打开IDEA,new一个project,选择Maven,勾选Create from archetype,选中maven-archetype-webapp,next,输入GroupId为com.feng,ArtifactId为springmvc_simpleLogin,next,选中项目地址,Finish,然后开始自动下载Maven相关文件,加载完成后,就创建了一个Maven管理的Web项目。

2 然后添加Tomcat服务器,选中工具栏小锤子右边的Add Configuration,点击+好,选中Tomcat Server,选中local,输入一个名字,在Deployment下选中+,选择Artifact,选择下方的exploded结尾的选项,点击ok,完成Tomcat的配置。

然后点击绿色小三角,出现HelloWorld页面,项目便运行起来了。

3 添加Spring MVC的相关Jar包 spring-webmvc spring-tx,通过pom.xml添加相关的dependencies。
打开MavenRepository,搜索Spring webmvc和Spring transaction,选择5.1.5版本的把依赖拷贝到pom.xml中

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>

      <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.1.5.RELEASE</version>
      </dependency>

下面是配置好的pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.feng</groupId>
      <artifactId>springmvc_simpleLogin</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <name>springmvc_simpleLogin Maven Webapp</name>
      <!-- FIXME change it to the project's website -->
      <url>http://www.example.com</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
    
        <!-- Spring webmvc  -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>

        <!-- Spring Transaction -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
    
      </dependencies>
    
      <build>
        <finalName>springmvc_simpleLogin</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
          <plugins>
            <plugin>
              <artifactId>maven-clean-plugin</artifactId>
              <version>3.1.0</version>
            </plugin>
            <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
            <plugin>
              <artifactId>maven-resources-plugin</artifactId>
              <version>3.0.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.8.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-surefire-plugin</artifactId>
              <version>2.22.1</version>
            </plugin>
            <plugin>
              <artifactId>maven-war-plugin</artifactId>
              <version>3.2.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-install-plugin</artifactId>
              <version>2.5.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-deploy-plugin</artifactId>
              <version>2.8.2</version>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>

4 配置web.xml,在其中配置好Spring上下文,DispatcherServlet,如下所示:

        <!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>Archetype Created Web Application</display-name>
    
        <context-param>  <!-- 这一段没加报错了 所以后来又加上了,运行之后报错找不到这个xml,然后在WEB-INF目录下创建applicationContext.xml,点击Configurate Spring Context 即可 -->
            <param-name>ContextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
    
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <!-- spring mvc的前端控制器 -->
        <servlet>
            <servlet-name>spring</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/spring-mvc.xml</param-value>  <!-- Spring MVC配置文件 -->
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>spring</servlet-name>
            <url-pattern>*.html</url-pattern>        <!-- 处理的请求为html -->
        </servlet-mapping>
    </web-app>

5 编写spring-mvc.xml文件,在WEB-INF目录下,new一个XMLConfiguration File 选择Spring config,新建一个spring-mvc.xml,添加自动扫描包,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns="http://www.springframework.org/schema/beans"
           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">
    
        <!-- 自动扫描包,使SpringMVC认为该包下面具有@Controller注解的类的控制器 -->
        <context:component-scan base-package="com.feng"/>
    </beans>

右键项目名,选择 Open Module Settings,选择Spring,界面如下:

配置工作到现在就完成了,下面开始编写代码。

6 编写显示层代码。编写login.jsp和success.jsp两个jsp页面,在web目录下新建jsp目录,创建login.jsp用于登录,在其中添加一个form表单,点击登录提交用户名和密码,代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>登录页面</title>
</head>
<body>
    <form action="login.html" method="post">
        <p>
            用户名:<input name="username" type="text">
        </p>
        <p>&nbsp;&nbsp;码:<input name="password" type="password">
        </p>
        <p>
            <input type="submit" value="登录">
        </p>
    </form>

    <font color="red">${error }</font>
</body>
</html>

同理,创建一个success.jsp,作为登录成功后的页面,代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>
您已登录!
</body>
</html>

7 编写业务层和模型层代码,创建Controller和Service。
在main下新建一个java目录,右键 选择 Make Directory as Sources Root。
接下来在java目录下new一个Java Class,package为com.feng.demo.springmvc.controller,类名LoginController,用作Controller;同理创建LoginService,package为com.feng.demo.springmvc.service,用作Service。
编写LoginController,在class上方添加Controller注解,创建两个方法,用于显示登录页面和处理登录,并添加RequestMapping注解,代码如下:

/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: LoginController
 * Author:   cfl
 * Date:     2019/8/9 22:32
 * Description: 控制器实现
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.feng.demo.springmvc.controller;

import com.feng.demo.springmvc.service.LoginService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 〈一句话功能简述〉<br> 
 * 〈控制器实现〉
 *
 * @author cfl
 * @create 2019/8/9
 * @since 1.0.0
 */
@Controller
public class LoginController {
    @Resource
    LoginService loginService;

    @Resource
    HttpServletRequest request;


    @RequestMapping("index")
    public ModelAndView toLoginPage(){
        return new ModelAndView("WEB-INF/jsp/login.jsp");
    }

    @RequestMapping("login")
    public ModelAndView doLogin(){
        String loginPageUrl = "/WEB-INF/jsp/login.jsp";
        String successUrl = "/WEB-INF/jsp/success.jsp";

        String name = request.getParameter("username");
        String password = request.getParameter("password");
		
		//具体处理交由LoginService
        return loginService.doLogin(loginPageUrl, successUrl, name, password);
    }
}

编写Service,在LoginService的class上方添加Service注解,并编写doLogin方法,处理登录的业务逻辑,如果用户名为admin,密码为123456,则登录成功。代码如下:

/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: LoginService
 * Author:   cfl
 * Date:     2019/8/9 22:33
 * Description: Service实现
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.feng.demo.springmvc.service;

/**
 * 〈一句话功能简述〉<br> 
 * 〈Service实现〉
 *
 * @author cfl
 * @create 2019/8/9
 * @since 1.0.0
 */

import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

@Service
public class LoginService {

    public ModelAndView doLogin(String loginPageUrl, String successUrl, String name, String password) {
        if (name == null ||"".equals(name)){
            return new ModelAndView(loginPageUrl, "error", "用户名不能为空");
        }

        if(password == null || "".equals(password)){
            return new ModelAndView(loginPageUrl, "error", "密码不能为空");
        }

//        假设用户名为admin,密码为123456
        if (name.equals("admin") && password.equals("123456")){
            return new ModelAndView(successUrl);
        }
        return new ModelAndView(loginPageUrl, "error", "用户名或密码错误");
    }
}

最终得到的工程目录如下:

现在可以运行项目了,在地址栏输入index.html


在这里插入图片描述
项目成功运行。


写在最后:编写完代码运行项目时遇到了两个问题:

  1. connot resolve symbol ‘HttpServletRequest’
    百度之后说是需要添加servlet-api.jar。 参考
  2. EL表达式直接显示${error }
    在jsp页面最前面的<@page>里面加上了isELIgnored=“false”,成功解决。参考

注:第四部分Spring MVC实现参考了使用IntelliJ IDEA开发SpringMVC网站


版权声明:本文为dunlongzun8445原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。