★springMVC表现层框架
什么是MVC?
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范
是将业务逻辑、数据、显示分离的方法来组织代码
MVC主要作用是降低了视图与业务逻辑间的双向耦合
MVC不是一种设计模式,MVC是一种架构模式,不同的MVC存在差异
Model(模型):数据模型,提供前端要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao)和服务层(行为Service),也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务
View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示,也就是说控制器做了个调度员的工作
SpringMVC
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架
Spring MVC的特点:
1、轻量级,简单易学
2、高效,基于请求响应的MVC框架
3、与Spring兼容性好,无缝结合
4、约定优于配置
5、功能强大:RESTful、数据验证、格式化、本地化、主题化等
6、简洁灵活
最开始我们在处理请求和响应是基于servlet的,那servlet是一个规范,不属于框架,springMVC是一个表现层的框架,在底层封装了servlet
MVC实现了视图和业务代码的分离
springMVC核心原理
- 用户发送请求给服务器,url:user.do
- 服务器收到请求,发现DispatcherServlet可以处理,于是调用DispatcherServlet
- DispatcherServlet内部,通过HandlerMappings(处理映射器)检查这个url有没有对应的Controller,如果有,则通HandlerAdapters(处理适配器)调用Controller
- Controller开始执行
- Controller执行完毕后,如果返回字符串,则ViewResolvers将字符串转化成相应的视图对象,如果返回ModelAndView对象,该对象本身就包含了视图对象信息
- DispatcherServlet通过ViewResolvers(视图解析器)将视图对象中的数据输出给服务器
- 服务器将数据输出给客户端
springMVC整体调度流程
- 客户端发送请求给服务端,springMVC框架会通过DispatcherServlet来做一个资源的拦截(http://localhost:8080/servlet/test)
- DispatcherServlet会调用处理映射器HandlerMappings来完成对地址的解析,然后把解析的信息告诉DispacherServlet
- DispacherServlet调用处理适配器HandlerAdapters从容器中找到对应的资源(会找到controller对应的资源)
- HandlerAdapters找到对应资源之后,会去执行具体的Controller(然后会去封装数据,设置视图名称)
- 执行完逻辑之后会将视图和模块(ModelAndView)返回给DispacherServlet
- 继续调用视图解析器ViewResolvers视图解析器来解析ModelAndView里面视图名称,然后根据视图解析器内部的匹配规则来定位到具体的前端资源(jsp)
- ViewResolvers在解析完之后会将解析的信息告诉DispacherServlet,然后会去做具体的页面跳转,数据渲染等工作
配置springMVC
springMVC框架如何去使用,如何去配置?
使用控制器
创建一个TestController类,实现Controller接口
package com.os467.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 TestController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//创建一个模型视图对象
ModelAndView modelAndView = new ModelAndView();
//封装数据
modelAndView.addObject("name","Hello spring MVC");
//设置视图名称
modelAndView.setViewName("test02");
return modelAndView;
}
}
我们在定义了一个Controller之后如何通过mvc去访问这个资源?
1、在web.xml中配置DispatcherServlet:mvc框架前端总调度器
具体会去完成web交互时的各自调度工作
- Spring的web框架围绕DispatcherServlet调度Servlet设计
- DispatcherServlet的作用是将请求分发到不同的处理器,从Spring2.5开始,使用Java5或者以上版本的用户可以采用基于注解形式进行开发
在web.xml中配置前端总调度器,所有的访问请求都会进入此资源
<?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>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!--拦截所有的客户端的请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2、由于MVC框架属于spring的功能模块,所以必须得有核心容器的支持,要去创建spring配置文件springMVC.xml
创建springMVC.xml配置文件,引入springMVC的xml约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
</beans>
在web.xml中注册配置文件位置,核心容器对象可以交给DispacherServlet去创建,需要指定配置文件的位置,以及设置启动级别
<!--配置前端总调度器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--绑定springMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<!--配置文件的路径-->
<param-value>classpath:xml/springMVC.xml</param-value>
</init-param>
<!--设置启动级别,需要在tomcat服务器启动的时候就去加载核心容器对象-->
<load-on-startup>1</load-on-startup>
</servlet>
继续配置springMVC.xml,注册controller组件,视图解析器实例
<!--注册controller组件-->
<bean id="/controller1" class="com.os467.controller.TestController"></bean>
<!--处理映射器和适配器可以不做注册,这里仅作演示-->
<!--注册一个处理映射器-->
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!--注册一个处理适配器-->
<bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!--必须要配置视图解析器-->
<!--注册一个视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置视图的前缀-->
<property name="prefix" value="/jsp/"></property>
<!--设置视图的后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
SpringMVC基于注解
<mvc:default-servlet-handler/>
让SpringMVC不处理静态资源
<mvc:annotation-driven/>
支持mvc注解驱动
InternalResourceViewResolver
视图解析器
配置xml,开启对注解的支持
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启扫描包-->
<context:component-scan base-package="com.os467"></context:component-scan>
<!--过滤静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--支持mvc注解的驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!--设置后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
@Controller注解
这个注解如果只是在spring框架中使用的话,就是将当前类的实例存到容器中
但是如果在springMVC中去使用,它不仅可以存实例到容器,还能够将该类下任意一个方法的返回值是String
的方法,返回值会作为视图名称,用于视图跳转
@RequestMapping注解
用于地址的映射,可以修饰类也可以修饰方法,也可以只在方法上使用,能够体现层级关系
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("test")
public String getTest(){
return "test";
}
}
此时在前端访问:http://localhost:8080/springMVC/user/test 测试资源
@ResponseBody注解
让当前视图失效,并且会直接返回数据
springMVC如何去接收前端传递过来的值
springMVC可以支持参数接值,你在前端需要传递的数据,后端mvc可以使用参数进行接收
可以在接收参数的时候接收HttpServletrequest,再接收Parameter值
也可以在参数中根据对应参数名接值
//前端测试:http://localhost:8080/springMVC/user/test03?username=jack001&password=123456&i=10&d=3.14
@RequestMapping("test03")
public String getTest03(String username,String password,int i,double d){
System.out.println(username+" "+password+" "+i+" "+d);
return "test";
}
springMVC在参数列表中可以通过实体进行接值
mvc会根据接收实例的属性名称来接收对应的前端数据,并且封装成java对象
@RequestMapping("test04")
public String getTest04(MvcVo mvcVo){
System.out.println(mvcVo);
return "test";
}
springMVC如何将封装好的数据存到Model中
在参数中接收一个Model接口的实例,是由springMVC提供的,底层封装了request域
通过返回字符串的方式
@RequestMapping("test05")
public String getTest05(MvcVo mvcVo, Model model){
//把实体存到Model中,底层封装了一个request域
model.addAttribute("mcvVo",mvcVo);
return "test02";
}
通过返回ModelAndView的方式
@RequestMapping("list")
public ModelAndView getEmpList(){
ModelAndView modelAndView = new ModelAndView();
List<Emp> empList = empService.getEmpList();
//访问持久层查询数据
modelAndView.addObject("empList",empList);
//设置视图名称
modelAndView.setViewName("list");
return modelAndView;
}
通过SpringMVC来实现转发和重定向
默认是定位视图资源
forward 转发
在MVC框架中视图跳转默认就是请求转发 forward:t8
redirect 重定向
都是根据内部资源跳转,如果不写则是要去定位视图 redirect:t8
//从t9重定向到t8
@RequestMapping("/t9")
public String test09(){
return "redirect:t8"
}
支持mvc返回对象给客户端
会自动将对象转成json,然后再响应
导入下面pom坐标
<!-- jackson依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.3</version>
</dependency>
项目
通过spring + springMVC + jdbcTemplate 来搭建一个web项目,完成员工列表
web.xml配置
<?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>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--绑定核心配置容器-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:xml/springMVC.xml</param-value>
</init-param>
<!--设置启动级别-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--拦截客户端所有请求-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
springMVC.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启扫描包-->
<context:component-scan base-package="com.os467"></context:component-scan>
<!--过滤静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--开启mvc注解的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!--设置后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
<!--配置一个持久层的实例-->
<bean id="empDao" class="com.os467.dao.impl.EmpDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--注册数据源实例-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--注入数据源-->
<property name="url" value="jdbc:mysql://localhost:3306/web_test?serverTimezone=GMT&characterEncoding=utf-8"></property>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--注册jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入数据源数据-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
表现层(控制器)
package com.os467.controller;
import com.os467.pojo.Emp;
import com.os467.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import java.util.List;
@Controller
@RequestMapping("emp")
public class EmpController {
@Autowired
private EmpService empService;
//建立视图层级关系,添加资源路径
@RequestMapping("/list")
public String getEmpList(Model model){
List<Emp> empList = empService.getEmpList();
//访问持久层查询数据
model.addAttribute("empList",empList);
return "list";
}
//建立视图层级关系,添加资源路径
@RequestMapping("/add")
public String getAddPage(){
//跳转添加页面
return "add";
}
@ResponseBody
//建立视图层级关系,添加资源路径
@RequestMapping("/addSave")
public String addSave(Emp emp){
boolean b = empService.addSave(emp);
//返回信息
return b?"1":"0";
}
@ResponseBody
//建立视图层级关系,添加资源路径
@RequestMapping("/deleteByEid")
public String deleteByEid(Integer eid){
boolean b = empService.deleteByEid(eid);
//返回信息
return b?"1":"0";
}
//建立视图层级关系,添加资源路径
@RequestMapping("/getUpdate")
public String getUpdate(Integer eid,Model model){
Emp emp = empService.getUpdate(eid);
model.addAttribute("emp",emp);
//跳转编辑页面
return "update";
}
@ResponseBody
//建立视图层级关系,添加资源路径
@RequestMapping("/updateSave")
public String updateSave(Emp emp){
boolean b = empService.updateSave(emp);
//返回信息
return b?"1":"0";
}
}
业务层
package com.os467.service.impl;
import com.os467.dao.EmpDao;
import com.os467.pojo.Emp;
import com.os467.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpDao empDao;
@Override
public List<Emp> getEmpList() {
return empDao.getEmpList();
}
@Override
public boolean addSave(Emp emp) {
return empDao.addSave(emp);
}
@Override
public boolean deleteByEid(Integer eid) {
return empDao.deleteByEid(eid);
}
@Override
public Emp getUpdate(Integer eid) {
return empDao.getUpdate(eid);
}
@Override
public boolean updateSave(Emp emp) {
return empDao.updateSave(emp);
}
}
持久层
package com.os467.dao.impl;
import com.os467.dao.EmpDao;
import com.os467.pojo.Emp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Repository
public class EmpDaoImpl implements EmpDao {
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 获取员工列表的方法
* @return
*/
@Override
public List<Emp> getEmpList() {
return jdbcTemplate.query("select * from emp", new RowMapper<Emp>() {
@Override
public Emp mapRow(ResultSet resultSet, int i) throws SQLException {
Emp emp = new Emp();
emp.setEmpName(resultSet.getString("emp_name"));
emp.setAge(resultSet.getInt("age"));
emp.setEid(resultSet.getInt("eid"));
emp.setSex(resultSet.getInt("sex"));
emp.setSalary(resultSet.getInt("salary"));
emp.setBirthday(resultSet.getString("birthday"));
return emp;
}
});
}
/**
* 保存用户数据
* @return
* @param emp
*/
@Override
public boolean addSave(Emp emp) {
int i = jdbcTemplate.update("insert into emp(emp_name,age,sex,salary,birthday)values(?,?,?,?,?)", emp.getEmpName(),
emp.getAge(), emp.getSex(), emp.getSalary(), emp.getBirthday());
return i>0?true:false;
}
@Override
public boolean deleteByEid(Integer eid) {
int i = jdbcTemplate.update("delete from emp where eid = ?", eid);
return i>0?true:false;
}
/**
* 回显用户信息的方法
* @return
*/
@Override
public Emp getUpdate(Integer eid) {
List<Emp> empList = jdbcTemplate.query("select * from emp where eid = ?", new RowMapper<Emp>() {
@Override
public Emp mapRow(ResultSet resultSet, int i) throws SQLException {
Emp emp = new Emp();
emp.setEmpName(resultSet.getString("emp_name"));
emp.setAge(resultSet.getInt("age"));
emp.setEid(resultSet.getInt("eid"));
emp.setSex(resultSet.getInt("sex"));
emp.setSalary(resultSet.getInt("salary"));
emp.setBirthday(resultSet.getString("birthday"));
return emp;
}
}, eid);
return empList.get(0);
}
/**
* 编辑用户信息的方法
* @return
*/
@Override
public boolean updateSave(Emp emp) {
int i = jdbcTemplate.update("update emp set emp_name = ?,age = ?,sex = ?,salary = ?,birthday = ? where eid = ?",
emp.getEmpName(), emp.getAge(), emp.getSex(), emp.getSalary(), emp.getBirthday(),emp.getEid());
return i>0?true:false;
}
}
springMVC能够高效的去处理请求和响应,还支持参数接值,也可以支持注解的方式来映射资源路径
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com