SpringMVC 01: SpringMVC + 第一个SpringMVC项目
SpringMVC
SpringMVC概述:
是基于MVC开发模式的框架,用来优化控制器
是Spring家族的一员,也具备IOC和AOP
什么是MVC:
它是一种开发模式,是模型视图控制器的简称,所有的web应用都应当基于MVC模式开发
M:模型层,包含实体类,业务逻辑层,数据访问层
V:视图层,html,javaScript,vue等都是视图层,用来显示数据
C:控制器,它是用来接收客户端的请求,并返回响应到客户端的组件,Servlet就是这样的组件
SpringMVC框架的优点
- 优点:
- 轻量级,基于MVC开发模式的框架
- 易于上手,容易理解,功能强大
- 具备IOC和AOP
- 完全基于注解开发
SpringMVC的执行流程
- 理解SpringMVC执行流程的一个方法:一个好汉,三个帮
- DispatcherServlet:是SpringMVC的核心处理器,也就是所谓的好汉
- HandlerMapping + HandlerAdapter + ViewResolver:三个负责完成SpringMVC主要功能的处理器,是核心处理器的三个帮手
- DispatcherServlet接受用户请求,调用HandlerMapping,HandlerAdapter,ViewResolver三个小帮手来完成任务,最后再由DispatcherServlet将返回的数据响应到视图,反馈给用户
SSM框架的组成
组成:
SSM:Spring + SpringMVC + MyBatis
仨框架的分工:
MyBatis:增强数据访问层
SpringMVC:增强控制器
Spring:整合MyBatis和SpringMVC框架,使得框架更加易用
了解SSH:
Spring + Struts2 + Hibernate:Struts2后来被SpringMVC取代,Hibernate后来被MyBatis取代
SSM框架下的web请求流程
- SpringMVC负责蓝色矩形框中的业务处理:优化数据提交和数据返回
- MyBatis负责红色矩形框中的业务处理:优化数据库相关操作
基于注解的SpringMVC框架开发的步骤
- 第一个简单SpringMVC项目的预期结构
- 新建maven项目,选择webapp模板
- 修改目录结构,添加缺失的目录,修改目录属性
- 修改pom.xml文件,添加SpringMVC依赖,添加Servlet的依赖
<?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.example</groupId>
<artifactId>ch01-springmvc-demo</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<!-- junit测试依赖 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- 添加spring-webmvc的依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- 添加javax-servlet依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<!-- 添加资源文件指定 -->
<resources>
<!-- 资源文件指定1 -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<!-- 资源文件指定2 -->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
</project>
- 在src/main/resources/下添加springmvc.xml配置文件(SpringMVC的核心配置文件),指定包扫描,添加视图解析器
- 包扫描:用于交给Spring容器来创建控制层对象
- 视图解析器:根据控制器中的action方法返回的字符串,依据配置前缀和配置后缀拼接出需要跳转的页面路径,本例为:/admin/main.jsp,添加完视图解析器之后,只要返回"main"字符串即可,简化了页面跳转和数据返回操作
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 添加包扫描 -->
<context:component-scan base-package="com.example.controller"/>
<!-- 添加视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀-->
<property name="prefix" value="/admin/"/>
<!-- 配置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- 删除web.xml文件(模板生成的web.xml文件的版本较低,不用),并新建web1.xml文件,将web1.xml改名为web.xml(又直接新建web.xml的话,生成的还是旧文件,不支持EL表达式,必须这么折腾一下)
- 在项目结构管理中删除和新建web.xml文件
- 在web.xml文件中注册springMVC框架(因为web请求都是基于servlet的,而SpringMVC控制器是普通的类和方法,必须注册一个DispatcherServlet来完成请求的接收和响应,同时将web项目交给SpringMVC框架来管理)
<?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_4_0.xsd"
version="4.0">
<!-- 注册SpringMVC框架 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<!-- 注册底层使用的servlet -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 要让SpringMVC的核心处理器知道SpringMVC的核心配置文件,相当于把web项目交给SpringMVC接管-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 拦截处理所有以action为后缀名的请求 -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
- 在webapp目录下新建admin目录,在admin目录下新建main.jsp页面,删除index.jsp并新建index.jsp(旧的index.jsp内容太少),向服务器发送请求
<!-- index.jsp -->
<%--
Created by IntelliJ IDEA.
User: wangxun
Date: 2022/8/30
Time: 下午8:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index.jsp</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/demo.action">访问服务器</a>
</body>
</html>
- 开发控制器(只是一个普通的类)
package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 业务管理器:包含很多完成具体需求的方法
*/
@Controller
public class DemoAction {
/**
* DemoAction中的所有功能实现都是由方法来完成的
* 这些方法的规范
* 1.访问权限:public
* 2.方法的返回值:任意
* 3.方法名称:任意
* 4.方法参数:可以没有,如果有可以是任意类型
* 5.注解:需要使用@RequestMapping注解来声明一个访问路径(名称),这里不用再写:demo.action项目请求路径后面的后缀
* 因为该后缀是给web.xml中注册的DispatcherServlet看的,起到拦截请求的作用,符合拦截要求的请求才交给底层servlet处理
*/
@RequestMapping("/demo")
public String demo(){
System.out.println("服务器被访问......");
return "main";
}
}
- 添加tomcat进行功能测试
- 启动tomcat
- 网站首页(left)以及请求结果(right)
- 控制台输出
web请求分析
关于为什么要在web.xml文件中注册DispatcherServlet:
由于SpringMVC的控制器是一个普通的方法,而web请求都是基于servlet的,所以必须在web.xml文件中注册SpringMVC框架
将注册的DispatcherServlet作为SpringMVC的核心处理器,成为前端请求和SpringMVC控制器的沟通桥梁,完成前端请求和SpringMVC控制器的交互
而又由于我们无法直接通过类似@WebServlet这样的注解获得DispatcherServlet,所以要使用其所在的jar包注册DispatcherServlet
上述案例中web请求的流程究竟是怎样的:
将前端请求的路径和web.xml中注册的可以给予处理的请求路径比对,如果请求路径满足请求的通配条件(先具有被处理的资格),请求被底层DispatcherServlet拦截处理。
由于注册了SpringMVC框架,此时容器已经注册生成了许多通过注解生成的SpringMVC的控制器对象
根据请求的具体路径(根据需求,给予处理),将web请求交给SpringMVC的不同控制器中的不同action方法来解决
最终,SpringMVC的控制器将处理结果返回给DispatcherServlet,后者将结果返回给前端
注册SpringMVC的核心处理器:DispatcherServlet
index.jsp <--------> DispatcherServlet <--------> SpringMVC的控制器是一个普通方法
one.jsp <--------> DispatcherServlet <--------> SpringMVC的控制器是一个普通方法
@RequestMapping注解
- 该注解可以用在方法上,为此方法注册一个可以访问的名称(路径)
- 此注解可以加在类上,相当于包名(虚拟路径),用于区别不同控制器中相同的action方法名称
- 添加在类上做注解的演示:
- 修改index.jsp,变成两个不同请求路径下的请求,但这两个请求的结尾都是demo.action
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index.jsp</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/test01/demo.action">访问服务器test01</a><br>
<a href="${pageContext.request.contextPath}/test02/demo.action">访问服务器test02</a>
</body>
</html>
- 在admin目录下新增main2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>main2.jsp</title>
</head>
<body>
<h2>main2......page.......</h2>
</body>
</html>
- 修改原有DemoAction,新增类上注解:@RequestMapping("/test01")
package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 业务管理器:包含很多完成具体需求的方法
*/
@Controller
@RequestMapping("/test01")
public class DemoAction {
/**
* DemoAction中的所有功能实现都是由方法来完成的
* 这些方法的规范
* 1.访问权限:public
* 2.方法的返回值:任意
* 3.方法名称:任意
* 4.方法参数:可以没有,如果有可以是任意类型
* 5.注解:需要使用@RequestMapping注解来声明一个访问路径(名称),这里不用再写:demo.action项目请求路径后面的后缀
* 因为该后缀是给web.xml中注册的DispatcherServlet看的,起到拦截请求的作用,符合拦截要求的请求才交给底层servlet处理
*/
@RequestMapping("/demo")
public String demo(){
System.out.println("服务器test01被访问......");
return "main";
}
}
- 新增SpringMVC控制器:DemoAction2,同样包含类上注解
package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 业务管理器:包含很多完成具体需求的方法
*/
@Controller
@RequestMapping("/test02")
public class DemoAction2 {
/**
* DemoAction中的所有功能实现都是由方法来完成的
* 这些方法的规范
* 1.访问权限:public
* 2.方法的返回值:任意
* 3.方法名称:任意
* 4.方法参数:可以没有,如果有可以是任意类型
* 5.注解:需要使用@RequestMapping注解来声明一个访问路径(名称),这里不用再写:demo.action项目请求路径后面的后缀
* 因为该后缀是给web.xml中注册的DispatcherServlet看的,起到拦截请求的作用,符合拦截要求的请求才交给底层servlet处理
*/
@RequestMapping("/demo")
public String demo(){
System.out.println("服务器test02被访问......");
return "main2";
}
}
- 启动tomcat测试
- 网站首页和两次访问到的页面
- 控制台输出
- 以上web请求流程分析
- 两次点击超链接,访问路径的后半段分别为:/test01/demo.action 和 /test02/demo.action
- 两次请求的后缀都为action,满足web.xml中注册的访问请求的通配条件,有资格被处理
- SpringMVC框架通过注解生成了DemoAction和DemoAction2的控制器对象,由于这两个控制器都添加了类上注解,所以相当于添加了一个路径选择条件
- /test01 与 /test02分别被这两个控制器接收处理,又根据/test01/demo 和 /test02/demo分别被满足各自控制器中的方法上的注解路径条件的方法所处理
- 根据各自方法的返回值和视图解析器的路径拼接结果得到要访问的页面路径并访问
- 将访问结果通过SpringMVC核心处理器返回到视图层呈现
SpringMVC 01: SpringMVC + 第一个SpringMVC项目的更多相关文章
- SpringMVC(一):搭建一个SpringMVC helloword项目
操作步骤: 1)下载spring framework开发包,给eclipse安装spring开发插件,如何安装开发插件&下载开发包请参考我的博文:<Spring(一):eclipse上安 ...
- (一)SpringMvc简介以及第一个springmvc工程
一.SpringMVC是什么? springmvc是Spring的一个模块,提供web层解决方案(就与MVC设计架构) 如上图, DispatcherServlet:前端控制器,由SpringMVC提 ...
- SpringMVC:走通一个SpringMVC
我们现在使用SpringMVC来做一个小的用户管理系统,由于重点在学习SpringMVC,这里我们就不用数据库了. 该小系统实现的功能是:1.登录,不做用户名密码的正确性判断,任何用户名+密码都可以成 ...
- Eclipse的maven构建一个web项目,以构建SpringMVC项目为例
http://www.cnblogs.com/javaTest/archive/2012/04/28/2589574.html springmvc demo实例教程源代码下载:http://zuida ...
- 学习建一个spring-Mvc项目
学习建一个spring-Mvc项目 首先要有jdk1.8以上,spring,mybatis,以及整合jar包,tomcat ,然后配置环境(前面有配置得方法). 1)右键new project,--& ...
- MyBatis整合Spring+SpringMVC搭建一个web项目(SSM框架)
本文讲解如何搭建一个SSM架构的web站点 [工具] IDEA.SqlYog.Maven [简述] 该项目由3个模块组成:dao(数据访问层).service(业务处理层).web(表现层) dao层 ...
- 第一个SpringMVC项目——HelloMVC
第一步:启动IDEA新建一个无模板的Maven项目,注意这还不是一个web项目,想成为web项目,需要添加web框架,这就是第二步需要做的事情 第二步:添加web框架支持 单击之后会弹出这个界面 第三 ...
- 1、第一个SpringMVC程序
1.创建如下项目结构 2.在src下的com.springmvc下创建User.java package com.springmvc; public class User { private Stri ...
- springmvc 项目完整示例07 设置配置整合springmvc springmvc所需jar包springmvc web.xml文件配置
前面主要是后台代码,spring以及mybatis的整合 下面主要是springmvc用来处理请求转发,展现层的处理 之前所有做到的,完成了后台,业务层和持久层的开发完成了 接下来就是展现层了 有很多 ...
随机推荐
- 我所使用的生产 Java 17 启动参数
JVM 参数升级提示工具:jacoline.dev/inspect JVM 参数词典:chriswhocodes.com Revolut(英国支付巨头)升级 Java 17 实战:https://ww ...
- bitmap技术解析:redis与roaringBitmap
bitmap的表象意义是,使用一个01标识位来表示是否的状态,可以达到节省空间和高效判定的效果.在我们的实际工作中,也有着许多的应用场景,相信了解bitmap定会给你带来一些额外的收获. 1. bit ...
- BUUCTF-签到题
签到题 很简单写在介绍里面了.
- canvas简易画布
今天学习了canvas,利用它做了一个简易版的画板,校验自己所学的知识,分享出来以供大家学习指教.先上效果图. 主要是使用了canvas的stroke和clearReact来实现画板的绘画和橡皮擦功能 ...
- Leetcode----<Re-Space LCCI>
题解如下: /** * 动态规划解法: * dp[i] 表示 0-i的最小不能被识别的字母个数 * 求 dp[k] 如果第K个字母 不能和前面的字母[0-{k-1}]合在一起被识别 那么dp[k] = ...
- 为什么不建议使用自定义Object作为HashMap的key?
此前部门内的一个线上系统上线后内存一路飙高.一段时间后直接占满.协助开发人员去分析定位,发现内存中某个Object的量远远超出了预期的范围,很明显出现内存泄漏了. 结合代码分析发现,泄漏的这个对象,主 ...
- Hashtable集合 --练习题_计算一个字符串中每个字符出现次数
Hashtable集合 java.util.Hashtable<K,V>集合 implements Map<K,V>接口 Hashtable:底层也是一个哈希表,是一个线程安 ...
- HackerRank第一趴--Basic Select
CITY表: Field Type ID number NAME VARCHAR2(17) COUNTRYCODE VARCHAR2(3) DISTRICT VARCHAR2(20) POPULATI ...
- Python中使用 for 循环来拿遍历 List 的值
常规版本 简单的 for 循环遍历 x_n = ["x1","x2","x3"] for x in x_n: print(x) >&g ...
- kube-shell安装
1.开源项目kube-shell可以为kubectl提供自动的命令提示和补全,对于初学kubernetes比较友好. https://github.com/cloudnativelabs/kube-s ...