MVC三层架构:
模型(Model)、view(视图)、控制器(Controller),是一种软件设计规范!
- 将业务逻辑、数据、显示分离的方法来组织代码
- mvc只要作用是降低视图与业务逻辑间的双向耦合
- mvc不是设计模式,是一种架构模式
Controller:控制器
- 取得表单数据
- 调用业务逻辑
- 转向指定的页面
Model:模型
- 业务逻辑
- 保存数据的状态
View:视图
- 显示页面
官方文档:Web on Servlet Stack (spring.io)
1、回顾servlet
1.1 创建maven项目
1.导入依赖包:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
2.创建普通的maven项目后要将新建的模块右键添加为web项目
出现web的项目文件才创建完成!
1.2 创建项目
1.servlet层
package com.liu.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取前端参数
String method = req.getParameter("method");
if (method.equals("add")){
req.getSession().setAttribute("msg","执行了add方法");
}
if (method.equals("delete")){
req.getSession().setAttribute("msg","执行了delete方法");
}
//2.调取业务层
//3.视图转发或重定向
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.创建跳转的页面jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
3.在web.xml里配置servlet映射路径
<?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">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.liu.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!-- <session-config>-->
<!-- <session-timeout>15</session-timeout>-->
<!-- </session-config>-->
<!-- -->
<!-- <welcome-file-list>-->
<!-- <welcome-file>index.jsp</welcome-file>-->
<!-- </welcome-file-list>-->
</web-app>
4.创建一个提交表单
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/hello" method="post">
<input type="text" name="method">
<input type="submit">
</form>
</body>
</html>
回顾form表单的各属性值
input 标签的 value 属性的作用是由 input 标签的 type 属性的值决定的
当 type 的取值为 button、reset、submit 中的其中一个时,此时 value 属性的值表示的是按钮上显示的文本
当 type 的取值为 text、password、hidden 中的其中一个时,此时 value 属性的值表示的是输入框中显示的初始值,此初始值可以更改,并且在提交表单时,value 属性的值会发送给服务器(既是初始值,也是提交给服务器的值)
当 type 的取值为 checkbox、radio 中的其中一个时,此时 value 属性的值表示的是提交给服务器的值
当 type 的取值为 image 时,点击它提交表单后,会将用户的点击位置相对于图像左上角的 x 坐标和 y 坐标提交给服务器
- 当设置 input 标签的 type 属性值为checkbox 或者 radio 时,必须同时设置 input 标签的 value 属性。
- 当 type=“file” 时,不能使用 value 属性
- name 属性规定 input 元素的名称
- name 属性用于对提交到服务器后的表单数据进行标识,或者在客户端通过 JavaScript 引用表单数据
- 只有设置了 name 属性的表单元素才能在提交表单时传递它们的值,因为服务端获取表单提交的数据是通过表单元素的 name 属性的值而得到的,没有 name 属性就无法得到表单元素提交给服务端的值。
5.配置tomcat并启动
1.3 MVC框架完成的事
- 将url映射到java类或Java类的方法
- 封装用户提交的数据
- 处理请求-调用业务处理-封装响应数据
- 将响应的数据进行渲染 .jsp/html等表示层数据
2、为什么要学习MVC
Spring MVC的特点:
1.轻量级 简单易学
2.高效,基于请求响应的MVC框架
3.与Spring兼容性好
4.约定大于配置
5.功能强大:RESTful,数据验证、格式化、本地化、主题
6.简洁灵活
Spring的web框架围绕DispatcherServlet【请求分发到不同的处理请的作用】设计
3、HelloSpringMVC
配置:
- 新建一个module,添加web支持
- 确定导入了springMVC的依赖
- 配置web.xml,注册DispatcherServlet
不用在web.xml里配置了!!
在web.xml里注册DispatcherServlet
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别-1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--匹配所有的请求:不包括jsp-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
注意点:
*/和/的区别:
- /:只匹配所有的请求,不会去匹配jsp页面
- /*:匹配所有的请求包括jsp页面
编写springMVC的配置文件:名称:springmvc-servlet.xml
<?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">
</beans>
添加处理映射器
这个beanName处理器需要根据bean的id查找,需要有bean,以后不用这个处理器!
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
添加处理器适配器
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
添加视图解析器
<!--视图解析器
1.获取了ModelAndView的数据
2.解析ModelAndView的视图和名字
3.拼接视图名字
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
写一个控制层的类
package com.liu.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//modelAndView 模型和视图
ModelAndView mv = new ModelAndView();
//封装对象,放在ModelAndView中
mv.addObject("msg","HelloSpringMVC!");
//封装要跳转的视图,放在ModelAndView中
mv.setViewName("hello");//:/WEB-INF/jsp/hello.jsp
return mv;
}
}
将自己的类交给spring容器,注册bean
<!--Handler-->
<bean id="/hello" class="com.liu.controller.HelloController"/>
写要跳转的页面,显示ModelAndView存放的数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
配置tomcat启动测试
可能遇到的问题404:
1.查看控制台输出,看一下是不是缺少jar包
2.如果jar包存在显示无法输出,就在IDEA的项目发布中添加lib依赖
3.重启tomcat
4、springMVC的执行原理
实线都是spring做了,我们只用做虚线部分!
分析执行流程:
1.DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心,用户发出请求,
DispatcherServlet接收请求并拦截请求
- 假设请求的url为:http://localhost:8080/SpringMVC/hello
- url被拆分为三部分:
- http://localhost:8080服务器域名
- SpringMVC部署在服务器的web站点
- hello表示控制层
- 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器
2.HandlerMapping为处理器映射,DispatcherServlet调用,主要作用是根据url查找Handler
3.HandlerExecution表示具体的Handler,主要作用是根据url查找控制器,如上url被查找控制器为hello
4.HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等
5.HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler
6.Handler让具体的Controller执行
7.Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView
8.HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
9.DispatcherServlet调用视图解析器(ViewResolver)来解析HanderAdapter传递的逻辑视图名
10.视图解析器将解析的逻辑视图名传递给DispatcherServlet
11.DispatcherServlet根据视图解析器的视图结果调用具体的视图
12.视图呈现给用户
5、注解版
rvlet,如解析控制器映射等**
5.HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler
6.Handler让具体的Controller执行
7.Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView
8.HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
9.DispatcherServlet调用视图解析器(ViewResolver)来解析HanderAdapter传递的逻辑视图名
10.视图解析器将解析的逻辑视图名传递给DispatcherServlet
11.DispatcherServlet根据视图解析器的视图结果调用具体的视图
12.视图呈现给用户