什么是MVC?
Model(模型):数据模型,提供前端要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao)和服务层(行为Service),也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务
View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示,也就是说控制器做了个调度员的工作
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架
Spring MVC的特点:
1、轻量级,简单易学
2、高效,基于请求响应的MVC框架
3、与Spring兼容性好,无缝结合
4、约定优于配置
5、功能强大:RESTful、数据验证、格式化、本地化、主题化等
6、简洁灵活
最开始我们在处理请求和响应是基于servlet的,那servlet是一个规范,不属于框架,springMVC是一个表现层的框架,在底层封装了servlet
MVC实现了视图和业务代码的分离
springMVC整体调度流程
springMVC框架如何去使用,如何去配置?
使用控制器
创建一个TestController类,实现Controller接口
xxxxxxxxxx271package com.os467.controller;2
3import org.springframework.web.servlet.ModelAndView;4import org.springframework.web.servlet.mvc.Controller;5
6import javax.servlet.http.HttpServletRequest;7import javax.servlet.http.HttpServletResponse;8
9public class TestController implements Controller {10
11 12 public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {13
14 //创建一个模型视图对象15 ModelAndView modelAndView = new ModelAndView();16
17 //封装数据18 modelAndView.addObject("name","Hello spring MVC");19
20 //设置视图名称21 modelAndView.setViewName("test02");22
23 return modelAndView;24
25 }26
27}
我们在定义了一个Controller之后如何通过mvc去访问这个资源?
1、在web.xml中配置DispatcherServlet:mvc框架前端总调度器
具体会去完成web交互时的各自调度工作
在web.xml中配置前端总调度器,所有的访问请求都会进入此资源
xxxxxxxxxx201 2<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"5 version="4.0">6 7 <!--配置前端总调度器-->8 <servlet>9 <servlet-name>dispatcherServlet</servlet-name>10 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>11 </servlet>12
13 <servlet-mapping>14 <servlet-name>dispatcherServlet</servlet-name>15 16 <!--拦截所有的客户端的请求-->17 <url-pattern>/</url-pattern>18 </servlet-mapping>19
20</web-app>
2、由于MVC框架属于spring的功能模块,所以必须得有核心容器的支持,要去创建spring配置文件springMVC.xml
创建springMVC.xml配置文件,引入springMVC的xml约束
xxxxxxxxxx111 2<beans xmlns="http://www.springframework.org/schema/beans"3 xmlns:mvc="http://www.springframework.org/schema/mvc"4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"5 xsi:schemaLocation="6 http://www.springframework.org/schema/beans7 http://www.springframework.org/schema/beans/spring-beans.xsd8 http://www.springframework.org/schema/mvc9 http://www.springframework.org/schema/mvc/spring-mvc.xsd">10 11</beans>
在web.xml中注册配置文件位置,核心容器对象可以交给DispacherServlet去创建,需要指定配置文件的位置,以及设置启动级别
xxxxxxxxxx161<!--配置前端总调度器-->2 <servlet>3 <servlet-name>dispatcherServlet</servlet-name>4 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>5
6 <!--绑定springMVC的配置文件-->7 <init-param>8 <param-name>contextConfigLocation</param-name>9 <!--配置文件的路径-->10 <param-value>classpath:xml/springMVC.xml</param-value>11 </init-param>12
13 <!--设置启动级别,需要在tomcat服务器启动的时候就去加载核心容器对象-->14 <load-on-startup>1</load-on-startup>15
16 </servlet>
继续配置springMVC.xml,注册controller组件,视图解析器实例
xxxxxxxxxx211<!--注册controller组件-->2<bean id="/controller1" class="com.os467.controller.TestController"></bean>3
4<!--处理映射器和适配器可以不做注册,这里仅作演示-->5<!--注册一个处理映射器-->6<bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>7
8<!--注册一个处理适配器-->9<bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>10
11<!--必须要配置视图解析器-->12<!--注册一个视图解析器-->13<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">14
15 <!--设置视图的前缀-->16 <property name="prefix" value="/jsp/"></property>17
18 <!--设置视图的后缀-->19 <property name="suffix" value=".jsp"></property>20
21</bean>
<mvc:default-servlet-handler/>
让SpringMVC不处理静态资源
<mvc:annotation-driven/>
支持mvc注解驱动
InternalResourceViewResolver
视图解析器
配置xml,开启对注解的支持
xxxxxxxxxx341 2<beans xmlns="http://www.springframework.org/schema/beans"3 xmlns:mvc="http://www.springframework.org/schema/mvc"4 xmlns:context="http://www.springframework.org/schema/context"5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"6 xsi:schemaLocation="7 http://www.springframework.org/schema/beans8 http://www.springframework.org/schema/beans/spring-beans.xsd9 http://www.springframework.org/schema/context10 http://www.springframework.org/schema/context/spring-context.xsd11 http://www.springframework.org/schema/mvc12 http://www.springframework.org/schema/mvc/spring-mvc.xsd">13
14 <!--开启扫描包-->15 <context:component-scan base-package="com.os467"></context:component-scan>16
17 <!--过滤静态资源-->18 <mvc:default-servlet-handler></mvc:default-servlet-handler>19
20 <!--支持mvc注解的驱动-->21 <mvc:annotation-driven></mvc:annotation-driven>22
23 <!--配置视图解析器-->24 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">25
26 <!--设置前缀-->27 <property name="prefix" value="/WEB-INF/jsp/"></property>28
29 <!--设置后缀-->30 <property name="suffix" value=".jsp"></property>31
32 </bean>33
34</beans>
@Controller注解
这个注解如果只是在spring框架中使用的话,就是将当前类的实例存到容器中 但是如果在springMVC中去使用,它不仅可以存实例到容器,还能够将该类下任意一个方法的返回值是String 的方法,返回值会作为视图名称,用于视图跳转
@RequestMapping注解
用于地址的映射,可以修饰类也可以修饰方法,也可以只在方法上使用,能够体现层级关系
xxxxxxxxxx1212("user")3public class UserController {4
5 ("test")6 public String getTest(){7
8 return "test";9
10 }11
12}此时在前端访问:http://localhost:8080/springMVC/user/test 测试资源
@ResponseBody注解
让当前视图失效,并且会直接返回数据
springMVC可以支持参数接值,你在前端需要传递的数据,后端mvc可以使用参数进行接收
可以在接收参数的时候接收HttpServletrequest,再接收Parameter值
也可以在参数中根据对应参数名接值
xxxxxxxxxx91//前端测试:http://localhost:8080/springMVC/user/test03?username=jack001&password=123456&i=10&d=3.142("test03")3public String getTest03(String username,String password,int i,double d){4
5 System.out.println(username+" "+password+" "+i+" "+d);6
7 return "test";8
9}springMVC在参数列表中可以通过实体进行接值
mvc会根据接收实例的属性名称来接收对应的前端数据,并且封装成java对象
xxxxxxxxxx81("test04")2public String getTest04(MvcVo mvcVo){3
4 System.out.println(mvcVo);5
6 return "test";7
8}
在参数中接收一个Model接口的实例,是由springMVC提供的,底层封装了request域
通过返回字符串的方式
xxxxxxxxxx91("test05")2public String getTest05(MvcVo mvcVo, Model model){3
4 //把实体存到Model中,底层封装了一个request域5 model.addAttribute("mcvVo",mvcVo);6
7 return "test02";8
9}通过返回ModelAndView的方式
xxxxxxxxxx151("list")2public ModelAndView getEmpList(){3
4 ModelAndView modelAndView = new ModelAndView();5
6 List<Emp> empList = empService.getEmpList();7
8 //访问持久层查询数据9 modelAndView.addObject("empList",empList);10
11 //设置视图名称12 modelAndView.setViewName("list");13
14 return modelAndView;15}
通过SpringMVC来实现转发和重定向
forward 在MVC框架中视图跳转默认就是请求转发
redirect
通过spring + springMVC + jdbcTemplate 来搭建一个web项目,完成员工列表
web.xml配置
xxxxxxxxxx291 2<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"5 version="4.0">6 <!--配置前端总控制器-->7 <servlet>8 <servlet-name>dispatcherServlet</servlet-name>9 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>10
11 <!--绑定核心配置容器-->12 <init-param>13 <param-name>contextConfigLocation</param-name>14 <param-value>classpath:xml/springMVC.xml</param-value>15 </init-param>16
17 <!--设置启动级别-->18 <load-on-startup>1</load-on-startup>19
20 </servlet>21
22
23 <!--拦截客户端所有请求-->24 <servlet-mapping>25 <servlet-name>dispatcherServlet</servlet-name>26 <url-pattern>/</url-pattern>27 </servlet-mapping>28
29</web-app>
springMVC.xml配置
xxxxxxxxxx571 2<beans xmlns="http://www.springframework.org/schema/beans"3 xmlns:mvc="http://www.springframework.org/schema/mvc"4 xmlns:context="http://www.springframework.org/schema/context"5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"6 xsi:schemaLocation="7 http://www.springframework.org/schema/beans8 http://www.springframework.org/schema/beans/spring-beans.xsd9 http://www.springframework.org/schema/context10 http://www.springframework.org/schema/context/spring-context.xsd11 http://www.springframework.org/schema/mvc12 http://www.springframework.org/schema/mvc/spring-mvc.xsd">13
14 <!--开启扫描包-->15 <context:component-scan base-package="com.os467"></context:component-scan>16
17 <!--过滤静态资源-->18 <mvc:default-servlet-handler></mvc:default-servlet-handler>19
20 <!--开启mvc注解的支持-->21 <mvc:annotation-driven></mvc:annotation-driven>22
23 <!--配置视图解析器-->24 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">25 <!--设置前缀-->26 <property name="prefix" value="/WEB-INF/jsp/"></property>27 <!--设置后缀-->28 <property name="suffix" value=".jsp"></property>29 </bean>30
31 <!--配置一个持久层的实例-->32 <bean id="empDao" class="com.os467.dao.impl.EmpDaoImpl">33 34 <property name="jdbcTemplate" ref="jdbcTemplate"></property>35 36 </bean>37
38 <!--注册数据源实例-->39 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">40
41 <!--注入数据源-->42 <property name="url" value="jdbc:mysql://localhost:3306/web_test?serverTimezone=GMT&characterEncoding=utf-8"></property>43 <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>44 <property name="username" value="root"></property>45 <property name="password" value="root"></property>46
47 </bean>48
49 <!--注册jdbcTemplate-->50 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">51
52 <!--注入数据源数据-->53 <property name="dataSource" ref="dataSource"></property>54 55 </bean>56
57</beans>
表现层(控制器)
xxxxxxxxxx901package com.os467.controller;2
3import com.os467.pojo.Emp;4import com.os467.service.EmpService;5import org.springframework.beans.factory.annotation.Autowired;6import org.springframework.stereotype.Controller;7import org.springframework.ui.Model;8import org.springframework.web.bind.annotation.RequestMapping;9import org.springframework.web.bind.annotation.ResponseBody;10import org.springframework.web.servlet.ModelAndView;11import org.springframework.web.servlet.config.annotation.EnableWebMvc;12
13import java.util.List;14
1516("emp")17public class EmpController {18
19 20 private EmpService empService;21
22 //建立视图层级关系,添加资源路径23 ("/list")24 public String getEmpList(Model model){25
26 List<Emp> empList = empService.getEmpList();27
28 //访问持久层查询数据29 model.addAttribute("empList",empList);30
31 return "list";32
33 }34
35 //建立视图层级关系,添加资源路径36 ("/add")37 public String getAddPage(){38
39 //跳转添加页面40 return "add";41
42 }43
44 45 //建立视图层级关系,添加资源路径46 ("/addSave")47 public String addSave(Emp emp){48
49 boolean b = empService.addSave(emp);50
51 //返回信息52 return b?"1":"0";53 }54
55 56 //建立视图层级关系,添加资源路径57 ("/deleteByEid")58 public String deleteByEid(Integer eid){59
60 boolean b = empService.deleteByEid(eid);61
62 //返回信息63 return b?"1":"0";64 }65
66 //建立视图层级关系,添加资源路径67 ("/getUpdate")68 public String getUpdate(Integer eid,Model model){69
70 Emp emp = empService.getUpdate(eid);71
72 model.addAttribute("emp",emp);73
74 //跳转编辑页面75 return "update";76 }77
78 79 //建立视图层级关系,添加资源路径80 ("/updateSave")81 public String updateSave(Emp emp){82
83 boolean b = empService.updateSave(emp);84
85 //返回信息86 return b?"1":"0";87 }88
89
90}
业务层
xxxxxxxxxx421package com.os467.service.impl;2
3import com.os467.dao.EmpDao;4import com.os467.pojo.Emp;5import com.os467.service.EmpService;6import org.springframework.beans.factory.annotation.Autowired;7import org.springframework.stereotype.Service;8
9import java.util.List;10
1112public class EmpServiceImpl implements EmpService {13
14 15 private EmpDao empDao;16
17 18 public List<Emp> getEmpList() {19
20 return empDao.getEmpList();21 }22
23 24 public boolean addSave(Emp emp) {25 return empDao.addSave(emp);26 }27
28 29 public boolean deleteByEid(Integer eid) {30 return empDao.deleteByEid(eid);31 }32
33 34 public Emp getUpdate(Integer eid) {35 return empDao.getUpdate(eid);36 }37
38 39 public boolean updateSave(Emp emp) {40 return empDao.updateSave(emp);41 }42}
持久层
xxxxxxxxxx1111package com.os467.dao.impl;2
3import com.os467.dao.EmpDao;4import com.os467.pojo.Emp;5import org.springframework.beans.factory.annotation.Autowired;6import org.springframework.jdbc.core.JdbcTemplate;7import org.springframework.jdbc.core.RowMapper;8import org.springframework.stereotype.Repository;9
10import java.sql.ResultSet;11import java.sql.SQLException;12import java.util.List;13
1415public class EmpDaoImpl implements EmpDao {16
17 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {18 this.jdbcTemplate = jdbcTemplate;19 }20
21 22 private JdbcTemplate jdbcTemplate;23
24 /**25 * 获取员工列表的方法26 * @return27 */28 29 public List<Emp> getEmpList() {30 return jdbcTemplate.query("select * from emp", new RowMapper<Emp>() {31 32 public Emp mapRow(ResultSet resultSet, int i) throws SQLException {33
34 Emp emp = new Emp();35
36 emp.setEmpName(resultSet.getString("emp_name"));37 emp.setAge(resultSet.getInt("age"));38 emp.setEid(resultSet.getInt("eid"));39 emp.setSex(resultSet.getInt("sex"));40 emp.setSalary(resultSet.getInt("salary"));41 emp.setBirthday(resultSet.getString("birthday"));42
43 return emp;44 }45 });46 }47
48 /**49 * 保存用户数据50 * @return51 * @param emp52 */53 54 public boolean addSave(Emp emp) {55
56 int i = jdbcTemplate.update("insert into emp(emp_name,age,sex,salary,birthday)values(?,?,?,?,?)", emp.getEmpName(),57 emp.getAge(), emp.getSex(), emp.getSalary(), emp.getBirthday());58
59 return i>0?true:false;60 }61
62 63 public boolean deleteByEid(Integer eid) {64
65 int i = jdbcTemplate.update("delete from emp where eid = ?", eid);66
67 return i>0?true:false;68 }69
70 /**71 * 回显用户信息的方法72 * @return73 */74 75 public Emp getUpdate(Integer eid) {76
77 List<Emp> empList = jdbcTemplate.query("select * from emp where eid = ?", new RowMapper<Emp>() {78
79
80 81 public Emp mapRow(ResultSet resultSet, int i) throws SQLException {82
83 Emp emp = new Emp();84
85 emp.setEmpName(resultSet.getString("emp_name"));86 emp.setAge(resultSet.getInt("age"));87 emp.setEid(resultSet.getInt("eid"));88 emp.setSex(resultSet.getInt("sex"));89 emp.setSalary(resultSet.getInt("salary"));90 emp.setBirthday(resultSet.getString("birthday"));91
92 return emp;93 }94 }, eid);95
96 return empList.get(0);97 }98
99 /**100 * 编辑用户信息的方法101 * @return102 */103 104 public boolean updateSave(Emp emp) {105
106 int i = jdbcTemplate.update("update emp set emp_name = ?,age = ?,sex = ?,salary = ?,birthday = ? where eid = ?",107 emp.getEmpName(), emp.getAge(), emp.getSex(), emp.getSalary(), emp.getBirthday(),emp.getEid());108
109 return i>0?true:false;110 }111}
springMVC能够高效的去处理请求和响应,还支持参数接值,也可以支持注解的方式来映射资源路径