Spring Boot 2.0 读书笔记_03:MVC 上

版权声明:未经博主本人同意,请勿私自转发分享。 https://blog.csdn.net/Nerver_77/article/details/84567315

2. MVC 上

写在开头,关于MVC,Model - View - Controller模式

  • Model(模型) - 代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器。
  • View(视图) - 代表模型包含的数据的可视化。
  • Controller(控制器) - 作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。

这里有几个很容易混淆的概念:模式、框架、架构、平台,它们之间究竟是什么关联?

  • 模式(设计模式):包括本章讲述的MVC模式,均属于设计模式。设计模式说白了就是:告诉你针对特定问题如何组织类、对象和接口之间的关系,是前人总结的经验。
  • 框架:框架是为了解决特定问题而存在的,其它诸如模板框架、缓存框架等。
  • 架构:从大的层面来说,架构关注的是技术整合、扩展、可维护性。
  • 平台:类似框架,但又结合的架构的考虑,它是更高层面上的“框架”,准确说是一种应用。它是针对企业用户,为解决企业业务需要而形成的产品。

概念比较:设计模式 < 框架 < 架构 < 平台

从复用角度讲:设计模式是代码级复用、框架是模块级复用、架构是系统级复用、平台是企业应用级复用。

在项目中使用最多的就是Spring MVC框架了,Spring Boot已经将这一MVC框架进行了自动集成并实现了自动配置,可谓一步到位。

  • Web项目目录结构及包结构规范

    • 项目目录结构
      关于web项目,常规情况下采用maven项目构建工具的打包工具生成。有了Spring Boot这一集成框架,在IDEA中通过Spring Initializr可进行快速SpringBoot项目的搭建。
      项目根目录:src/main
      • java
        • packageName
          • conf
          • controller
          • entity
          • service
            • impl
          • dao
          • Application.java (启动器类)
      • resources
        • static (静态资源默认)
          • css
          • js
        • template (页面模板默认)
        • application.properties (配置文件)
    • 包结构规范:上述项目目录结构为标准
    • Spring Boot默认扫描规则是:自动扫描启动器类的同包或者其子包的下的注解。
  • URL映射到方法

    • @RequestMapping
      • 用于类上的@RequestMapping注解用来标注请求路径
      • 用于方法上的@RequestMapping注解用来进一步映射特定的URL到具体的处理方法
    • @RequestMapping 的属性
      • value :请求的URL路径,支持URL模板、正则表达式
      • method:HTTP请求方法 GET、POST、PUT等
      • consumes:允许的媒体类型| consumes = “application/json” 对应HTTP请求的Content-type
      • produces:响应的媒体类型| produces = “application/json” 对应HTTP请求的Accept字段
      • params:请求的参数,params = “action=update”
      • headers:请求HTTP头的值,headers = “myHeader=myValue”
    • URL 路径匹配
      • 属性value用于匹配URL映射,value支持简单的表达式来匹配
        例如:@RequestMapping(value = “/get/user.json”)
      • Ant路径表达式
        • Ant 用符号 " * " 来表示匹配任意字符,用 " ** " 来表示统配任意路径,用 " ? " 来匹配单个字符。
    例子 说明
    /user/*.html 匹配 /user/1.html、/user/2.html等
    /**/1.html 匹配 /1.html、/user/1.html、/user/add/1.html等
    /user/?.html 匹配 /user/1.html,不匹配 /user/11.html
    • 匹配优先级:如果一个请求有多个 @RequestMapping 能够匹配

      • 有通配符的低于没有通配符的,比如 /user/add.json 比 /user/*.json 优先匹配。
      • 有 “**” 通配符的低于有 “*” 通配符的。
      • 其他URL映射:通过外部配置文件可以进行参数获取
        @Value("${paramName}")
        private String name; // 将paramName映射到成员变量name属性
        +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        @Value("#{ }") SpEL表达式
        通常用来获取bean的属性,或者调用bean的某个方法,也可以表示常量
    • HTTP method 匹配

      • @RequestMapping 提供 method 属性来映射HTTP的请求方法。
      • 通常对于Web应用,GET和POST是经常使用的method,对于REST接口,则会采用PUT、DELETE等用来从语义上进一步区分操作。
      • Spring 提供简化后的 @RequestMapping ,提供了新的注解来表示 HTTP 方法。如:
        • @GetMapping
        • @PostMapping
        • @PutMapping
        • @DeleteMapping
        • @PatchMapping
    • consumes 和 produces

      • 属性 consumes 表示请求的HTTP头的Content-type媒体类型与consumes的value匹配才能调用此方法

          @GetMapping(value = "/consumes/test.json", consumes = "application/json")
          @ResponseBody
          public User forJson() {
          	return userService.getUserById(1l);
          }
        

        这里映射指定请求的媒体类型是 application/json 。因此,此方法接收一个如下AJAX请求:

          $.ajax({
          	type: "get",
          	url: "/consumes/test.json",
          	contentType: "application/json",
          	...
          });
        
      • 属性 produces 对应HTTP请求的Accept字段,只有匹配成功才能进行方法调用。

          @GetMapping(value = "/user/{userId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
        

        将通常浏览器都会把 Accept 设置为 *.* ,因此通过浏览器直接访问 “/user/1” ,浏览器总是返回对应信息,并通过 @ResponseBody 转换成JSON格式返回。

    • params 和 headers
      不同于Servlet规范,在方法中通过 HttpServletRequest 获取请求的URL、HTTP头这些信息再进行处理。Spring在方法签名处提供了很多匹配方式,能进一步规范方法调用,提高代码可阅读性。

        @GetMapping(value = "/update.json", headers = "action=update") // params 同理
      
  • 方法参数

    • @PathVariable

      • 用于从请求URL中获取参数,并映射到方法参数中

          @GetMapping(path = "/{userId}.json", produces = "application/json")
          @ResponseBody
          public User getUserById(@PathVariable Long userId) {
          	return userService.getUserById(userId);
          }
        

        符号 {} 中的变量名与方法参数名字对应,若不想对应可以使用:@PathVariable(“userId”) Long id

    • Model & ModelAndView

      • Model(结构类似Map),可以向视图中添加需要的变量
      • Model对象主要方法:
        • Model addAttribute(String attributeName, Object attributeValue):向模型中添加一个变量,参数签名列表前者指明变量名称,可以在随后的视图中引用。后者代表变量。
        • Model addAttribute(Object attributeValue):向模型中添加一个变量,变量的名字就是类名首字母小写后专为的Java变量。
        • Model addAllAttributes(Map attributes):添加多个变量,若变量存在,则覆盖。
        • Model mergeAttributes(Map attributes):添加多个变量,若变量存在,则忽略。
        • Boolean containsAttribute(String attributeName):判断是否存在变量。
    • 如何使用:ModelAndView对象类似Model,但额外提供了一个视图名称的配置。

        // Model model
        model.addAttribute("userInfo", user);
      
        // ModelAndView view
        view.addObject("userInfo", user);
        view.setViewName("/userInfo.html");
        return view
      
    • JavaBean 接收HTTP参数 @RequestParam

      • 通过 @RequestParam 限定HTTP参数

        • name:指明HTTP参数名称

        • required:布尔类型,声明此参数是否必须有,如果该参数没有,抛出400错误

        • defaultValue:字符类型,如果HTTP参数没有提供,可以指定一个默认字符串

            String getUser(@RequestParam(name = "name", required = false, defaultValue = "zhangsan")
            String name){...}
          
      • 接收一个参数对象:HTTP参数名字对应POJO属性名

          @GetMapping("/getUser")
          @ResponseBody
          public String getUser(User user){...} 
        
    • @RequestBody 接收JSON

      • 方法参数使用 @RequestBody 指定参数类型为JSON数据,且映射的是一个实体POJO类。

      • Spring Boot默认使用Jackson来处理反序列化工作。

          @PostMapping("/save.json")
          @ResponseBody
          public String saveUser(@RequestBody User user){...}
        
      • 注意,和JavaBean接收HTTP参数(对象)区分开,接收JSON数据是字符串,采用@RequestBody进行字符串向对象的映射对应

    • MultipartFile:处理文件上传

      • 案例代码

          @PostMapping("/form")
          @ResponseBody
          public String handleFormUpload(@RequestParam("name") String name, 
          		@RequestParam("file") MultipartFile file) throws IOException {
          	if (!file.isEmpty()) {
          		String fileName = file.getOriginalFilename();
          		InputStream ins = file.getInputStream();
          		
          		// 处理上传内容
          		return "success";
          	}
          	return "failure";
          }
        
      • MultipartFile相关方法

    方法名 说明
    getOriginalFilename 获取上传文件名称
    getBytes 获取上传文件内容,转为字节数组
    getInputStream 获取一个InputStream
    isEmpty 文件上传内容为空,或者没有文件上传
    getSize 上传文件大小
    transferTo(File dest) 保存上传文件到目标文件系统
    • 多文件上传:使用MultipartFile数组类来接收多个文件上传

       	@RequestParam("file") MultipartFile[] files
      
    • 上传文件参数限制:通过配置文件 application.properties 进行配置

  • @ModelAttribute

    • 该注解通常作用在Controller的某个方法上,此方法会首先被调用,并将结果作为Model的属性。

        	@ModelAttribute
        	public void findUserById(@PathVariable Long id, Model model) {
        		model.addAttribute("user", userService.getUserById(id));
        	}
      
        	@GetMapping(path = "/{id}/get.json")
        	@ResponseBody
        	public String getUser(Model model) {
        		System.out.println(model.containsAttribute("user"));
        		return "success";
        	}
      
  • @InitBinder

    • Spring框架通过WebDataBinder 类实现HTTP参数向JavaBean对象的绑定
    • 可以通过@InitBinder声明方法,进行绑定对象的特性拓展

猜你喜欢

转载自blog.csdn.net/Nerver_77/article/details/84567315
今日推荐