1.MVC模式
视图(View)-对应组件:JSP或者HTML文件 控制器(Controller)-对应组件:Servlet 模型(Model) -对应组件:JavaBean
2.MVC模式具体说明
JSP:负责生成动态网页 Servlet:负责流程控制 JavaBean:负责业务逻辑处理
3.MVC执行过程
MVC执行过程: a.将url映射到java类或类里面的方法 b.封装请求数据 c.调用相关业务处理--->封装返回数据 d.将响应数据渲染到相关视图view(jsp、html、freemarker......)
4.SpringMVC概述
含义:是一个轻量级基于请求/响应模式的MVC框架
包含内容:Controller(控制器)-接收请求、调用业务处理、响应客户端
ModelAndView:模型和视图--封装和传递数据
View(视图)-数据展示(jsp、html、freemarker等)
特点:与Spring无缝集成,方便使用SpringIOC和AOP功能 支持异常处理、类型转换、数据验证、拦截器、本地化、国际化等功能 支持Restful风格及各种视图的支持
5.SpringMVC处理请求流程
6.SpringMVC环境搭建
6.1.导入依赖
<dependencies>
<!--spring-context依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<!--log4j日志记录-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
6.2.编写配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.mvc.controler"/>
<!--启用注解驱动-mvc配置 -->
<mvc:annotation-driven />
<!--配置视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
</beans>
6.3.控制层代码
@Controller //此注解标示着 该类是一个可以处理请求的类 而不是一个普通的类
public class StudentController {
//@RequestMapping是一个用来处理 请求地址映射 的注解
@RequestMapping("/toIndex.do")
public String toIndex(){ //去首页
System.out.println("省略业务逻辑层和数据访问层");
return "index"; //表示的是 一个逻辑视图名
}
}
6.4.配置web.xml
<!--配置核心控制器|前端控制器-DispatcherServlet -->
<servlet>
<servlet-name>smvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>smvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!--过滤器 解决中文乱码问题 -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
6.5.测试
http://localhost:8080/P28_SpringMVC/toIndex.do
7.SpringMVC传参传值
7.1.创建返回类型
String、ModelAndView、void、Map、Model
7.2.控制层方法返回类型具体操作
控制层
@Controller //此注解标示着 该类是一个可以处理请求的类 而不是一个普通的类
public class StudentController {
//@RequestMapping是一个用来处理 请求地址映射 的注解
@RequestMapping("/toIndex.do")
public String toIndex(){ //去首页
System.out.println("省略业务逻辑层和数据访问层");
return "index"; //表示的是 一个逻辑视图名
}
//去首页通过ModelAndView
@RequestMapping("/toIndex1.do")
public ModelAndView toIndex1(){
//ModelAndView 1个参数 代表的是 逻辑视图名
return new ModelAndView("index");
}
//去首页通过ModelAndView
@RequestMapping("/toIndex2.do")
public ModelAndView toIndex2(){
//ModelAndView 3个参数 第1代表的是 逻辑视图名 第2个参数代表的是要传到页面的key 第3个参数代表的是要传到页面的value
return new ModelAndView("index","msg","嘿");
}
}
测试
http://localhost:8080/P28_SpringMVC/toIndex.do
http://localhost:8080/P28_SpringMVC/toIndex1.do
http://localhost:8080/P28_SpringMVC/toIndex2.do
7.3.控制层方法传参类型和方式
一个参数
//控制方法 参数类型 一个参数
@RequestMapping("/toIndex3.do")
public ModelAndView toIndex3(String sname){
//String sname=request.getParameter("sname"); //以前servlet阶段
System.out.println("sname:"+sname);
return new ModelAndView("index","msg","嘿");
}
多个参数
//控制方法 参数类型 2个参数(多个参数)
@RequestMapping("/toIndex4.do")
public ModelAndView toIndex4(String sname,Integer age){
System.out.println("sname:"+sname+"\tage:"+age);
return new ModelAndView("index","msg","嘿");
}
对象传参
注册页面
<body>
<form action="doReg.do" method="post">
<p>姓名:<input type="text" name="sname" value=""/></p>
<p>性别:<input type="text" name="sex" value=""/></p>
<p>年龄:<input type="text" name="age" value=""/></p>
<p><input type="submit" value="注册"/></p>
</form>
</body>
去注册页面:对应StudentController控制层
@RequestMapping("/toReg.do")
public String toRegPage(){ //去注册页面
return "reg";
}
实体类
//学生类
public class Student {
private Integer sno;
private String pwd;
private String sname;
private String sex;
private Integer gid;
private Integer age;
private String phone;
private String address;
// 省略getter和setter方法
}
控制层参数为对象:对应控制层StudentController 伪注册功能
//控制方法 参数类型 多个参数一般 用对象传参
@RequestMapping("/doReg.do")
public ModelAndView doReg(Student stu){ //注册功能
System.out.println("sname:"+stu.getSname()+" sex:"+stu.getSex()+"age:"+stu.getAge());
return new ModelAndView("login");
}
登录页面
<body>
<h3>欢迎来到登录页面</h3>
</body>
测试
http://localhost:8080/P28_SpringMVC/toReg.do
7.4.控制层向页面传值方式
说明方式:通过ModelAndView对象;通过Model对象;通过Map对象。
具体操作:
通过ModelAndView对象:对应StudentController中
//控制层 向页面传值方式1-通过ModelAndView 对象
@RequestMapping("/doReg1.do")
public ModelAndView doReg1(Student stu){ //注册功能
System.out.println("名字:"+stu.getSname());
return new ModelAndView("reg","stu",stu);
}
//控制层 向页面传值方式1-通过ModelAndView 对象
@RequestMapping("/doReg2.do")
public ModelAndView doReg2(Student stu){ //注册功能
System.out.println("名字:"+stu.getSname());
ModelAndView mv =new ModelAndView();
mv.addObject("stu",stu); //将对象带到页面去-通过ModelAndView
mv.setViewName("reg"); //逻辑视图名
return mv;
}
通过Model对象:对应StudentController中
//控制层 向页面传值方式2-通过Model对象
@RequestMapping("/doReg3.do")
public ModelAndView doReg3(Student stu,Model model){ //注册功能
System.out.println("model:"+model);
ModelAndView mv =new ModelAndView();
// mv.addObject("stu",stu); //把用户对象传到页面去
model.addAttribute("stu",stu); //将对象带到页面去-通过Model
mv.setViewName("reg"); //逻辑视图名
return mv;
}
通过Map对象:对应StudentController中
//控制层 向页面传值方式3-通过Map对象
@RequestMapping("/doReg4.do")
public ModelAndView doReg4(Student stu,Map<String,Object> maps){ //注册功能
System.out.println("maps:"+maps);
ModelAndView mv =new ModelAndView();
maps.put("stu",stu); //将对象带到页面去-通过Map
mv.setViewName("reg"); //逻辑视图名
return mv;
}
8.SpringMVC上传下载
8.1.S平日那个MVC上传功能
8.1.1.上传实现
导入依赖
<dependencies>
<!--spring-context依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<!--commons-fileupload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
编写配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.mvc.controller"/>
<!--启用注解驱动-mvc配置 -->
<mvc:annotation-driven />
<!--配置视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
<!--支持文件上传的解析器 maxUploadSize上传的最大大小,单位是字节-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:maxUploadSize="802400" p:defaultEncoding="utf-8"/>
</beans>
添加上传表单:对应upDownLoad.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上传下载页面</title>
</head>
<body>
<form action="doUpload.do" method="post" enctype="multipart/form-data">
图片:<input type="file" name="file"/><input type="submit" value="上传"/>
</form>
</body>
</html>
编写控制层代码
@Controller //此注解标示着 该类是一个可以处理请求的类 而不是一个普通的类
public class FileController {
//去上传的页面
@RequestMapping("/toUpPage.do")
public String toUpPage(){
return "upDownLoad";
}
//文件上传
@RequestMapping("/doUpload.do")
public ModelAndView toUpload(MultipartFile file,HttpServletRequest request)throws Exception{
//1、获取文件名
String fname=file.getOriginalFilename();
//2、对文件进行处理(比喻生成随机文件名)
//a-获取文件的后缀名
String ext=FilenameUtils.getExtension(fname);
//b-生成随机文件名
//String ranFName=System.currentTimeMillis()+"."+ext;
String rfName=UUID.randomUUID()+"."+ext; //全球唯一识别码
//3、获取存放文件的物理路径
String savePath=request.getServletContext().getRealPath("upload");
System.out.println("地址:"+savePath);
//4、创建文件实例
File f1=new File(savePath,rfName);
//5、写入文件进行上传操作
//FileUtils.copyInputStreamToFile(file.getInputStream(),f1);
file.transferTo(f1);
return new ModelAndView("upDownLoad");
}
}
配置web.xml
<!--配置核心控制器|前端控制器-DispatcherServlet -->
<servlet>
<servlet-name>smvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>smvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!--过滤器 解决中文乱码问题 -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
测试
http://localhost:8080/P29_SpringMVC_uploaddown/toUpPage.do
项目结构图
8.1.2.上传功能的注意点
表单上:在表单上添加enctype="multipart/form-data"且上传按钮的type为file
<form action="doUpload.do" method="post" enctype="multipart/form-data">
图片:<input type="file" name="file"/><input type="submit" value="上传"/>
</form>
核心配置文件:需要添加支持文件上传组件的解析器
<!--支持文件上传的解析器 maxUploadSize上传的最大大小,单位是字节-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:maxUploadSize="802400" p:defaultEncoding="utf-8"/>
控制层方法上面:需要添加MultipartFile file参数并且file和表单的name保持一致
8.2.SpringMVC下载功能
8.2.1.下载实现
提供下载超链接
<h3>-------------下面是下载----------------</h3>
<h3><a href="downLoad.do?filename=01.jpg">点击下载</a></h3>
<h3><a href="downLoad.do?filename=老孙.jpg">点击中文文件名下载</a></h3>
控制层代码
//下载功能
@RequestMapping("/downLoad.do")
public void downLoad(String filename,HttpServletRequest req,HttpServletResponse res)throws Exception{
//1、获得文件
String file=req.getServletContext().getRealPath("/upload/"+filename);
//2、通过文件构建一个输入流对象
FileInputStream fis=new FileInputStream(file);
//中文乱码问题-碰到中文文件名的下载 需要考虑-浏览器接收文件时 默认ISO-8859-1编码
filename=new String(filename.getBytes("UTF-8"),"ISO-8859-1");
//3、设置输出格式和内容
res.setHeader("content-disposition","attchment;filename="+filename);//文档头
res.setContentType("application/octet-stream"); //文件类型
res.setContentLength(fis.available()); //文件大小
//4、构建缓冲区
byte[] by=new byte[2048]; //构建一个缓冲区
//5、循环读写
int len=0; //计数
while((len=fis.read(by))!=-1){
res.getOutputStream().write(by,0,len);
}
//6、刷新并关闭资源
res.getOutputStream().flush(); //刷新
res.getOutputStream().close();
fis.close();
}
8.2.2.下载功能注意点
针对中文文件名的下载,注意中文乱码的问题
//中文乱码问题-碰到中文文件名的下载 需要考虑-浏览器接收文件时 默认ISO-8859-1编码
filename=new String(filename.getBytes("UTF-8"),"ISO-8859-1");