SpringMVC

it2025-08-12  6

初识SpringMVC

Servlet的缺点

1、通常情况下,一个Servlet类只负责处理一个请求,若项目中有成百上千个请求需要处理,就需要有成百上千个Servlet类,这样会使得项目中Servlet类的个数暴增;

2、在Servlet3.0版本之前,每一个Servlet都需要在web.xml文件中至少做八行配置信息,配置内容多且繁琐。当Servlet特别多时,web.xml配置量太多,不利于团队开发;

3、当通过客户端提交参数到服务器,通过Servlet进行接收时,无论数据本身是什么格式,在Servlet中一律按照字符串进行接收,后期需要进行类型转换,复杂类型还需要特殊处理,特别麻烦!

String value = request.getParameter(String name);

4、servlet具有容器依赖性,必须放在服务器中运行,不利于单元测试;

SpringMVC简介

Springmvc是spring框架的一个模块,spring和springmvc无需中间整合层整合

Springmvc是一个基于mvc的web框架

SpringMVC五大组件

前端控制器(DispatcherServlet)处理器映射器(HandlerMapping)处理器适配器(HandlerAdapter)视图解析器(ViewReslover)视图渲染(View)

SpringMVC执行原理

提示:DispatcherServlet的作用:接收请求,调用其它组件处理请求,响应结果,相当于转发器、中央处理器,是整个流程控制的中心

用户发送请求 至 前端控制器(DispatcherServlet);

前端控制器(DispatcherServlet)收到请求后调用处理器映射器(HandlerMapping),处理器映射器(HandlerMapping)找到具体的Controller(可以根据xml配置、注解进行查找),并将Controller返回给DispatcherServlet;

前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)。处理器适配器经过适配调用具体的Controller;(Controller–> service --> Dao --> 数据库) Controller执行完成后返回ModelAndView,处理器适配器(HandlerAdapter)将controller执行的结果(ModelAndView)返回给前端控制器(DispatcherServlet);

提示:Model(模型数据,即Controller处理的结果,Map) View(逻辑视图名,即负责展示结果的JSP页面的名字)

.前端控制器(DispatcherServlet)将执行的结果(ModelAndView)传给视图解析器(ViewReslover) 视图解析器(ViewReslover)根据View(逻辑视图名)解析后返回具体JSP页面

前端控制器(DispatcherServlet)根据Model对View进行渲染(即将模型数据填充至视图中);(默认会存到request域中) 前端控制器(DispatcherServlet)将填充了数据的网页响应给用户。

其中整个过程中需要开发人员编写的部分有Controller、Service、Dao、View;

SpringMVC执行详解

在SpringMVC框架启动之初,程序会对 处理器映射器(HandlerMapping)的进行实例化,其中处理器映射器(HandlerMapping)中会有一个map的结构类型.其中map中的key存储的是你要拦截请求路径,value存储的是 你要具体要执行的请求方法. 所以在SpringMVC框架启动之初, 处理器映射器(HandlerMapping)会把所有请求的注解,和他标识的相关方法进行统一的记录.如果有用户发来请求,首先会被前端控制器(DispatcherServlet所拦截,前端控制器(DispatcherServlet)收到请求后调用处理器映射器(HandlerMapping),通过相关路径匹配,找到具体的Controller(可以根据xml配),并将Controller返回给DispatcherServlet;前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)。处理器适配器根据你标识的注解,调用相对应的handler处理器,由这个handler处理器来做具体的调用.Controller;(Controller–>service --> Dao --> 数据库) 最后将controller执行的结果(ModelAndView)对象返回给前端控制器(DispatcherServlet);前端控制器(DispatcherServlet)将执行的结果(ModelAndView)传给视图解析器(ViewReslover) 视图解析器(ViewReslover)根据View(逻辑视图名)解析后返回具体JSP页面前端控制器(DispatcherServlet)根据Model对View进行渲染(即将模型数据填充至视图中); 前端控制器(DispatcherServlet)将填充了数据的网页响应给用户。

SpringMVC拦截器

工作原理

Spring MVC中的拦截器基于回调机制,可以在目标方法执行之前,先进行业务检测,满足条件则放行,不满足条件则进行拦截,拦截器原理分析如下图所示:

SpringMVC拦截器工作原理 HandlerInterceptor

案例

HandlerInterceptor 拦截器

@Component //spring容器管理对象 public class UserInterceptor implements HandlerInterceptor { @Autowired private JedisCluster jedisCluster; //Spring版本升级 4 必须实现所有的方法 spring 5 只需要重写指定的方法即可. /** * 需求: 拦截/cart开头的所有的请求进行拦截.,并且校验用户是否登录..... * 拦截器选择: preHandler * 如何判断用户是否登录: 1.检查cookie信息 2.检查Redis中是否有记录. * true : 请求应该放行 * false: 请求应该拦截 则配合重定向的语法实现页面跳转到登录页面 使得程序流转起来 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //1.判断用户是否登录 检查cookie是否有值 String ticket = CookieUtil.getCookieValue(request,"JT_TICKET"); //2.校验ticket if(!StringUtils.isEmpty(ticket)){ //3.判断redis中是否有值. if(jedisCluster.exists(ticket)){ //4.动态获取json信息 String userJSON = jedisCluster.get(ticket); User user = ObjectMapperUtil.toObj(userJSON,User.class); request.setAttribute("JT_USER",user); return true; } } response.sendRedirect("/user/login.html"); return false; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { //销毁数据 request.removeAttribute("JT_USER"); } }

WebMvcConfigurer— springmvc 配置类

@Configuration public class MvcConfigurer implements WebMvcConfigurer{ //添加拦截器 @Autowired private UserInterceptor userInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userInterceptor).addPathPatterns("/cart/**","/order/**"); } }

各种拦截器Filer

SpringMVC基于Servlet进行封装的框架

关于SpringMVC参数提交问题说明

1 简单参数传参问题

1.页面url标识

2.Controller中的方法

@RequestMapping("/xxx") public void xxx(String name,int age){ }

2 使用对象方法接收参数

1.页面url标识

2.Controller中的方法

@RequestMapping("/xxx") public void xxx(User user){ } public class User{ //pojo类 private Integer name; private String age; }

3 使用对象的引用为参数赋值

难点: 属性的重名提交问题… 解决思路: 可以采用对象引用的方式为属性赋值.

<input name="name" value="二郎神" /> <input name="age" value="3000" /> <input name="dog.name" value="哮天犬" /> <input name="dog.age" value="8000" />

Controller中的方法

@RequestMapping("/xxx") public void xxx(User user){ } public class Dog{ private String name; private Integer age; } public class User{ private String name; private Integer age; private Dog dog; }

不同注解的含义

@RequestMapping("/xxx") 页面url路径@GetMapping("/xxx") 页面get请求 才会拦截@PostMapping("/xxx") 页面post请求 才会拦截

Spring MVC 接收参数的几个注解

@RequestParam 键值对参数,只要前端参数name属性,和后端接收名字的一致,新版本Springboot项目中.注解可省略.

@PathVariable 请求路径参数 ,运用restfun风格{module} 注解不可省略

@RequestBody 完整接收post请求协议的内容,转成pojo集合

springmvc响应数据

Model的使用

当请求发起访问Controller中的方法时,可以通过参数声明,在方法内使用Model。

@RequestMapping("/doorList") public String doorList(Model model){ }

Model对象实际上是一个Map集合,例如:往model中添加一个属性

model.addAttribute(String name, Object value);

其中,addAttribute方法会将属性保存到request域中,再通过转发将属性数据带到相应的JSP中,通过${}取出并显示。

案例,往Model中添加属性

@RequestMapping("/testModel") public String testModel(Model model){ /* 往Model添加属性 */ model.addAttribute("name", "小雨"); model.addAttribute("age", 20); return "home"; } <body> <h1>hello springmvc~~~</h1> ${ name } <br/> ${ age } </body>

实际代码

controller

@RequestMapping("/{itemid}") public String findItemById(@PathVariable Long itemid, Model model){ Item item= dubboItemService.findItemById( itemid); ItemDesc itemDesc= dubboItemService.findItemDescById(itemid); model.addAttribute("item", item); model.addAttribute("itemDesc",itemDesc); return "item"; }

item.jsp

转发(forward)和重定向(redirect)

实现转发(forward)

在request对象的学习中,通过request对象可以实现请求转发(即资源的跳转)。同样的,springmvc也提供了请求转发的方式,具体实现如下:

@RequestMapping("testForward") public String testForward(){ System.out.println("测试请求转发(forward)..."); return "forward:hello"; }

转发是一次请求,一次响应;转发后地址栏地址没有发生变化(还是访问testForward的地址);转发前后的request和response对象也是同一个。

实现重定向(redirect)

在response对象的学习中,通过response对象可以实现请求重定向(即资源的跳转)。

同样的,springmvc也提供了请求重定向的方式,具体实现如下:

@RequestMapping("testRedirect") public String testRedirect(){ System.out.println("测试请求重定向(redirect)..."); return "redirect:hello"; }

重定向是两次请求,两次响应;重定向后地址栏地址发生了变化(变为转发后的地址);并且在重定向前后,request和response对象不是同一个。
最新回复(0)