Spring知识点总结4 SpringMVC

说说自己对于 Spring MVC 了解?

MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。

随着 Spring 轻量级开发框架的流行,Spring 生态圈出现了 Spring MVC 框架, Spring MVC 是当前最优秀的 MVC 框架。相比于 Struts2 , Spring MVC 使用更加简单和方便,开发效率更高,并且 Spring MVC 运行速度更快。

MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring MVC 可以帮助我们进行更简洁的 Web 层的开发,并且它天生与 Spring 框架集成。Spring MVC 下我们一般把后端项目分为 Service 层(处理业务)、Dao 层(数据库操作)、Entity 层(实体类)、Controller 层(控制层,返回数据给前台页面)。

Spring MVC 的核心组件有哪些?

记住了下面这些组件,也就记住了 SpringMVC 的工作原理。

  • DispatcherServlet核心的中央处理器,负责接收请求、分发,并给予客户端响应。
  • HandlerMapping处理器映射器,根据 uri 去匹配查找能处理的 Handler,并会将请求涉及到的拦截器和 Handler一起封装。
  • HandlerAdapter处理器适配器,根据 HandlerMapping找到的 Handler,适配执行对应的 Handler
  • Handler请求处理器,处理实际请求的处理器。
  • ViewResolver视图解析器,根据 Handler返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给 DispatcherServlet响应客户端

SpringMVC 工作原理了解吗?

Spring MVC 原理

Spring知识点总结4 SpringMVC

流程说明(重要):

  1. 客户端(浏览器)发送请求, DispatcherServlet拦截请求。
  2. DispatcherServlet根据请求信息调用 HandlerMappingHandlerMapping根据 uri 去匹配查找能处理的 Handler(也就是我们平常说的 Controller控制器) ,并会将请求涉及到的拦截器和 Handler一起封装。
  3. DispatcherServlet调用 HandlerAdapter适配执行 Handler
  4. Handler完成对用户请求的处理后,会返回一个 ModelAndView对象给 DispatcherServletModelAndView顾名思义,包含了数据模型以及相应的视图的信息。 Model是返回的数据对象, View是个逻辑上的 View
  5. ViewResolver会根据逻辑 View查找实际的 View
  6. DispaterServlet把返回的 Model传给 View(视图渲染)。
  7. View返回给请求者(浏览器)

Spring MVC 的相关注解?

@Controller:在类定义处添加,将类交给IoC容器管理。

@RequtestMapping:将URL请求和业务方法映射起来,在类和方法定义上都可以添加该注解。 value属性指定URL请求的实际地址,是默认值。 method属性限制请求的方法类型,包括GET、POST、PUT、DELETE等。如果没有使用指定的请求方法请求URL,会报405 Method Not Allowed 错误。 params属性限制必须提供的参数,如果没有会报错。

@RequestParam:如果 Controller 方法的形参和 URL 参数名一致可以不添加注解,如果不一致可以使用该注解绑定。 value属性表示HTTP请求中的参数名。 required属性设置参数是否必要,默认false。 defaultValue属性指定没有给参数赋值时的默认值。

@PathVariable:Spring MVC 支持 RESTful 风格 URL,通过 @PathVariable完成请求参数与形参的绑定。

Springmvc的优点:

(1)可以支持各种视图技术,而不仅仅局限于JSP;

(2)与Spring框架集成(如IoC容器、AOP等);

(3)清晰的角色分配:前端控制器(dispatcherServlet) ,请求到处理器映射(handlerMapping),处理器适配器(HandlerAdapter),视图解析器(ViewResolver)。

(4) 支持各种请求资源的映射策略。

springMVC和struts2的区别有哪些?

(1)springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。

(2)springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

(3)Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

什么是注解

Java 注解就是代码中的一些特殊标记(元信息),用于在编译、类加载、运行时进行解析和使用,并执行相应的处理。
它本质是继承了 Annotation 的特殊接口,其具体实现类是 JDK 动态代理生成的代理类,通过反射获取注解时,返回的也是 Java 运行时生成的动态代理对象 $Proxy1。
通过代理对象调用自定义注解的方法,会最终调用 AnnotationInvocationHandler 的 invoke 方法,该方法会从 memberValues 这个Map中查询出对应的值,而 memberValues 的来源是Java常量池。

SpringMvc的控制器是不是单例模式?

是单例模式,在多线程访问的时候有线程安全问题,解决方案是在控制器里面不能写可变状态量,如果需要使用这些可变状态,可以使用ThreadLocal机制解决,为每个线程单独生成一份变量副本,独立操作,互不影响。

.当一个方法向AJAX返回特殊对象,譬如Object,List等,需要做什么处理?

  1. 在方法上加@ResponseBody注解,表示该方法的返回值不管是什么类型,都会返回JSON格式的数据。
  2. 把原来Controller类上的@Controller注解替换为@RestController注解。@RestController = @Controller + @ResponseBody,表明该Controller类所有的方法都返回JSON格式的数据(没有加@RequestMapping注解的方法除外)。
  3. 加入@ResponseBody注解就能返回JSON格式数据的原因是:SpringMVC提供的HttpMessageConverter自动转为JSON ,如果使用了Jackson或者Gson,不需要额外配置就可以自动返回JSON了,因为框架帮我们提供了对应的HttpMessageConverter ,如果使用了Alibaba的Fastjson的话,则需要自己手动提供一个相应的 HttpMessageConverter的实例。

SpringMVC四种返回值类型总结

1. ModelAndView

  1. 我们在使用SpringMVC的时候,经常返回ModelAndView类型,现在前后端分离后,后端都是返回JSON格式数据为主。
  2. 返回 ModelAndView类型,我们可以在ModelAndView对象中指定视图名称,然后也可以绑定数据,如下面代码:
@RequestMapping("/userList")
public ModelAndView getAllUser(ModelAndView mv) {
 &#xA0; &#xA0;List<user> users= userService.getAllUser();
 &#xA0; &#xA0;//&#x6DFB;&#x52A0;&#x6570;&#x636E;&#x6A21;&#x578B;&#x5230;request&#x57DF;&#x4E2D;
 &#xA0; &#xA0;mv.addObject("users", users);
 &#xA0; &#xA0;mv.setViewName("userList");//&#x6307;&#x5B9A;&#x89C6;&#x56FE;&#x540D;
 &#xA0; &#xA0;return mv;
}</user>

2.void

如果返回值为void的话,并不是真正没有返回值,而是会出现以下几种情况:

  1. 如果方法内真的没有返回值,那么SpringMVC默认把 deleteUser&#xFF08;&#x6620;&#x5C04;&#x7684;URL&#xFF09;当成视图名称来解析,如果存在该视图,就返回给客户端;如果不存在该视图,就会报视图找不到异常。
@RequestMapping("/deleteUser")
public void deleteUser() {
 &#xA0; &#xA0;//&#x5220;&#x9664;&#x64CD;&#x4F5C;
}

通过加@ResponseBody来修改默认行为,加上该注解表示返回JSON数据,这里返回空JSON数据,而不是把URL当成视图名称来解析

@RequestMapping("/deleteUser")
@ResponseBody
public void deleteUser() {
 &#xA0; &#xA0;//&#x5220;&#x9664;&#x64CD;&#x4F5C;
}
  1. 请求转发
@GetMapping("/")
public void root(HttpServletRequest req,HttpServletResponse resp) {
 &#xA0; &#xA0;req.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(req,resp);
}
  1. 重定向
@RequestMapping("/")
@ResponseBody
public void root(HttpServletResponse resp){
 &#xA0; &#xA0;resp.setStatus(302);
 &#xA0; &#xA0;resp.addHeader("Location","/WEB-INF/jsp/index.jsp");
}
@RequestMapping("/")
@ResponseBody
public void root(HttpServletResponse resp){
 &#xA0; &#xA0;resp.sendRedirect("/WEB-INF/jsp/index.jsp");
}

3. String

当方法的返回值为String的时候,也会出现下面几种情况:

  1. 逻辑视图名 返回String最常见的是逻辑视图名,这种时候一般利用默认的参数Model来传递数据
@RequestMapping("/deleteUser")
//&#x65B9;&#x6CD5;&#x8FD4;&#x56DE;JSON&#x6570;&#x636E;
@ResponseBody &#xA0;
public String deleteUser(Model model) {
 &#xA0; &#xA0;model.addAttribute("msg","&#x5220;&#x9664;&#x6210;&#x529F;");
 &#xA0; &#xA0;return "userList";
}
  1. 重定向 登录失败的时候重定向到登录页面。
@RequestParam("/login")
public String redirect(User user){
 &#xA0; &#xA0;if{
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x767B;&#x5F55;&#x6210;&#x529F;...

 &#xA0;  }else{
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x767B;&#x5F55;&#x5931;&#x8D25;&#xFF0C;&#x91CD;&#x5B9A;&#x5411;&#x5230;&#x767B;&#x5F55;&#x9875;&#x9762;
 &#xA0; &#xA0; &#xA0; &#xA0;return "redirect:tologin";
 &#xA0;  }
}
  1. 请求转发 登录失败的时候请求转发到登录页面。
@RequestParam("/login")
public String redirect(User user){
 &#xA0; &#xA0;if{
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x767B;&#x5F55;&#x6210;&#x529F;...

 &#xA0;  }else{
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x767B;&#x5F55;&#x5931;&#x8D25;&#xFF0C;&#x8F6C;&#x53D1;&#x5230;&#x767B;&#x5F55;&#x9875;&#x9762;
 &#xA0; &#xA0; &#xA0; &#xA0;return "forward:tologin";
 &#xA0;  }
}
  1. 真的返回String,相当于JSON格式的数据
@RequestMapping("/deleteUser")
@ResponseBody
public String deleteUser() {
 &#xA0; &#xA0;try{
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x5220;&#x9664;&#x6210;&#x529F;
 &#xA0; &#xA0; &#xA0; &#xA0;return "&#x5220;&#x9664;&#x6210;&#x529F;";
 &#xA0;  }catch(Exception e){
 &#xA0; &#xA0; &#xA0; &#xA0;return "&#x5220;&#x9664;&#x5931;&#x8D25;";
 &#xA0;  }
}

4.JSON

现在前后端分离的情况下,大部分后端只需要返回JSON数据即可,List 集合、Map集合,实体类等都可以返回,这些数据由 HttpMessageConverter自动转为JSON ,如果使用了Jackson或者Gson,不需要额外配置就可以自动返回JSON了,因为框架帮我们提供了对应的HttpMessageConverter ,如果使用了Alibaba的Fastjson的话,则需要自己手动提供一个相应的 HttpMessageConverter的实例,方法的返回值如下面代码:

@GetMapping("/getUser")
@ResponseBody
public User getUser() {
 &#xA0; &#xA0;User user = userService.getUser();
 &#xA0; &#xA0;return user;
}
@RequestMapping("/userList")
@ResponseBody
public List<user> getAllUser() {
 &#xA0; &#xA0;List<user> users = userService.getAllUser();
 &#xA0; &#xA0;return users;
}</user></user>

SpringMVC用什么对象从后台向前台传递数据的?

  1. 使用Map、Model和ModelMap的方式,这种方式存储的数据是在request域中
@RequestMapping("/getUser")
public String getUser(Map<string,object> map,Model model,ModelMap modelMap){
 &#xA0; &#xA0;//1.&#x653E;&#x5728;map&#x91CC; &#xA0;
 &#xA0; &#xA0;map.put("name", "xq");
 &#xA0; &#xA0;//2.&#x653E;&#x5728;model&#x91CC;&#xFF0C;&#x4E00;&#x822C;&#x662F;&#x4F7F;&#x7528;&#x8FD9;&#x4E2A;
 &#xA0; &#xA0;model.addAttribute("habbit", "Play");
 &#xA0; &#xA0;//3.&#x653E;&#x5728;modelMap&#x4E2D;
 &#xA0; &#xA0;modelMap.addAttribute("city", "gd");
 &#xA0; &#xA0;modelMap.put("gender", "male");
 &#xA0; &#xA0;return "userDetail";
}</string,object>
  1. 使用request的方式
@RequestMapping("/getUser")
public String getUser(Map<string,object> map,Model model,ModelMap modelMap,HttpServletRequest request){
 &#xA0; &#xA0;//&#x653E;&#x5728;request&#x91CC; &#xA0;
 &#xA0; &#xA0;request.setAttribute("user", userService.getUser());
 &#xA0; &#xA0;return "userDetail";
}</string,object>
  1. 使用ModelAndView
@RequestMapping("/getUser") &#xA0;
public ModelAndView getUser(ModelAndView modelAndView) {
 &#xA0; &#xA0;mav.addObject("user", userService.getUser()); &#xA0;
 &#xA0; &#xA0;mav.setViewName("userDetail"); &#xA0;
 &#xA0; &#xA0;return modelAndView
} &#xA0;

SpringMVC怎么样设定重定向和转发的?

(1)转发:在返回值前面加”forward:”,例如”forward:user.check?name=method”
(2)重定向:在返回值前面加”redirect:”,例如”redirect:http://www.xxxx.com

Original: https://www.cnblogs.com/spring-ioc/p/16574168.html
Author: 你问人生何
Title: Spring知识点总结4 SpringMVC

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/574229/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Java基础

    环境 并非所有的计算机都可以开发java程序,java程序的开发与运行需要专门的环境。 因为java语言的程序是运行在java所专有的系统中。 要运行java程序我们需要在操作系统…

    Java 2023年6月7日
    0138
  • Redis Zset实现统计模块

    背景 公司有一个配置中心系统,使用MySQL存储了大量的配置,但现在不清楚哪些配置正在线上使用,哪些已经废弃了,所以需要实现一个统计模块,实现以下两个功能: 查看总体配置的数量以及…

    Java 2023年6月5日
    0122
  • java学习之jdbc

    在一些web开发或者是数据存储的时候,肯定会使用到数据库来进行数据存储。而在Java里面需要调用JDBC来对数据库进行操作。每次用jdbc很麻烦,就可以采用一些连接池来解决这个问题…

    Java 2023年6月13日
    075
  • 并发编程 1

    jmm java 内存模型,这个东西目前先不跟jvm模型对应起来。 存在一个工作内存、驻内存的概念 线程间通信 cas 原子性 有序性 可见性 结合一个两个线程之间交互的例子 pu…

    Java 2023年6月9日
    094
  • 一、全新安装搭建redis主从集群

    前言· 这里分为三篇文章来写我是如何重新搭建redis主从集群和哨兵集群的及原本服务器上有单redis如何通过升级脚本来实现redis集群。(redis结构:主-从(备)-从(备)…

    Java 2023年6月5日
    092
  • Netty

    学习本章需要先知道IO多路复用,不清楚的请移步:IO多路复用 网络通信中,阻塞IO两大阻塞的地方:socket链接阻塞,等待读取文件阻塞。 本地文件io就只有一个等待文件阻塞 一….

    Java 2023年6月7日
    0102
  • 搭建简单JavaWeb项目

    参考:(17条消息) 手把手搭建一个完整的javaweb项目(适合新手)_心歌技术的博客-CSDN博客_javaweb项目完整案例 补充项目结构的细节,进行了一点修改,修改为学生信…

    Java 2023年6月9日
    098
  • java实现微信公众号的模板消息推送

    文章目录前言一、什么是模板消息二、获取模板ID三、获取access_token四、发送消息五、完整的代码总结前言最近做项目时需要用到公众号的模板消息,所以在这里记录分享一下实现过程…

    Java 2023年5月29日
    074
  • 干货分享之Spring框架源码解析01-(xml配置解析)

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正! 环境: spring5.X + idea Spring 是一个工厂,是一个负责对象的创建…

    Java 2023年6月5日
    097
  • 2021/1/28

    #include <bits/stdc++.h> using namespace std; string a,b; int maxl[1001][1001]; int …

    Java 2023年6月5日
    079
  • 2.69分钟完成BERT训练!新发CANN 5.0加持

    摘要:快,着实有点快。 现在,经典模型BERT只需2.69分钟、ResNet只需16秒。 啪的一下,就能完成训练! 快,着实有点快。 现在,经典模型BERT只需 2.69分钟、Re…

    Java 2023年6月15日
    074
  • JAVAWEB开发之JSTL标签库的使用、 自己定义EL函数、自己定义标签(带属性的、带标签体的)

    JSTL JSTL简单介绍: JSTL的全称:JSP Standard Tag Library,JSP标准标签库 JSTL的作用: 提供给Java Web开发者一个标准通用的标签函…

    Java 2023年5月29日
    078
  • SpringBoot框架学习教程,初学者用7天学完springboot直接去面试了

    如果你跟我一样,刚巧也是springboot小白,正要学springboot,建议看完下一段话: Spring Boot 是由 Pivotal 团队提供用来简化 Spring 的搭…

    Java 2023年6月7日
    065
  • JAVA_AesCBC例子

    java;gutter:true; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; im…

    Java 2023年5月29日
    077
  • java实现单链表的创建、增、删、改、查

    文章目录 单链表的创建、增、删、改、查 * 1、增加一个节点 2、删除一个节点 3、修改某一个节点 5、遍历单链表 单链表的创建、增、删、改、查 双向链表的增删改查:https:/…

    Java 2023年6月13日
    093
  • 解决mybatisplus分页查询不起作用

    需要增加以下配置: @Configuration(proxyBeanMethods = false) public class MybatisAutoConfiguration {…

    Java 2023年5月30日
    067
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球