首页 > 其他分享 >Spring MVC学习笔记(1/2)

Spring MVC学习笔记(1/2)

时间:2022-11-16 21:56:19浏览次数:42  
标签:return String Spring 视图 MVC 笔记 请求 public RequestMapping

Spring MVC

MVC框架

image-20221113210005188

Spring MVC常用组件

image-20221113203426305

Spring MVC项目

  • 浏览器发送一个请求,若请求地址与 web.xml 中配置的前端控制器(DispatcherServlet)的 url-pattern 相匹配,则该请求就会被前端控制器 DispatcherServlet 拦截;
  • 前端控制器(DispatcherServlet )会读取 SpringMVC 的核心配置文件,通过组件扫描获取到所有的控制器(Contorller);
  • 将请求信息和控制器中所有控制器方法标识的 @RequestMapping 注解的 value、method 等属性值进行匹配。若匹配成功,则将请求交给对应的 @RequestMapping 注解所标识的控制器方法处理;
  • 处理请求的方法会返回一个字符串类型的视图名称,该视图名称会被 Spring MVC 配置文件中配置的视图解析器(ViewResolver)解析真正的视图(View)对象,最终展示给客户端。
package net.biancheng.c.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
    @RequestMapping("/")
    public String sayHello() {
        //视图名,视图为:视图前缀+index+视图后缀,即 /WEB-INF/template/index.html
        return "index";
    }
    @RequestMapping("/login")
    public String welcome() {
        //视图名,视图为:视图前缀+login+视图后缀,即 /WEB-INF/template/login.html
        return "login";
    }
    @RequestMapping("/register")
    public String success() {
        //视图名,视图为:视图前缀+register+视图后缀,即 /WEB-INF/template/register.html
        return "register";
    }
}

SpringMVC执行流程

image-20221113210321765

@RequestMapping注解

  • 使用方式

    • 修饰方法:要访问该方法,请求路径必须与这个value值相同
    • 修饰类:要访问类中的任意方法,都要带上这个父路径
  • 属性

    • value属性:用于设置请求地址

    • name属性:用于注释

    • method属性:method 属性的取值是一个 RequestMethod 类型的数组,表示一个控制器方法支持多种方式的请求,常用的请求方式有 GET、POST、DELETE、PUT 等。如果一个控制器方法没有设置 @RequestMapping 注解的 method 属性,则说明该控制器方法支持全部请求类型,可以处理所有类型的请求。

    • params属性:取值是一个字符串类型的数组,用于指定请求中的参数,只有当请求中携带了符合条件的参数时,控制器方法才会对该请求进行处理

      image-20221113211532567
      @RequestMapping(value = "/testParam", params = {"name=z5onk0", "url=http://www.baidu.com"})
      @ResponseBody
      public String testParam() {
          return "success";
      }
      //以上代码表示,只有当请求中同时携带 name 和 url 两个请求参数,且参数值必须分别为 “z5onk0” 和“http://www.baidu.com”时,控制器方法 testParam() 才会对该请求进行处理 。
      
    • headers属性:取值是一个字符串类型的数组,用于设置请求中请求头信息,只有当请求中携带指定的请求头信息时,控制器方法才会处理该请求

Spring MVC获取请求参数

  • 通过HttpServletRequest

    @RequestMapping("/getRequestParam")
        public String requestParam(HttpServletRequest request) {
        String name = request.getParameter("name");
        String url = request.getParameter("url");
        System.out.println("name:" + name);
        System.out.println("url:" + url);
        return "index";
    }
    
  • 通过形参获取:在 Controller 的控制器方法中设置与请求参数同名的形参,以获取请求中携带的参数。需要注意这种方式是无视参数的数据类型的,我们可以在控制器方法中使用 String 字符串类型的形参接收所有的请求参数;并且不适用于参数过多的情况

    @RequestMapping("/test")
    public String test(String name, String language) {
        System.out.println("a:" + a);
        System.out.println("b:" + b);
        return "success";
    }
    
  • 通过实体类对象获取(推荐):在 Controller 控制器方法的形参中设置一个实体类形参,如果请求参数的参数名与实体类中的属性名一致,那么 Spring MVC 会自动将请求参数封装到该实体类对象中

    • 在net.biancheng.c.entity 包下,创建一个名为 User 的实体类

      package net.biancheng.c.entity;
      public class User {
          private String UserId;
          private String UserName;
          private Integer age;
          public String getUserId() {
              return UserId;
          }
          public void setUserId(String userId) {
              UserId = userId;
          }
          public String getUserName() {
              return UserName;
          }
          public void setUserName(String userName) {
              UserName = userName;
          }
          @Override
          public String toString() {
              return "User{" +
                      "UserId='" + UserId + '\'' +
                      ", UserName='" + UserName + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
    • 创建一个名为 UserController 的 Controller 类

      package net.biancheng.c.controller;
      import net.biancheng.c.entity.User;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      @Controller
      public class UserController {
          /**
           * 通过实体类获取请求参数
           *
           * @param user
           * @return
           */
          @RequestMapping("/getUser")
          public String getUser(User user) {
              System.out.println("userId:" + user.getUserId());
              System.out.println("userName:" + user.getUserName());
              System.out.println("password:" + user.getPassword());
              return "success";
          }
      }
      

Spring MVC域对象共享

  • Controller 在接收到 Model 层返回的模型数据后,下一步就是将模型数据通过域对象共享的方式传递给 View 视图进行渲染,最终返回给客户端展示

  • 域对象是服务器在内存上创建的一块存储空间,主要用不同动态资源之间的数据传递和数据共享。在 Spring MVC 中,常用的域对象有 request 域对象、session 域对象、application 域对象等

  • 方式:

    • 使用 Servlet API 向 request 域对象中共享数据

      @RequestMapping("/testServletAPI")
      public String testServletAPI(HttpServletRequest request) {
          request.setAttribute("testScope", "hello,Servet API");
          return "success";
      }
      
    • 使用 ModelAndView 向 request 域对象中共享数据

      • model 负责数据共享,而 view 则主要用于设置视图,实现页面的跳转

        image-20221114200112232
        @RequestMapping("/testModelAndView")
        public ModelAndView testModelAndView() {
             /**
             * ModelAndView有Model和View的功能
             * Model主要用于向请求域共享数据
             * View主要用于设置视图,实现页面跳转
             */
            ModelAndView mav = new ModelAndView();
            //向请求域共享数据
            mav.addObject("testScope", "hello,ModelAndView");
            //设置视图,实现页面跳转
            mav.setViewName("success");
            return mav;
        }
        
    • 使用 Map 向 request 域对象中共享数据

      @RequestMapping("/testMap")
      public String testMap(Map<String, Object> map) {
          map.put("testScope", "hello,Map");
          return "success";
      }
      
  • 实例

    • 定义user和product实体类;定义userDao和productDao类,将多个user和product放入字典和列表中,并暴露方法;定义userService和productService,对Dao暴露的方法进行封装

    • 定义LoginController

      @Controller
      public class LoginController {
          @Autowired
          private UserService userService;
          @RequestMapping("/user")
          public String sayHello() {
              return "user";
          }
          @RequestMapping("/login")
          public String login(User user, HttpServletRequest request) {
              User user2 = userService.getUserByUserName(user.getUserName());
              if (user2 != null && user2.getPassword().equals(user.getPassword())) {
                  HttpSession session = request.getSession();
                  session.setAttribute("loginUser", user2);
                  return "redirect:/getProductList";
              }
              request.setAttribute("msg", "账号或密码错误!");
              return "user";
          }
      }
      
    • 定义ProductController

      @Controller
      public class ProductController {
          @Autowired
          private ProductService productService;
          @RequestMapping("/getProductList")
          public ModelAndView getProductList() {
              ModelAndView modelAndView = new ModelAndView();
              modelAndView.setViewName("productList");
              List<Product> productList = productService.getProductList();
              modelAndView.addObject(productList);
              return modelAndView;
          }
          @RequestMapping("/getProduct")
          public String getProduct(Integer productId, Model model) {
              Product productById = productService.getProductById(productId);
              model.addAttribute("product", productById);
              return "product";
          }
      }
      

Spring MVC视图和视图解析器

  • 无论控制器方法的返回值是哪种类型,Spring MVC 内部最终都会将它们封装成一个 ModelAndView 对象
  • 仅仅是一个 String 类型的逻辑视图名(View Name)而已,例如“success”、“index”等。这种情况下,Spring MVC 就需要借助 ViewResolver(视图解析器)将 ModelAndView 对象中逻辑视图名解析为真正的 View 视图对象,然后才能响应给客户端展示
  • 需要在视图解析器中配置视图前缀和视图后缀,用来转化控制器返回的字符串

Spring MVC请求转发与重定向

  • 请求转发

    • 当控制器方法中所设置的逻辑视图名称以“forward:”为前缀时,该逻辑视图名称不会被 Spring MVC 配置的视图解析器解析,而是会将前缀“forward:”去掉,以剩余部分作为最终路径通过转发的方式实现跳转

    • 通过String类型的返回值实现转发

      @RequestMapping("/testDispatcher")
      public String testDispatcher() {
          return "forward:/login";
      }
      //即路径“/testDispatcher”请求最终会被转发到 “/login”上进行处理
      
    • 通过 ModelAndView 实现转发

      @RequestMapping("/testDispatcher")
      public ModelAndView testDispatcher() {
          ModelAndView modelAndView = new ModelAndView();
          //设置逻辑视图名
          modelAndView.setViewName("forward:/login");
          return modelAndView;
      }
      
  • 重定向

    • 当控制器方法中所设置的视图名称以“redirect:”为前缀时,该视图名称不会被 Spring MVC 配置的视图解析器解析,而是会将前缀“redirect:”去掉,以剩余部分作为最终路径通过重定向的方式实现跳转
    • 通过String类型的返回值实现转发
    • 通过 ModelAndView 实现转发
    • 重定向和转发的区别:转发不会改变导航栏里的url

Spring MVC实现RESTful

  • 通过 @RequestMapping +@PathVariable 注解的方式,来实现 RESTful 风格的请求

  • 通过@RequestMapping 注解的路径设置

    @RequestMapping("/testRest/{id}/{username}", method = RequestMethod.DELETE)
    
  • 通过 @PathVariable 注解绑定参数

    @RequestMapping("/testRest/{id}/{username}")
    public String testRest(@PathVariable("id") String id, @PathVariable("username")
            String username) {
        System.out.println("id:" + id + ",username:" + username);
        return "success";
    }
    

Spring MVC类型转化器

  • 作用是在控制器方法对请求进行处理前,先获取到请求发送过来的参数,并将其转换为控制器方法指定的数据类型,然后再将转换后的参数值传递给控制器方法的形参,这样后台的控制器方法就可以正确地获取请求中携带的参数了

  • Spring MVC 对于基本类型(例如 int、long、float、double、boolean 以及 char 等)已经做好了基本类型转换

  • 对于一些较为复杂类型的转换,例如 String 转换 Date 类型,以及开发人员自定义格式的数据的转换等,就需要我们根据自身的需求开发自定义类型转换器来转换

    /**
    * 自定义日期转换器
    */
    public class MyDateConverter implements Converter<String, Date> {
        private String datePatten = "yyyy-MM-dd";
        @Override
        public Date convert(String source) {
            System.out.println("前端页面传递过来的时间为:" + source);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePatten);
            try {
                return simpleDateFormat.parse(source);
            } catch (ParseException e) {
                throw new IllegalArgumentException("无效的日期格式,请使用正确的日期格式" + datePatten);
            }
        }
    }
    //还需要将其注册到Spring MVC的核心配置文件中,才能生效
    

Spring MVC格式化器

  • Spring 提供了一个 Formatter 接口, T 表示目标数据类型,它被称为格式化转换器;特殊数据都要经过一定的格式化处理才能够正常使用

  • 同Converter的区别:Formatter 的源类型必须是 String 类型,而 Converter 的源类型可以是任意数据类型

  • 定义格式化器需要重写parse和print方法

  • 日期格式化

    • DateTimeFormat 注解可对 java.util.Date、java.util.Calendar、java.long.Long 等时间类型的数据进行标注

    • 控制器中:

      @DateTimeFormat(pattern = "yyyy-MM-dd")
      private Date date;
      
    • 模板中:

      <tr>
          <td>日期:</td>
          <td th:text="${#dates.format(market.getDate(),'yyyy-MM-dd')}"></td>
      </tr>
      
  • 数值格式化

    • @NumberFormat 注解可以用来格式化任何数字基本类型

    • 注解为货币类型

      @NumberFormat(style = NumberFormat.Style.CURRENCY)
      private BigDecimal money;
      

JSON数据交互

  • JSON转换注解

    image-20221115100808169
  • 实例

    • controller

      /**
      * 查看或回显商品信息,get:查看商品信息  update:为修改页回显的商品信息
      */
      @ResponseBody
      @RequestMapping("/product/{productId}")
      public Product getProduct(@PathVariable("productId") String productId) {
          Product product = productDao.getProductById(productId);
          return product;
      }
      /**
      * 新增商品
      *
      * @param product
      * @return
      */
      @ResponseBody
      @RequestMapping(value = "/product", method = RequestMethod.POST)
      public Product addProduct(@RequestBody Product product) {
          productDao.addProduct(product);
          return product;
      }
      
    • product_list.html

      • 主页面添加表格用来展示商品信息

        <tbody th:id="tb">
        
      • 通过ajax返回商品信息

        $(function () {
            $.ajax({
                //请求路径
                url: "http://localhost:8080/springmvc-json-demo/getProductList1",
                //请求类型
                type: "get",
                //定义发送请求的数据格式为JSON字符串
                contentType: "application/json;charset=utf-8",
                //定义回调响应的数据格式为JSON字符串,该属性可以省略
                dataType: "json",
                //成功响应的结果
                success: function (data) {
                    if (data != null) {
                        var html = "";
                        for (var i = 0; i < data.length; i++) {
                            var product = data[i];
                            html += "<tr>" +
                                "<td>" + product.productId + "</td>" +
                                "<td>" + product.productName + "</td>" +
                                "<td>" + product.price + "</td>" +
                                "<td>" + product.stock + "</td>" +
                                "<td><button  onclick='lookPage(" + product.productId + ")'>查看商品</button>" +
                                "<button  onclick='editPage(" + product.productId + ")';>修改商品</button>" +
                                "<button  onclick='deletePro(" + product.productId + ")';>删除商品</button></td>" +
                                "</tr>"
                        }
                        $("#tb").html(html);
                    }
                }
            });
        })
        
      • 首先通过css将增删查改的div块设置为不可见

        <style type="text/css">
            #addWindow, #editWindow {
                display: none;
                position: absolute;
                top: 25%;
                left: 25%;
                width: 30%;
                height: 40%;
                padding: 20px;
                border: 3px solid #ccc;
                background-color: white;
                z-index: 2;
                overflow: auto;
            }
        </style>
        
      • 每个商品信息栏后有增删查改,通过click方法,将addWindow/editWindow设置为可见

        $(document).ready(function () {
            //点击新增商品,弹出新增商品弹窗
            $("#btn").click(function () {
                $("#addWindow").slideDown(300);	 //slideDown方法以滑动方式显示被选元素
                $("#backGround").show();
            });
        
      • addWindow用来展示增加商品的页面

        <div id="addWindow">
            <label id="x" style="position: absolute;top:2px;left: 95%;font-size: 25px;">x</label>
            <h4>新增商品</h4>
            <form th:action="@{/product}" method="post">
                <table id="table-box" style="margin: auto">
                    <tr>
                        <td>商品 ID:</td>
                        <td><input type="text" id="productId" name="productId" required></td>
                    </tr>
                    <tr>
                        <td>商品名称:</td>
                        <td><input type="text" id="productName" name="productName" required></td>
                    </tr>
                    <tr>
                        <td colspan="2" align="center"><input id="addPro" type="submit" value="新增商品">
                            <input type="reset" id="reset" value="重置">
                        </td>
                    </tr>
                </table>
            </form>
        </div>
        <div id="backGround"></div>
        
      • 填完商品信息,点击提交后,通过jquery click调用add方法,向后端请求数据,返回的数据append到商品详情页

        $("#addPro").click(function () {
            add();
            $("#addWindow").slideUp(300);
            $("#backGround").hide();
            $("#reset").trigger("click")
        });
        
        $.ajax({
            //请求路径
            url: "http://localhost:8080/springmvc-json-demo/product",
            //请求类型
            type: "post",
            data: JSON.stringify({
                productId: productId,
                productName: productName,
            }), //定义发送请求的数据格式为JSON字符串
            contentType: "application/json;charset=utf-8",
            //定义回调响应的数据格式为JSON字符串,该属性可以省略
            dataType: "json",
            //成功响应的结果
            success: function (data) {
                if (data != null) {
                    var product = data;
                    var html = "<tr>" +
                        "<td>" + product.productId + "</td>" +
                        "<td>" + product.productName + "</td>" +
                        "<td><button onclick='lookPage(" + product.productId + ")'>查看商品</a>" +
                        "</tr>";
                    $("#tb").append(html);   
                }
            }
        

标签:return,String,Spring,视图,MVC,笔记,请求,public,RequestMapping
From: https://www.cnblogs.com/z5onk0/p/16897643.html

相关文章

  • Git笔记
    Git笔记git命令行操作设置信息设置用户名和邮箱gitconfig--globaluser.name"ch"gitconfig--globaluser.email"[email protected]"workspace提交代码至repository......
  • SpringBoot整合Spring Data JPA
    目录1SpringDataJPA1.1简介1.1.1JPA1.1.2SpringDataJPA1.2配置文件1.3操作使用JPA1.3.1实体类相关1.3.2Dao层1.3.2.1基本示例1.3.2.2@Query注解1.3.2.3SQL......
  • Javascript(笔记39) - ES6特性 - 集合Set
    SETES6 提供了新的数据结构set(集合)。集合类似于数组,但成员的值都是唯一的,集合实现iterator 接口,所以可以使用“扩展运算符”和“for...of”进行遍历,集合的属性和方法......
  • 肖sir__Java中spring boot
    1.1springboot介绍什么是SpringBoot?SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来......
  • 第一章 进入SpringBoot世界
    第一章进入SpringBoot世界1.1什么是SpringBootSpringBoot的设计初衷是解决Spring各版本配置工作过于繁重的问题,简化初始搭建流程,降低开发难度,使开发人员只需要专注应用......
  • Spring注解开发
    1、使用注解需要导入的依赖1、1在application.xml文件中加入该约束xmlns:context=http://www.springframework.org/schema/contexthttp://www.springframew......
  • Spring--注解开发定义Bean
    注解开发先看一看之前的bean的做法:所谓注解开发,当然就要用到注解啊,就是在BookDao接口的实现类里面进行注解的定义如图所示:而在.xml文件里面,就需要进行这样一个操作:......
  • MAUI / MAUI Blazor 环境路径测试笔记
    测试代码Tools服务类多平台实现MAUIpublicstringCacheDirectory()=>FileSystem.CacheDirectory;publicstringAppDataDirectory()=>FileSystem.AppDataDirecto......
  • 管道、环境变量与常用命令-acw学习笔记
    管道、环境变量与常用命令管道文件重定向将标准在输出重定向到某一个文件管道也是一个重定向,和文件重定向有所不同可以将前一个命令的标准输出stdout重定向到下一个命......
  • 12.Seata:Spring Cloud Alibaba分布式事务组件(非常详细)
    随着业务的不断发展,单体架构已经无法满足我们的需求,分布式微服务架构逐渐成为大型互联网平台的首选,但所有使用分布式微服务架构的应用都必须面临一个十分棘手的问题,那就是......