1 介绍
- 学习视频:https://www.bilibili.com/vide...
- Spring:IOC和AOP必须掌握
- SpringMVC:执行流程必须掌握
- 官网:https://docs.spring.io/spring...
1.1 什么是MVC?
- Model:数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
- View:负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
- Controller(调度员): 接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。
- 最常用的MVC:(Model)Bean +(view) Jsp +(Controller) Servlet
1.2 Model1时代
- 分为:视图层V和模型层M;由视图层的view来控制分发数据并展示给用户
- 缺点:JSP职责不单一,过重,不便于维护
1.3 Model2时代(MVC延续至今)
- 流程:分为了Contrller,Model,View
- 访问流程:
- 用户发请求
- Servlet接收请求数据,并调用对应的业务逻辑方法
- 业务处理完毕,返回更新后的数据给servlet
- servlet转向到JSP,由JSP来渲染页面
- 响应给前端更新后的页面
1.4 回顾Servlet创建
- 创建maven,父工程:pom.xml
4.0.0
com.ssl
SpringMVC
pom
1.0-SNAPSHOT
junit
junit
4.12
org.springframework
spring-webmvc
5.2.4.RELEASE
javax.servlet
servlet-api
2.5
javax.servlet.jsp
jsp-api
2.2
javax.servlet
jstl
1.2
org.projectlombok
lombok
1.18.12
com.fasterxml.jackson.core
jackson-databind
2.10.0
com.alibaba
fastjson
1.2.62
src/main/resources
**/*.properties
**/*.xml
true
src/main/java
**/*.properties
**/*.xml
true
- 创建子工程,idea右键Add Framwork Support添加web支持
- 实现HelloServlet继承HttpServlet接口,并创建/WEB-INF/jsp/test.jsp
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1 获得参数
//2 调用业务层
//3 视图转发或者重定向
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
- web.xml中注册HelloServlet,测试跳转:http://localhost:8080/springmvc_01_servlet//helloServlet
HelloServlet
com.ssl.web.HelloServlet
HelloServlet
/helloServlet
2 第一个SpringMVC
- 概念:SpringMVC是Spring框架中的一个分支,是基于Java实现MVC的轻量级Web框架
- 核心:Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计的。
2.1 执行原理
SpringMVC底层工作原理:
-
DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
- 假设url为 : http://localhost:8080/SpringMVC/hello
- 服务器域名:http://localhost:8080
- web站点:/SpringMVC
- hello表示控制器:/hello
- 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
- HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
- HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。
- HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
- HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
- Handler让具体的Controller执行。
- Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
- HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
- DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
- 视图解析器将解析的逻辑视图名传给DispatcherServlet。
- DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
- 最终视图呈现给用户。
2.2 不使用注解开发
- 了解具体的执行过程=面试谈资。虽然开发中不会这么麻烦的使用,但必须看完-理解-继续学习
1 配置web.xml
- 完成DispatcherServlet,关联resource配置文件
SpringMvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springMvc_servlet.xml
1
SpringMvc
/
2 配置springMvc_servlet.xml
- 获得视图解析器、映射器、适配器,绑定跳转url
3 /WEB-INF/jsp/hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
hello
<%--接受传递的参数--%>
${msg}
4 HelloController实现Controller
- 访问:http://localhost:8080/springmvc_02_hellomvc/hello
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//1 创建modelAndView
ModelAndView mv = new ModelAndView();
//2 调用业务层,这里没有,就不写
//3 封装对象,放在mv中添加
mv.addObject("msg", "Hello SpringMvc");
//4 封装要跳转的视图,WEB-INF/jsp/hello.jsp
mv.setViewName("hello");
return mv;
}
}
==5 SpringMVC原理回顾==
- 反复观看,理解原理!
2.3 使用注解开发
1 web.xml
springMvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springMvc_servlet.xml
1
springMvc
/
2 springMvc_servlet.xml
- 注解省略了映射器、适配器,专注于写视图解析器;跳转的Controller也不用配置进Spring
3 /WEB-INF/jsp/hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
hello
${msg}
4 HelloController
- 简化了实现的接口,使用@注解配置映射器
- 访问:http://localhost:8080/springmvc_03_annotation/hello
@Controller
public class HelloController {
/**
* @param model 模型
* @return 被视图解析器处理:访问"/WEB-INF/jsp/hello.jsp资源
* 访问的url:RequestMapping("/hello")
*/
@RequestMapping("/hello")
public String hello(Model model) {
//封装数据
model.addAttribute("msg", "Hello SpringMvc_annotation");
//被视图解析器处理:访问"/WEB-INF/jsp/hello.jsp资源
return "hello";
}
3 Controller和RestFul
- 配置web.xml
springMvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring_mvc_servlet.xml
springMvc
/
encode
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encode
/*
- spring_mvc_servlet.xml
3.1 Controller
-
不使用注解,极其不推荐使用,因为:
- 配置麻烦:
,并且需要implements Controller
- 不够灵活,太费力气,浪费时间
- 访问:http://localhost:8080/springmvc_04_controller/demo
- 配置麻烦:
public class ControllerDemo1 implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("demo1","demo1:Controller会返回一个modelAndView");
modelAndView.setViewName("demo1");
return modelAndView;
}
}
3.2 @Controller
- 使用注解开发,@Controller注册进Spring容器,如果返回值是String,并且有具体的页面可以跳转,那么就会被视图解析器解析
- 访问:http://localhost:8080/springmvc_04_controller/demo2
@Controller
public class ControllerDemo2 {
@RequestMapping("/demo2")
public String test1(Model model) {
model.addAttribute("demo2", "demo2");
return "demo2";
}
}
3.3 @RequestMapping
- 可以在类和方法上配置url访问路径
- 访问:http://localhost:8080/springmvc_04_controller/controller/demo3
@Controller
@RequestMapping("/controller")
public class ControllerDemo3 {
@RequestMapping("/demo3")
public String test1(Model model) {
model.addAttribute("demo3", "demo3");
return "demo3";
}
}
3.4 RestFul风格
-
优点:
- 最大的优势是安全,看不出源代码的参数和意义
- 实现地址复用,使得get和post访问url相同,框架会自动进行类型转换
- 高效:支持缓存
-
缺点:
- 不像原生的url见名知意,url理解不直观
-
实现方式:
-
1:url
@GetMapping("/addRest/{a}/{b}")
+ 参数@PathVariable int a, @PathVariable int b
- 访问:http://localhost:8080/springmvc_04_controller/addRest/1/2
-
2:url
@PostMapping("/addRest/{a}/{b}")
+ 参数不变@PathVariable int a, @PathVariable int b
- 使用Postman中的post访问:http://localhost:8080/springmvc_04_controller/addRest/1/2
-
@Controller
public class RestFulController {
/**
* 原生的url:http://localhost:8080/springmvc_04/add?a=1&b=1
*/
@RequestMapping("/add")
public String getAdd1(int a, int b, Model model) {
int result = a + b;
model.addAttribute("add", "原生的url:结果为" + result);
return "add";
}
/**
* RestFul方式一:method = get
* RequestMapping("/addRest/{a}/{b}" method=requestMethod.GET) = @GetMapping()
* http://localhost:8080/springmvc_04/addRest/1/1
*/
@GetMapping("/addRest/{a}/{b}")
public String getAdd2(@PathVariable int a, @PathVariable int b, Model model) {
int result = a + b;
model.addAttribute("add", "Rest的url:结果为" + result);
return "addRest";
}
/**
* 复用相同的url
* RestFul方式二:method=post,使用RestFul的话,请求的url和GET就一样了
*/
@PostMapping("/addRest/{a}/{b}")
public String getAdd3(@PathVariable int a, @PathVariable int b, Model model) {
int result = a + b;
model.addAttribute("add", "Rest的url:结果为" + result);
return "addRest";
}
}
3.5 重定向和转发
- 可以使用原生的request转发或者response重定向
- 推荐使用SpringMvc的
return “forward:xxx”/"redirect:xxx"
@Controller
public class ModelTest1 {
//原生的转发:返回值是void,没有经过视图解析器;原生的重定向同样如此,都不走视图解析器,直接重定向
@RequestMapping("/test1")
public void test1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getSession().getId();
System.out.println(id);
request.getRequestDispatcher("index.jsp").forward(request,response);
}
//SpringMvc转发:测试结果是不走视图解析器,url没变是转发
@RequestMapping("/test2")
public String test2(Model model) {
model.addAttribute("demo1","这是test2中的Spring转发");
return "forward:/WEB-INF/jsp/demo1.jsp";
}
//SpringMvc重定向:测试结果是不走视图解析器
@RequestMapping("/test3")
public String test3() {
System.out.println("跳转回首页index.jsp");
return "redirect:index.jsp";
}
}
3.6 接受请求参数和数据回显
- 前端提交的name和后端映射器接受的形参名一样,则直接接受
-
前端提交的name和后端映射器接受的形参名不用一样,再形参前
@RequestParam("xxx")
更改名称一致- 养成习惯:无论是否一样,都必须加上
@RequestParam
- 养成习惯:无论是否一样,都必须加上
- 后端参数封装如果成一个pojo,前端传过来的name会自动pojo中的成员属性,不匹配的属性=null/0
- 如何解决中文乱码问题?请看下节!
@Controller
public class UserController {
/** http://localhost:8080/springmvc_04/t1?id=1&name=abc&age=18
* @param user SpringMvc 会自动封装数据到参数里的pojo,不匹配的属性=null/0
*/
@GetMapping("/t1")
public String getUser(User user){
System.out.println(user);
return "test1";
}
}
3.7 Model,ModelAndView等
- Model:精简版,适合初学者,大多数情况封装参数,设置转发视图层就够用
- ModelMap:继承了LinkedHashMap,有它的方法和特性
- ModelAndView:可以在存储数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转
- 怎么学习:用80%的时间学号基础,18%时间研究框架,2%学点英文,剩下不会的看官方文档
4 乱码问题
-
方法一:web.xml里面配置的SpringMvc自带的过滤器
CharacterEncodingFilter
:因为要跳转到xxx.jsp页面,所以url是/*(≠/)/*
springMvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring_mvc_servlet.xml
springMvc
/
encode
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encode
/*
- 方法二:一劳永逸,但需要重启Tomcat服务器,修改Tomcat里面的server.xml配置文件:
URIEncoding = "UTF-8"
5 JSON
5.1 前端初识Json
- 前端展示两者数据,学会js和json互相转换
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
json
5.2 Jackson Databind
- 使用 Jackson Databind可以快速生成json数据
1 导入依赖
com.fasterxml.jackson.core
jackson-databind
2.10.0
- json=一个字符串,所以会有中文乱码问题,需要在springmvc.xml配置
2 编写Controller
- @RestControoler:该类下所有方法不走视图解析器,返回一个json数据
- @ResponceBody:该方法不走视图解析器,返回一个json数据
- 访问:http://localhost:8080/springmvc_05_json/t1,页面显示一个json数据,不经过视图解析器
- 回顾日期:
new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss")
@RestController
public class UserController {
/* 概念:前后端分离的项目,后端代码不走视图解析器,后端传给前端的是json数据
方法上:注解@ResponseBody指定该方法不走视图解析器,会直接返回一个String=json数据就是一个字符串
类上:注解@RestController指定该类下的所有方法都不走视图解析器
Json返回一个对象
*/
@RequestMapping("/t1")
public String json1() throws JsonProcessingException {
User user = new User(1, "张三", 20);
ObjectMapper jacksonMapper = new ObjectMapper();
String str_user = jacksonMapper.writeValueAsString(user);
//user.toString()是自己指定的String但是公司通常是允许的,通常是使用第三方工具来返回String
//str_user有中文乱码问题,springMvc可以统一配置
return str_user;
}
/**
* Json返回一个List
*/
@RequestMapping("/t2")
public String json2() throws JsonProcessingException {
User user1 = new User(1, "张三", 20);
User user2 = new User(2, "张三", 21);
User user3 = new User(3, "张三", 22);
User user4 = new User(4, "张三", 23);
List list = new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
return new ObjectMapper().writeValueAsString(list);
}
/**
* json返回一个日期格式
*/
@RequestMapping("/t3")
public String json3() throws JsonProcessingException {
//方式一:原始纯java日期转换:推荐使用
// String date = new SimpleDateFormat("yyyy-MM-dd:HH-mm-ss").format(new Date());
ObjectMapper objectMapper = new ObjectMapper();
//方式二:使用mapper来制定日期格式,先关闭时间戳表示
objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss"));
Date date = new Date();
return objectMapper.writeValueAsString(date);
}
@Test
public void DateTest1() {
//传统的java日期格式转换
String date = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss").format(new Date());
System.out.println(date);
}
}
5.3 FastJson
- 阿里巴巴官方提供的,实现Json数据的另一个工具,比JackSon Databind更方便
1 导包
com.alibaba
fastjson
1.2.62
2 编写Controller
- 比Jackson使用更方便
@RequestMapping("/t4")
public String json4() throws JsonProcessingException {
User user1 = new User(1, "张三", 20);
User user2 = new User(2, "张三", 21);
User user3 = new User(3, "张三", 22);
User user4 = new User(4, "张三", 23);
List list = new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
String jsonString = JSON.toJSONString(list);
return jsonString;
}
6 SSM整合
6.1 环境
- IDEA+Mysq5.7+Tomca5.7+Maven3.6
- 数据库
create database `ssmbuild`;
use `ssmbuild`;
CREATE TABLE `books` (
`bookId` int(10) NOT NULL AUTO_INCREMENT COMMENT '书id',
`bookName` varchar(100) NOT NULL COMMENT '书名',
`bookCounts` int(11) NOT NULL COMMENT '数量',
`detail` varchar(200) NOT NULL COMMENT '描述',
KEY `bookId` (`bookId`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
- pom.xml
4.0.0
com.ssl
ssmbuild
1.0-SNAPSHOT
junit
junit
4.12
mysql
mysql-connector-java
5.1.47
com.mchange
c3p0
0.9.5.2
javax.servlet
servlet-api
2.5
javax.servlet.jsp
jsp-api
2.2
javax.servlet
jstl
1.2
org.mybatis
mybatis
3.5.2
org.mybatis
mybatis-spring
2.0.2
org.springframework
spring-webmvc
5.2.4.RELEASE
org.springframework
spring-jdbc
5.0.5.RELEASE
org.projectlombok
lombok
1.18.12
src/main/resources
**/*.properties
**/*.xml
true
src/main/java
**/*.properties
**/*.xml
true
6.2 开发流程
- 需求分析+设计数据库+业务+传给前端页面
- 整体效果:
6.3 整合Mybatis
-
mybatis-config.xml
- 数据库连接交给Spring-dao.xml配置
# db.properties配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=false&useUnicode=true&characterEncoding=utf-8
username=root
password=123456
6.4 整合Spring
-
1 spring-dao.xml
- 数据库连接读取db.properties有bug,手动连接jdbcurl和user
- 2 spring-service.xml
-
3 application.xml
- 导入其他配置进spring主配置文件
6.5 整合SpringMVC
- 增加web项目的支持
- web.xml
springMVC
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:application.xml
1
springMVC
/
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encodingFilter
/*
15
- spring-mvc.xml
6.6 dao层
- BookMapper接口和BookMapperMapper.xml
public interface BookMapper {
//增加一本书
int addBook(Books books);
//删除一本书
int deleteBookById(@Param("bookId") int id);
//修改一本书
int updateBook(Books books);
//查询一本书根据id
Books queryBookById(@Param("bookId")int id);
//查询全部书
List queryAllBook();
Books queryBookByName(@Param("bookName") String bookName);
}
insert into ssmbuild.books(bookName, bookCounts, detail)
values (#{bookName},#{bookCounts},#{detail});
delete from ssmbuild.books where bookId = #{bookId}
update ssmbuild.books set
bookName=#{bookName},
bookCounts=#{bookCounts},
detail=#{detail}
where bookId=#{bookId};
6.7 service层
public interface BookService {
//增加一本书
int addBook(Books books);
//删除一本书
int deleteBookById(int id);
//修改一本书
int updateBook(Books books);
//查询一本书根据id
Books queryBookById(int id);
//查询全部书
List queryAllBook();
Books queryBookByName(String bookName);
}
public class BookServiceImpl implements BookService {
//注入Dao层
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
@Override
public int addBook(Books books) {
return bookMapper.addBook(books);
}
@Override
public int deleteBookById(int id) {
return bookMapper.deleteBookById(id);
}
@Override
public int updateBook(Books books) {
return bookMapper.updateBook(books);
}
@Override
public Books queryBookById(int id) {
return bookMapper.queryBookById(id);
}
@Override
public List queryAllBook() {
return bookMapper.queryAllBook();
}
@Override
public Books queryBookByName(String bookName) {
return bookMapper.queryBookByName(bookName);
}
}
6.8 controller层
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;
//查询全部的书籍,并且返回到一个书籍展示页面
@RequestMapping("/allBook")
public String list(Model model) {
List books = bookService.queryAllBook();
model.addAttribute("list", books);
return "allBook";
}
//跳转到增加书籍页面
@RequestMapping("/toAddBook")
public String toAddBook() {
return "addBook";
}
//添加书籍
@RequestMapping("/addBook")
public String addBook(Books books) {
int result = bookService.addBook(books);
if (result > 0) {
System.out.println("添加书籍成功");
}
return "redirect:/book/allBook";
}
@RequestMapping("/toUpdateBook")
public String toUpdate(int bookId, Model model) {
Books books = bookService.queryBookById(bookId);
model.addAttribute("book", books);
return "updateBook";
}
/*
没有提交事务操作,更新会失败
*/
@RequestMapping("/updateBook")
public String updateBook(Books books) {
int result = bookService.updateBook(books);
if (result > 0) {
System.out.println("修改书籍成功");
}
return "redirect:/book/allBook";
}
/*
删除书籍,回顾RestFul风格
*/
@RequestMapping("/deleteBook/{bookId}")
public String deleteBook(@PathVariable("bookId") int bookId) {
int result = bookService.deleteBookById(bookId);
if (result > 0) {
System.out.println("删除书籍成功");
}
return "redirect:/book/allBook";
}
@RequestMapping("/queryBook")
public String queryBook(String queryBookName, Model model) {
Books books = bookService.queryBookByName(queryBookName);
//复用,这样就显示一个
List list = new ArrayList<>();
list.add(books);
if (books == null) {
list= bookService.queryAllBook();
model.addAttribute("errMsg","未查任何书籍");
}
model.addAttribute("list", list);
return "allBook";
}
}
6.9 前端页面
index.xml
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
进入书籍展示页面
WEB-INF/jsp/addBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--BootStrap美化界面--%>
<%--屏幕分成12列--%>
新增书籍
<%--BootStrap官网拿"表单"数据 name属性保证pojo属性名称一致 required保证必须提交--%>
WEB-INF/jsp/allBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
书籍展示页面
<%--BootStrap美化界面--%>
WEB-INF/jsp/updateBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--BootStrap美化界面--%>
<%--屏幕分成12列--%>
修改书籍
<%--BootStrap官网拿"表单"数据 name属性保证pojo属性名称一致 required保证必须提交--%>
7 Ajax
7.1 概念
- Ajax就是一个异步无刷新请求,无需更新整个页面就异步加载一些数据,交互性更强
- 模拟异步请求
模拟Ajax异步请求
请输入地址:
7.2 使用JQ使用Ajax
1 初试Ajax
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
<%--加载动态的JQ资源--%>
<%--实现Ajax异步请求
1 绑定单击事件
2 单击事件函数使用Jq:$.post({})
--%>
用户名:
2 Ajax实现异步加载
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Ajax
姓名
年龄
性别
3 实现登录验证
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
login
用户名:
<%--span提示信息--%>
用户密码:
appliacation.xml添加json乱码问题
7.3 后端需要的前端知识
- HTML+CSS+Js(超级熟练)
-
Js必会?:
- 函数闭包?
-
DOM
- id,name.tag
- create,remove
-
BOM:浏览器对象模型
- window
- document
8 拦截器
8.1 概念
- 数据独立性:Servlet中的是过滤器,而拦截器是SpringMVC框架独有的,独享request和response
- 拦截器只会拦截访问的控制器方法,如果访问的是jsp/html/css等式不会拦截的
- 拦截器是基于AOP思想的,和AOP实现是一样的,在application.xml中配置
8.2 自定义拦截器
- 实现 HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//return true:执行下一个拦截器
System.out.println("===========处理前,这里进行拦截处理=================");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("===========处理后,通常进行日志管理=================");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("===========清洁中=================");
}
}
- applica.xml配置
8.3 登录验证判断
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
request.getRequestURL();
//URL:http://localhost:8080/springmvc_07_interceptor/user//main
System.out.println("URL:" + request.getRequestURL());
//URI:/springmvc_07_interceptor/user//main
System.out.println("URI:" + request.getRequestURI());
if (session.getAttribute("username") == null || session.getAttribute("password") == null) {
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
} else if (session.getAttribute("username").equals("admin") && session.getAttribute("password").equals("123456")) {
return true;
}
if (request.getRequestURI().contains("ogin")) {
return true;
}
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
}
@Controller
@RequestMapping("/user")
public class LoginController {
@RequestMapping("/main")
public String main() {
//沒登陸就不等進入首頁
return "main";
}
@RequestMapping("/goLogin")
public String goLogin() {
return "login";
}
@RequestMapping("/login")
public String login(String username, String password, HttpSession session, Model model) {
session.setAttribute("username", username);
session.setAttribute("password", password);
model.addAttribute("username", username);
return "main";
}
@RequestMapping("/outUser")
public String outUser(HttpSession session) {
session.removeAttribute("username");
session.removeAttribute("password");
return "main";
}
}
9 文件上传
- 前端form添加enctype="multipart/form-data",method="post"
- 后端pom导包
commons-fileupload
commons-fileupload
1.4
javax.servlet
javax.servlet-api
4.0.1
- Spring自带的文件上传,application.xml配置
@RestController
public class FileController {
@RequestMapping("/upFile")
public String upFile(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//设置文件保存路径
String path = request.getServletContext().getRealPath("/upload");
System.out.println("path:" + path);
File realPath = new File(path);
if (!realPath.exists()) {
realPath.mkdir();
}
System.out.println("上传的文件地址:" + realPath);
//CommonsMultipartFile的方法写文件,简化
file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));
return "redirect:/index.jsp";
}
}
10 文件下载
- 方式一:写方法下载
@RequestMapping(value = "/download")
public String downLoad(HttpServletResponse response, HttpServletRequest request) throws IOException {
//手动设置,要下载的图片地址
String path = request.getServletContext().getRealPath("/upload");
String fileName = "1.png";
//设置响应头
response.reset();//设置页面不缓存,清空buffer
response.setCharacterEncoding("UTF-8");
response.setContentType("multipart/form-data");//二进制传输数据
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
File file = new File(path, fileName);
//读取文件-输入流
InputStream input = new FileInputStream(file);
//写入文件-输出流
OutputStream out = response.getOutputStream();
byte[] buff = new byte[1024];
int index = 0;
while ((index = input.read(buff)) != -1) {
out.write(buff,0,index);
out.flush();
}
input.close();
out.close();
return "redirect:/index.jsp";
}
- 方式二:标签直接web下静态获取
图片下载