SpringMVC 框架中 Controller 控制器的参数接收方式详解

SpringMVC 框架中 Controller 控制器的参数接收和数据传递

在基于 SpringMVC 构建的 Web 应用程序中,Controller 扮演着处理 HTTP 请求的关键角色。而在实际应用中,HTTP 请求无论是 GET 请求还是 POST 请求,通常都会携带各种参数,这些参数对于服务器理解和处理请求至关重要。SpringMVC 为我们提供了多种灵活的方式来接收这些参数,本文将详细介绍其中最为常用的三种方式。

Controller 控制器的参数接收方式详解

一、HttpServletRequest 接收

1. 原理

HttpServletRequest对象是 Servlet 规范中的核心对象之一,它包含了客户端请求的所有信息,包括请求参数。通过HttpServletRequest的getParameter方法,我们可以根据参数名获取对应的参数值。

2. 代码示例

假设我们有一个简单的 HTML 表单,用于提交用户的姓名和年龄:

DOCTYPE html>
<html>
<head>
    <title>表单提交示例title>
head>
<body>
    <form action="/userInfo" method="post">
        <label for="name">姓名:label>
        <input type="text" id="name" name="name" required><br>
        <label for="age">年龄:label>
        <input type="number" id="age" name="age" required><br>
        <input type="submit" value="提交">
    form>
body>
html>

对应的 Controller 代码如下:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@Controller
public class UserController {

    @RequestMapping("/userInfo")
    @ResponseBody
    public String getUserInfo(HttpServletRequest request) {
        String name = request.getParameter("name");
        String ageStr = request.getParameter("age");
        int age = Integer.parseInt(ageStr);
        return "姓名:" + name + ",年龄:" + age;
    }
}
3. 优缺点
  • 优点

  • 这种方式非常直观,对于熟悉 Servlet 规范的开发者来说容易理解和上手。

  • 可以获取到请求中的所有信息,不仅仅是参数,还包括请求头、请求方式等,灵活性较高。

  • 缺点

  • 代码较为繁琐,需要手动从HttpServletRequest对象中提取参数,并且需要进行类型转换,容易出错。

  • 代码的可读性和维护性较差,特别是在处理大量参数时,代码会显得冗长且混乱。

二、方法形参接收

1. 原理

这种方式是直接把HTTP请求中的参数写在控制类相应方法的形参中,通过@RequestParam注解指定接收的请求参数名。

2. 代码示例

还是以上述的 HTML 表单为例,Controller 代码可以简化为:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    @RequestMapping("/userInfo")
    @ResponseBody
    public String getUserInfo(@RequestParam("name") String name,@RequestParam("age") int age) {
        return "姓名:" + name + ",年龄:" + age;
    }
}
@RequestParam注解拓展

在@RequestParam注解中包含三个属性:

@RequestParam(value="参数名",required="true/false",defaultValue="")
  • value:指定参数名,如果@RequestParam注解中只有一个value属性,value属性可省略。
  • required:参数是否必须,默认为true,表示该请求中必须包含该参数,如果不包含就报错。
  • defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值。
3. 优缺点
  • 优点

  • 代码简洁明了,直接在方法参数中声明需要接收的参数,减少了很多样板代码。

  • 类型转换由 SpringMVC 自动完成,减少了手动转换的错误风险,提高了开发效率。

  • 缺点

  • 对于复杂的参数结构(如对象嵌套、数组等),使用方法形参接收会变得复杂,代码可读性会下降。

  • 如果请求参数较多,方法的参数列表会变得很长,不利于维护。

三、实体类型接收

1. 原理

当请求参数较多时,可以创建一个 Java 实体类来封装这些参数。SpringMVC 会自动将请求参数与实体类中的属性进行匹配,前提是属性名与参数名一致。这种方式利用了 JavaBean 的特性,将相关的参数组合在一起,提高了代码的可读性和维护性。

2. 代码示例

首先创建一个User实体类:

public class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

然后修改 Controller 代码:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    @RequestMapping("/userInfo")
    @ResponseBody
    public String getUserInfo(User user) {
        return "姓名:" + user.getName() + ",年龄:" + user.getAge();
    }
}
3. 优缺点
  • 优点

  • 代码结构清晰,将相关参数封装在一个实体类中,便于管理和维护。

  • 对于复杂的参数结构,使用实体类接收更加直观和方便,提高了代码的可读性。

  • 可以利用实体类的校验机制,对参数进行合法性校验。

  • 缺点

  • 需要额外创建实体类,如果项目中参数类型较多,会增加一定的代码量。

  • 对于简单的参数接收场景,使用实体类可能会显得过于繁琐。

四、总结

在实际的 SpringMVC 项目开发中,选择合适的 Controller 参数接收方式至关重要。HttpServletRequest接收方式适合需要获取请求的所有信息且对灵活性要求较高的场景,但代码较为繁琐;方法形参接收方式简洁高效,适用于简单参数的接收,但对于复杂参数结构不太友好;实体类型接收方式则将参数封装在实体类中,提高了代码的可读性和维护性,适用于参数较多且结构复杂的场景。开发者应根据具体的业务需求和参数特点,合理选择参数接收方式,以提高项目的开发效率和代码质量。

Controller数据传递

1、三大作用域

Controller数据传递,指的是将Controller方法中获取到的数据传递到JSP页面中进行显示。要实现这个功能,需要依靠Servlet三大作用域来实现,作用域是服务器运行阶段在内存中开辟的空间, 用于存储数据,不同的作用域有效范围是不一样的。

作用域 对象类型 有效范围
request(请求作用域) HttpServletRequest 仅在当次请求中有效
session(会话作用域) HttpSession 在当前会话中有效
application(应用作用域) ServletContext 在整个服务器运行过程中都是有效的

三个作用域操作通用方法:

  • 存放数据:setAttribute([属性名],[值]);
  • 获取数据:getAttribute([属性名]);
  • 删除数据:removeAttribute([属性名]);

JSP页面中可以通过EL表达式获取作用域中指定属性的值。

获取request作用域中属性的值:${requestScope.[属性名]}

获取session作用域中属性的值:${sessionScope.[属性名]}

获取application作用域中属性的值:${applicationScope.[属性名]}

也可以直接通过${[属性名]}来获取值,默认按照request–》session–》application作用域的顺序寻找对应属性的值,直到找到为止。

2、在Controller中操作request域

在Controller方法中,可以通过HttpServletRequest、Model/ModelMap/Map、ModelAndView对象将数据存储到request作用域中。

2.1 HttpServletRequest

可以在Controller方法中加入一个HttpServletRequest类型的参数获取当前请求对象。

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(HttpServletRequest request){
        request.setAttribute("username","张三");
        return "hello";
    }
}
2.2 Model/ModelMap/Map

SpringMVC在调用方法前会创建一个隐含的数据模型,作为模型数据的存储容器,这个隐形模型类型为BindingAwareModelMap, SpringMVC 会帮我们把模型数据存入请求域 。BindingAwareModelMap继承了ModelMap,实现了Model和Map接口,以下是继承关系,因此,我们可以在Controller方法中加入Model/ModelMap/Map类型的参数用来获取该模型对象。

SpringMVC 框架中 Controller 控制器的参数接收方式详解_第1张图片

使用Model
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(Model model){
        model.addAttribute("username","张三");
        return "hello";
    }
}
使用ModelMap
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(ModelMap model){
        model.addAttribute("username","张三");
        return "hello";
    }
}
使用Map
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(Map<String,Object> map){
        map.put("username","张三");
        return "hello";
    }
}
2.3 ModelAndView

通过创建ModelAdnView对象并返回也可以将数据存储到数据模型然后传递到View页面中。

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public ModelAndView hello(){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        mv.addObject("username","张三");
        return mv;
    }
}

3、在Controller中操作session域

可以在Controller方法中加入一个HttpSession类型的参数获取当前会话。

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(HttpSession session){
        session.setAttribute("username","张三");
        return "hello";
    }
}

4、在Controller中操作application域

Tomcat服务器会为每一个Web应用创建一个ServletContext对象。这个对象全局唯一,而且Web应用 中的所有Servlet都共享这个对象。在SpringMVC框架启动后会创建IoC容器并将ServletContext放在IoC容器中,因此,我们可以通过属性注入获取该对象。

@Controller
public class HelloController {
    @Autowired
    private ServletContext context;
    @RequestMapping("/hello")
    public String hello(){
        context.setAttribute("username","张三");
        return "hello";
    }
}

rvlet都共享这个对象。在SpringMVC框架启动后会创建IoC容器并将ServletContext放在IoC容器中,因此,我们可以通过属性注入获取该对象。

@Controller
public class HelloController {
    @Autowired
    private ServletContext context;
    @RequestMapping("/hello")
    public String hello(){
        context.setAttribute("username","张三");
        return "hello";
    }
}

你可能感兴趣的:(SpringMVC,spring,java,学习,后端)