Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
一、流程
-
用户发送请求到前端控制器DispatcherServlet(调度servlet,底层就是servlet)
-
DispatcherServlet收到请求调用HandlerMapping处理器映射器
-
处理器映射器根据请求url找到具体的处理器(对应代码中的Controller),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet
-
DispatcherServlet通过HandlerAdapter(找到与之controller对应的类)处理器适配器调用处理器,执行处理器(Controller,也叫后端控制器)。
-
Controller执行完成返回ModelAndView给HandlerAdapter -
HandlerAdapter将Controller
执行结果ModelAndView给DispatcherServlet -
DispatcherServlet将ModelAndView传给ViewReslover视图解析器 -
ViewReslover解析后返回具体给DispatcherServlet具体的View
-
DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
-
DispatcherServlet响应用户
总结:
首先有请求来,经过tomcat服务器,进入里面的servlet进行处理。这里是DispatcherServlet,用来调度servlet
不同的请求具有不同的处理器来处理,DispatcherServlet接收到请求调用HandlerMapping处理器映射器
处理器根据请求的url找到具体的处理器,生成处理的对象,返回给DispatcherServlet
DispatcherServlet通过HandlerAdapter处理器适配器调用处理器,执行处理器,处理处理器对象
处理完之后,返回处理后的结果ModelAndView
可以看出来,只有DispatcherServlet有处理的功能
调用HandlerMapping处理器映射器找到处理器的对象
转交通过HandlerAdapter处理,执行对应的处理器的对象
从上面可以看出,DispatcherServlet有接收请求,响应结果,转发等作用。有了DispatcherServlet之后,可以减少组件之间的耦合度。
SpringMVC的优点:
-
可以支持各种视图技术,而不仅仅局限于JSP;
-
与Spring框架集成(如IoC容器、AOP等);
-
清晰的角色分配:前端控制器(dispatcherServlet) , 请求到处理器映射(handlerMapping), 处理器适配器(HandlerAdapter), 视图解析器(ViewResolver)。
SpringMVC的主要组件
1. 前端控制器 DispatcherServlet(不需要程序员开发)
作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
2. 处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的URL来查找Handler
3. 处理器适配器HandlerAdapter
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
4. 处理器Handler(需要程序员开发)
5. 视图解析器 ViewResolver(不需要程序员开发)
作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)
6. 视图View(需要程序员开发jsp)
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法地形参,可以设计为单例或多例(建议单例),
二、SpringMVC笔记
MVC框架要做的事情?
- 将url映射到java类或java类的方法 (写的hello,映射到helloServlet)
- 封装用户提交的数据 ()
- 处理请求--调用相关的业务处理--封装响应数据
- 将响应的数据进行渲染、jsp/html等表示层数据
2.1 复习servlet
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方法");
//session就像map一样的进行保存数据
//意思是获得session,设置属性级对应的key value
}
if(method.equals("delete")){
req.getSession().setAttribute("msg","执行了delete方法");
}
//2、调用业务层
//3、视图转发或重定向
req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req,resp);
resp.sendRedirect("/WEB-INF/jsp/hello.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//这样的作用实现复用
doGet(req,resp);
}
}
回顾
请求转发\ (正常使用的话请求转发使用的较多)
用户先通过浏览器访问 oneServlet,但是 oneServlet 不能解决用户的问题。于是 oneServlet 将 request 对象和 response 对象传递给 TwoServlet,然后 twoServlet 去处理用户的请求。
其实请求转发就相当于你去找刘备借钱,刘备一摸兜没钱,但是刘备这人挺仗义,他就带着你去找曹操借钱,最后你从曹操那里借到了钱。
不会放弃带着你,拿着你的对象\
格式为:
req.getRequestDispatcher("URL对应的文件的路径").forward(req.resp);
重定向
则是响应另一个界面,response.SendRedirect(“”),转达到另一个页面
你去找刘备借钱,刘备一摸兜没钱,然你去找小红借钱,重新响应到另外一个界面,不携带之前的对象
格式为:
resp.senfRedict("URL对应的文件的路径");
2、将servlet注册到web.xml中,让URL路径和资源进行映射
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servler-mapping>
通过媒介servlet,将servlet的class和url进行映射,去执行servlet.class里面的代码,进行跳转.jsp文件
补充servlet的其他配置,配置欢迎页,和session的过期时间
<session>
<session-timeout>15</session-timeout>
</session>
<welcome-file-list>
<welcome-file>index.jsp<welcome-file>
</welcome-file-list>
2.2 SpringMVC初学
Spring:可以将SpringMVC的bean注入到容器中\
- Spring的核心
- DispathweServlet
- 处理器的映射器
- 处理器的适配器
- 视图解析器 (Thymeleaf) controller返回的modeleAndView
补英语:prefix 前缀 suffix后缀
2.3 使用注解进行开发
@Controller
@RequestMapping("/hello")
public class HelloController {
//真实访问地址 : 项目名/hello/h1
@RequestMapping("/h1")
public String hello(Model model) {
//封装数据
//向模型中添加属性msg与值,可以在JSP页面中取出并渲
model.addAttribute("msg","HelloSpringMVCAnnotation");
//返回视图
//web-inf/jsp/hello.jsp
return "hello"; //会被视图解析器处理
}
}
@Controller是为了让Spring IOC容器初始化时自动扫描到;
@RequestMapping是为了映射请求路径,这里因为类与方法上都有映射所以访问时应该 是/HelloController/h1;
方法中声明Model类型的参数是为了把Action中的数据带到视图中;
方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/hello.js
后面在前端页面,使用${msg}进行获取相关加入视图中的信息
- 重要:之前是Controller执行完之后需要需要返回视图,这里使用Model model,进行封装数据,返回给ModelAndView
2.4 RestFul和控制器
控制器Controller
- 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
- 控制器负责解析用户的请求并将其转换为一个模型。
- 在Spring MVC中一个控制器类可以包含多个方法
- 在Spring MVC中,对于Controller的配置方式有很多种
注解的使用
@Controller
@ResquestMapping (一般放在类上,方法与专门的注解)
- @RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
方法级别的注解变体有如下几个:组合注解
@GetMapping 一般GetMapping使用的较多一点
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
路径的变量
@PathVariable
//@PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中
//这里URL上的占位符和形参相同,相同时可以将@PathVariable("name")的name去掉
@RequestMapping("/getUserById/{name}")
public User getUser(@PathVariable("name") String name){
return userService.selectUser(name);
}
@RequestMapping("/getUserById/{name}")
public User getUser(@PathVariable("name") String userName){
return userService.selectUser(userName);
}
@Controller
public class RestFulController {
//映射访问路径
@RequestMapping("/commit/{p1}/{p2}")
public String index(@PathVariable int p1, @PathVariable int p2, Model model){
int result = p1+p2;
//Spring MVC会自动实例化一个Model对象用于向视图中传值
model.addAttribute("msg", "结果:"+result);
//返回视图位置
return "test";
}
}
http://localhost:8080/commit/1/2
//则跳转到页面返回的是3
RestFul风格
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get
http://127.0.0.1/item/queryItem.action?id=1 查询,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST
使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!
http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
2.5 JSON
前后端分离的时代:
- 后端部署后端,提供接口
数据交换的格式JSON - 采用完全独立于编程语言的文本格式来存储和表示数据。
- 前端独立部署,负责渲染后端的数据
在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。看看他的要求和语法格式:
- 对象表示为键值对,数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
2.6 Ajax
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
2.7拦截器
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
过滤器与拦截器的区别:拦截器是AOP思想的具体应用。
过滤器
servlet规范中的一部分,任何java web工程都可以使用
在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器
拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果是登陆页面则放行
System.out.println("uri: " + request.getRequestURI());
if (request.getRequestURI().contains("login")) {
return true;
}
HttpSession session = request.getSession();
// 如果用户已登陆也放行
if(session.getAttribute("userLoginInfo") != null) {
return true;
}
// 用户没有登陆跳转到登陆页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
}
- 实现了HandlerInterceptor接口,里面有preHandle方法