【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤
作者:mmseoamin日期:2023-12-20

【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第1张

目录

引言

一、常用注解

1.1.@RequestMapping

1.2.@RequestParam

1.3.@RequestBody

1.4.@RequestHeader

1.5.@PathVariable

二、参数传递

2.1.基础类型+String

2.2.复杂类型

2.3.@RequestParam

2.4.@PathVariable

2.5.@RequestBody

2.6.@RequestHeader

三、返回值

3.1.void

3.2.String

3.3.String+Model

3.4.ModelAndView

四、页面跳转

4.1.转发forward

4.2.重定向redirect


引言

欢迎阅读Spring MVC入门必读!在这篇文章中,我们将探索这个令人兴奋的框架,它为您提供了一种高效、灵活且易于维护的方式来构建Web应用程序。通过使用Spring MVC,您将享受到以下好处:简洁的代码、强大的功能和与Spring生态系统的无缝集成。

在本指南中,我们将深入探讨Spring MVC的关键步骤,包括注解的使用、参数传递、返回值处理以及页面跳转。这些技术将帮助您更好地理解Spring MVC的核心概念,并使您能够更轻松地应对实际开发中的挑战。

无论您是初学者还是有经验的开发者,本篇文章都将为您提供有价值的见解和实践建议。让我们一起踏上这个充满乐趣和挑战的旅程吧!

一、常用注解

1.1.@RequestMapping

作用:用于映射请求路径与处理请求的方法之间的关系,可以用在类或方法上 。

  • 标注在方法上

    用于方法上,表示在类的父路径下追加方法上注解中的地址将会访问到该方法

    @Controller
    public class HelloController {
    ​
        @RequestMapping("/requestTest")
        public String requestTest(){
            return "success";
        }
    }

    此时请求映射的请求路径为:

    http://localhost:8080/springmvc01/requestTest

    springmvc01表示项目名

    • 标注在类和方法上

      用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

      注意:当你在类上添加RequestMapping注解后,如果要请求映射,就意味着请求要先映射到标注类的位置,然后再映射到该类的方法上

      @Controller
      @RequestMapping("/hello")
      public class HelloController {
      ​
          @RequestMapping("/requestTest")
          public String requestTest(){
              return "success";
          }
      }

      此时请求映射的请求路径为:

      http://localhost:8080/springmvc01/hello/requestTest

      springmvc01表示项目名

      • 参数列表

        参数说明
        value@RequestMapping 的 value 属性必须设值; @RequestMapping 的 value 属性是通过当前请求的请求地址来匹配请求; 从源码中可以看到value属性是一个字符串类型的数组,因此说明可以将多个请求映射到一个方法上,只需要给 value 来指定一个包含多个路径的数组。
        method@RequestMapping的method属性是通过当前请求的请求方式来匹配请求; 浏览器向服务器发送请求,请求方式有很多GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACE。可以使用 method 属性来约束请求方式。
        headers@RequestMapping的headers属性是通过当前请求的请求头信息来匹配请求; @RequestMapping的headers属性是一个字符串类型的数组,可以通过下面四种表达是来设置匹配关系 例如: “header”:要求请求映射的请求必须为包含 header的请求头信息 “!header”:要求请求映射的请求必须为不包含 header的请求头信息 “header=value”:要求请求映射的请求必须为包含 header的请求头信息,并且header的值必须为value “header!=value”:要求请求映射的请求必须为包含 header的请求头信息,并且header的值必须不是value
        params@RequestMapping的params属性是通过当前请求的请求参数来匹配请求; @RequestMapping的params属性是一个字符串类型的数组,可以通过下面四种表达是来设置匹配关系 例如: “param”:要求请求映射的请求必须为包含 param的请求参数 “!param”:要求请求映射的请求是不能包含param的请求参数 “param=value”:要求请求映射的请求必须包含 param 的请求参数,且 param 参数的值必须为 value “param!=value”: 要求请求映射的请求是必须包含 param 的请求参数,其值不能为 value。

        示例一:@RequestMapping的params属性

        @RequestMapping(value = "/test",params = "username")
        public String test(){
            return "success";
        }

        注意:我们设置了params属性,就意味着该请求映射的请求必须包含username才能够请求成功。

        示例二:@RequestMapping的headers属性

        @RequestMapping(value = "/test",headers = "Host = localhost:8081")
        public String test(){
            return "success";
        }

        注意:如果当前请求不满足headers属性,此时页面就会显示404错误,即资源未找

        小贴士:

        @GetMapping:处理get方式请求的映射

        @PostMapping:处理post方式请求的映射

        @PutMapping:处理put方式请求的映射

        @DeleteMapping:处理delete方式请求的映射

        @GetMapping就相当于@RequestMapping(method=RequestMethod.GET),它会将get映射到特定的方法上。

        1.2.@RequestParam

        作用:用于获取请求参数的值,并将其绑定到方法的参数上。

        • 参数列表
          参数说明
          value请求中传入参数的名称,如果不设置后台接口的value值,则会默认为该变量名。
          required该参数是否为必传项。默认是true,表示请求中一定要传入对应的参数,否则会报404错误,如果设置为false时,当请求中没有此参数,将会默认为null,而对于基本数据类型的变量,则必须有值,这时会抛出空指针异常。如果允许空值,则接口中变量需要使用包装类来声明。
          defaultValue参数的默认值,如果请求中没有同名的参数时,该变量默认为此值。注意默认值可以使用SpEL表达式,如"#{systemProperties[‘java.vm.version’]}"

          示例:

          @RequestMapping("/queryBooks")
          public List queryBooks(
              @RequestParam(required = false,defaultValue = "0",value="page") int page,
              @RequestParam(required = false,defaultValue = "10",value = "rows") int rows){
                  return bookService.queryBooks(page,rows);
          }

          1.3.@RequestBody

          作用:用于将请求体中的JSON数据绑定到方法的参数上。

          GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。

          总结来说就是

          • 一个请求:只有一个@RequestBody;

          • 一个请求:可以有多个@RequestParam。

            @RequestMapping("/hello")
            public String toHello1(@RequestBody Book book){
                log.info(">>>> 使用@RequestBody传递JSON格式的参数:{}", JSON.toJSONString(book));
                return "index";
            }

            @RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为)实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。

            1.4.@RequestHeader

            作用:用于获取请求头中指定的参数值。

            如果想要获取所有的请求头信息,可以使用 Map、MultiValueMap、HttpHeaders 这三个 Map 中的任何一个封装所有请求头的 name 和 value。

            • 参数列表
              参数说明
              namename 和 value 互为别名,当只有一个参数时,可以省略 value,直接("xxx") 就可以了
              valuename 和 value 互为别名,当只有一个参数时,可以省略 value,直接("xxx") 就可以了
              required默认情况下,如果请求头中缺少了指定的 name,那么将会报错。 如果没有添加required = false,当请求头中没有这个zking请求头时就会报错。
              defaultValue如果请求头中缺少了指定的 name ,那么会报错,可以使用 defaultValue 这个属性指定默认值,就可以避免报错 ;如果请求头缺少指定 name ,该属性设置的值将会作为默认值,如果该属性不设置值,它有自己的默认值 DEFAULT_NONE

              示例:

              @GetMapping("/headParams")
              public Map userInfo(
                  @RequestHeader(value = "zking",defaultValue = "hello zking") String username,
                  // 将请求头中 name=Accept-Encoding 赋值给形参 encoding
                  @RequestHeader("Accept-Encoding") String encoding,
                  // 将请求头中 name=Host 赋值给形参 host
                  @RequestHeader("Host") String host,
                  // 将所有请求头的 name 和 value 封装到 Map 集合 headsMap 中
                  @RequestHeader Map headsMap) {
                      Map map = new HashMap();
                      map.put("username",username);
                      map.put("Accept-Encoding",encoding);
                      map.put("Host",host);
                      map.put("headsMap",headsMap);
              ​
                      return map;
              }

              由于请求头中不存在 name=zking 这个信息,所以如果只用 value=zking 会抛出异常。

              解决方案:

              1、required 的默认值为 true ,也就是请求头中没有 name=zking 会报错,将其值改为 false,即没有该头信息也不报错

              @RequestHeader(value = "zking",required = "false") String username

              2、不修改 required=true 这个默认值,当头信息中不包含 name=zking ,给它一个默认值 hello zking

              @RequestHeader(value = "zking",defaultValue = "hello zking") String username

              1.5.@PathVariable

              作用:用于获取URL路径中的参数值,并将其绑定到方法的参数上。

              即当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上。

              //@PathVariable可以用来映射URL中的占位符到目标方法的参数中
              @RequestMapping("/testPathVariable/{id}")
              public String testPathVariable(@PathVariable("id") Integer id)
              {
                  System.out.println("testPathVariable:"+id);
                  return SUCCESS;
              }

              二、参数传递

              在讲解之前,先向大家介绍一下本次需要用到的依赖slf4j

              SLF4J是一个简单的日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。 

              SLF4J的作用是提供了一种抽象层,使得开发人员可以使用任何他们喜欢的日志框架,而不必关心它们之间的差异。这样可以使开发人员更专注于编写代码,而不是处理日志记录的细节。  

              在实际运用中,SLF4J通常用于将日志记录从应用程序代码中分离出来,并将其委托给专门的日志记录器。这样可以使得应用程序更易于维护和扩展,并且可以提高性能和可靠性。  

              pom.xml 

              2.9.1
              3.2.0
              1.7.13
              //-------------------------------------------------
              
              
              
              
              
              	org.slf4j
              	slf4j-api
              	${slf4j.version}
              
              
              	org.slf4j
              	jcl-over-slf4j
              	${slf4j.version}
              	runtime
              
              
              
              	org.apache.logging.log4j
              	log4j-api
              	${log4j2.version}
              
              
              	org.apache.logging.log4j
              	log4j-core
              	${log4j2.version}
              
              
              
              	org.apache.logging.log4j
              	log4j-slf4j-impl
              	${log4j2.version}
              
              
              
              	org.apache.logging.log4j
              	log4j-web
              	${log4j2.version}
              	runtime
              
              
              
              	com.lmax
              	disruptor
              	${log4j2.disruptor.version}
              

              2.1.基础类型+String

              Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                  @RequestMapping("/list")
                  public String list(String name,Integer age){
                      log.info("基础类型+String➡name:{},age:{}",name,age);
                      return "hello";
                  }
              }

              此时请求映射的请求路径为:

              http://localhost:8080/Spring_MyBatis/csdn/list?name=彭于晏&age=18

               控制台打印结果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第2张

              2.2.复杂类型

              Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                  @RequestMapping("/list01")
                  public String list01(Book book, HttpServletRequest req){
                      log.info("复杂类型:bid:{},bname:{}",
                              req.getParameter("bid"),
                              req.getParameter("bname"));
                      log.info("book:{}",book.toString());
                      return "hello";
                  }
              }
              

              此时请求映射的请求路径为:

              http://localhost:8080/Spring_MyBatis/csdn/list01?bid=01&bname=斗破苍穹

               控制台打印结果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第3张

              2.3.@RequestParam

              Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                  @RequestMapping("/list02")
                  public String list02(
                          @RequestParam(required = false) String name,
                          @RequestParam Integer age) {
                      log.info("@RequestParam注解传递参数name:{},age:{}",name,age);
                      return "hello";
                  }
              }

              此时请求映射的请求路径为:

              http://localhost:8080/Spring_MyBatis/csdn/list02?name=彭于晏&age=18

               控制台打印结果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第4张

              如果我们少传递一个age结果会是怎么样的呢 ?

              http://localhost:8080/Spring_MyBatis/csdn/list02?name=彭于晏

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第5张

                结论:被@RequestParam注解的参数required默认为true表示请求中一定要传入对应的参数,否则会报404错误如果设置为false时,当请求中没有此参数,将会默认为null,而对于基本数据类型的变量,则必须有值,这时会抛出空指针异常。如果允许空值,则接口中变量需要使用包装类来声明。

              2.4.@PathVariable

              Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                @RequestMapping("/list03/{id}")
                  public String list03(@PathVariable("id") Integer id) {
                      log.info("@PathVariable:  id{}",id);
                      return "hello";
                  }
              }

              此时请求映射的请求路径为:

              http://localhost:8080/Spring_MyBatis/csdn/list03/7

               控制台打印结果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第6张

              2.5.@RequestBody

              讲解@RequestBody之前,将大家推荐postman或者apipost/eolink等工具发送请求数据。

              这些工具可以帮助您模拟发送请求和接收响应,以便更好地理解@RequestBody参数的含义和使用方法。

               Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
               @RequestMapping("/list04")
                  public String list04(Map map) {
                      log.info("没有注解:  Map:{}",map);
                      return "hello";
                  }
                  @RequestMapping("/list05")
                  public String list05(@RequestBody Map map) {
                      log.info("@ResponseBody:  Map:{}",map);
                      return "hello";
                  }
              }

              此时请求映射的请求路径为:

              http://localhost:8080/Spring_MyBatis/csdn/list04

               eolink测试工具[没有注解]:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第7张

                控制台打印结果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第8张

                eolink测试工具[有注解]:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第9张

                控制台打印结果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第10张  

              2.6.@RequestHeader

              Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                @RequestMapping("/list06")
                  public String list06(@RequestHeader String jwt) {
                      log.info("@RequestHeader:  jwt:{}",jwt);
                      return "hello";
                  }
              }

              此时请求映射的请求路径为:

              http://localhost:8080/Spring_MyBatis/csdn/list06

               控制台打印结果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第11张

              三、返回值

              为了方便模拟效果,借助ResponseUtil工具类,ResponseUtil类提供了一种方便的方式来将对象以文本或JSON格式写入HTTP响应流中,以便在Web应用程序中向客户端返回数据。

              ResponseUtil

              package com.csdn.xw.util;
              import com.fasterxml.jackson.databind.ObjectMapper;
              import javax.servlet.http.HttpServletResponse;
              import java.io.PrintWriter;
              public class ResponseUtil {
              	public static void write(HttpServletResponse response,Object o)throws Exception{
              		response.setContentType("text/html;charset=utf-8");
              		PrintWriter out=response.getWriter();
              		out.println(o.toString());
              		out.flush();
              		out.close();
              	}
              	public static void writeJson(HttpServletResponse response,Object o)throws Exception{
              		ObjectMapper om = new ObjectMapper();
              //		om.writeValueAsString(o)代表了json串
              		write(response, om.writeValueAsString(o));
              	}
              }
              

              pom.xml依赖

              
                    com.fasterxml.jackson.core
                    jackson-databind
                    2.12.4 
                  

              3.1.void

              处理器对请求处理后,无需跳转到其它任何资源,此时可以让处理器方法返回 void。

              Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                 @RequestMapping("/return01")
                  public void return01(HttpServletResponse resp){
                  Map map=new HashMap<>();
                  map.put("code",200);
                  map.put("msg","成功添加。。。");
                      try {
                          ResponseUtil.writeJson(resp,map);
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  }
              }

              网页效果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第12张

              3.2.String

              通过http://localhost:8080/Spring_MyBatis/csdn/return02访问请求方法,并经过视图解析器跳转指定页面。

              Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                 @RequestMapping("/return02")
                  public String return02( ){
                     return "hello";
                  }
              }

              网页效果:

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第13张

              3.3.String+Model

              通过http://localhost:8080/Spring_MyBatis/csdn/return03访问请求方法,并经过视图解析器跳转指定页面。

              Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                 @RequestMapping("/return03")
                  public String return03(Model Model,HttpServletRequest req){
                      Model.addAttribute("name","Java方文山");
                      req.setAttribute("age",18);
                      return "hello";
                  }
              }

              JSP页面:

              <%@ page contentType="text/html;charset=UTF-8" language="java" %>
              
              
                  Title
              
              
              💖Hello Spring MVC💖
              
              用户名:${name} 年龄:${age}

              网页效果:【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第14张

              3.4.ModelAndView

               Controller编写:

              @Slf4j
              @Controller
              @RequestMapping("/csdn")
              public class IndexController {
                 @RequestMapping("/return04")
                  public ModelAndView return04(){
                     ModelAndView mv=new ModelAndView();
                     mv.addObject("name","湖南彭于晏");
                      mv.addObject("age",18);
                     mv.setViewName("hello");
                      return mv;
                  }
              }

              JSP页面:

              <%@ page contentType="text/html;charset=UTF-8" language="java" %>
              
              
                  Title
              
              
              💖Hello Spring MVC💖
              
              用户名:${name} 年龄:${age}

              网页效果:【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第15张

              四、页面跳转

              转发(forward:path)和重定向(redirect:path)这两种跳转方式将会绕开视图解析器的前缀和后缀;还有就是如果是在同一controller中则不用使用"/"从根目录开始,而如果是在不同的controller则一定要从根目录开始。

              4.1.转发forward

              • 当前类

                Controller编写:

                //  转发到当前类
                    @RequestMapping("/forward01")
                    public String forward01(){
                        return "forward:return02";
                    }
                @RequestMapping("/return02")
                    public String return02( ){
                        return "hello";
                    }

                JSP页面:

                <%@ page contentType="text/html;charset=UTF-8" language="java" %>
                
                
                    Title
                
                
                💖Hello Spring MVC💖
                
                用户名:${name} 年龄:${age}

                网页效果:

                【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第16张

                • 其他类

                  Controller编写:

                  //  转发到其他类
                      @RequestMapping("/forward02")
                      public String forward02(){
                          return "forward:/hello/requestTest";
                      }
                  
                  @Controller
                  @RequestMapping("/hello")
                  public class hello {
                      @RequestMapping("/requestTest")
                      public String Hello(){
                          return "text";
                      }
                  }

                  JSP页面:

                  <%@ page contentType="text/html;charset=UTF-8" language="java" %>
                  
                  
                      Title
                  
                  
                  你好我是其他类跳转过来的
                  
                  

                  网页效果:

                  【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第17张

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第18张

              4.2.重定向redirect

              •  当前类

                Controller编写:

                 //  重定向到当前类
                    @RequestMapping("/redirect01")
                    public String redirect01(){
                        return "redirect:return02";
                    }
                @RequestMapping("/return02")
                    public String return02( ){
                        return "hello";
                    }

                JSP页面:

                <%@ page contentType="text/html;charset=UTF-8" language="java" %>
                
                
                    Title
                
                
                💖Hello Spring MVC💖
                
                用户名:${name} 年龄:${age}

                网页效果:

                 【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第19张 

                • 其他类

                   Controller编写: 

                   //  重定向到其他类
                      @RequestMapping("/redirect02")
                      public String redirect02(){
                          return "redirect:/hello/requestTest";
                      }
                  
                  @Controller
                  @RequestMapping("/hello")
                  public class hello {
                      @RequestMapping("/requestTest")
                      public String Hello(){
                          return "text";
                      }
                  }

                  JSP页面:

                  <%@ page contentType="text/html;charset=UTF-8" language="java" %>
                  
                  
                      Title
                  
                  
                  你好我是其他类跳转过来的
                  
                  

                  网页效果:

                   【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第20张  

              到这里我的分享就结束了,欢迎到评论区探讨交流!!

              💖如果觉得有用的话还请点个赞吧 💖

              【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤,第21张