参数解密:揭示Spring MVC请求参数处理的实际应用指南

简介: 参数解密:揭示Spring MVC请求参数处理的实际应用指南

处理中文乱码

配置 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 引入 DispatcherServlet -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!-- 指定 Spring MVC 配置文件位置 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring-mvc.xml</param-value>
        </init-param>
        <!-- 设置此 Servlet 在 Tomcat 启动的时候创建 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
  
    <!-- POST 中文乱码 -->
    <servlet>
        <servlet-name>characterEncodingFilter</servlet-name>
        <servlet-class>org.springframework.web.filter.CharacterEncodingFilter</servlet-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>characterEncodingFilter</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

HttpServletRequest

/**
 * 发送Get请求
 * http://localhost:8080/api1?username=XW&password=123456
 */
@RequestMapping("/api1")
public String api1(HttpServletRequest request) {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    System.out.println("username = " + username + ", password = " + password);
    return "index";
}

简单变量

/**
 * 发送Get请求
 * http://localhost:8080/api2?username=XW&password=123456&age=10
 */
@RequestMapping("/api2")
public String api2(String username, String password, Integer age) {
    System.out.println("username = " + username + ", password = " + password + ", age = " + age);
    return "index";
}
  • 对于常用的类型变量(八大基本数据类型 + String),SpringMVC 会对自动进行类型的转换。
  • 在定义参数的时候使用基本数据类型的包装器。

基于 POJO 的请求传参

package world.xuewei.entity;
/**
 * 用户实体
 *
 * @author 薛伟
 * @since 2023/10/30 16:18
 */
public class User {
    private String username;
    private String password;
    private Integer age;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}
/**
 * 发送Get请求
 * http://localhost:8080/api3?username=XW&password=123456&age=10
 */
@RequestMapping("/api3")
public String api3(User user) {
    System.out.println(user);
    return "index";
}
  • 当接口的参数列表为 String api3(String username, User user) 时,简单变量和 POJO 对象都可以接收到参数的值。

简单变量数组

/**
 * 发送Get请求
 * http://localhost:8080/api4?ids=1&ids=2&ids=3
 */
@RequestMapping("/api4")
public String api4(Integer[] ids) {
    System.out.println(Arrays.toString(ids));
    return "index";
}

注意:这种情况不可以使用 List 来接受参数。

原因是 SpringMVC 在做参数赋值的时候先去判断是否为简单对象,如果不是简单对象,那么会去创建定义的参数的对象,然后调用 set 方法进行属性的赋值。对于这个场景而言,首先 List 是接口,无法创建对象,程序将抛出异常,若将 List 改为 ArrayList,那么虽然可以创建对象,但是 ArrayList 中并没有 ids 的属性,所以无法进行赋值。

接收一组 POJO 对象

接收一组 POJO 就需要定义一个 DTO,在 DTO 中创建对应的属性,完成属性的赋值。

package world.xuewei.entity;
import java.util.List;
/**
 * 用户传输对象
 *
 * @author 薛伟
 * @since 2023/10/30 16:18
 */
public class UserDTO {
    
    List<User> users;
    public List<User> getUsers() {
        return users;
    }
    public void setUsers(List<User> users) {
        this.users = users;
    }
}
/**
 * 发送POST请求
 */
@RequestMapping("/api5")
public String api5(UserDTO dto) {
    System.out.println(dto.getUsers());
    return "index";
}

@RequestParam注解

在 Spring 框架中,@RequestParam 注解用于将请求中的参数绑定到方法的参数上。它可以被用于处理 GET 或 POST 请求中的查询字符串参数或表单参数。

使用 @RequestParam 注解时,你需要指定参数的名称,该名称与请求中的参数名称一致。如果请求中的参数与方法参数的名称相同,可以省略 @RequestParam 注解中的 value 属性。

@RequestParam 注解提供了一些可选属性,让你可以更好地控制参数的行为:

  1. value:指定请求参数的名称,如果省略,则默认使用参数名作为请求参数的名称。
  2. required:指定该参数是否为必需的,默认为 true,表示请求中必须包含该参数,否则将抛出异常。如果设置为 false,则表示该参数是可选的。
  3. defaultValue:指定当请求中没有指定该参数时的默认值。如果请求中存在该参数,则使用请求中的值,否则使用默认值。

下面是一个使用 @RequestParam 注解的示例:

@RequestMapping(value = "/example")
public String exampleMethod(@RequestParam(value = "n", required = true) String name,
                            @RequestParam(value = "age", required = false, defaultValue = "0") int age) {
    // 方法体
}

POJO 类型的形参,不能使用此注解,不然会报错 400。

接收Map数据

单值动态参数

package world.xuewei.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Map;
import java.util.Objects;
/**
 * 第一个控制器
 *
 * @author 薛伟
 * @since 2023/10/30 16:18
 */
@Controller
public class MapController {
    @RequestMapping("/map")
    public String map(@RequestParam Map<String, Object> map) {
        System.out.println(map);
        return "index";
    }
}

http://localhost:8080/map?name=xw&age=25

注意:必须使用 @RequestParam 注解

多值动态参数

package world.xuewei.controller;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * 第一个控制器
 *
 * @author 薛伟
 * @since 2023/10/30 16:18
 */
@Controller
public class MapController {
    @RequestMapping("/map")
    public String map(@RequestParam MultiValueMap<String, String> map) {
        System.out.println(map);
        return "index";
    }
}

http://localhost:8080/map?name=xw&name=zs&name=li

注意:此处使用 MultiValueMap 接口参数,每个 key 对应的值都是一个 List。


相关文章
|
13天前
|
前端开发 Java Spring
Spring MVC 是如何对对象参数进行校验的
【6月更文挑战第4天】对象参数校验是使用 SpringMVC 时常用的功能,这篇文章尝试分析了,Spring 是如何实现这一功能的。
28 5
|
2天前
|
JSON 前端开发 Java
【JavaEE进阶】 关于Spring MVC 响应
【JavaEE进阶】 关于Spring MVC 响应
13 3
|
3天前
|
缓存 NoSQL Java
在 SSM 架构(Spring + SpringMVC + MyBatis)中,可以通过 Spring 的注解式缓存来实现 Redis 缓存功能
【6月更文挑战第18天】在SSM(Spring+SpringMVC+MyBatis)中集成Redis缓存,涉及以下步骤:添加Spring Boot的`spring-boot-starter-data-redis`依赖;配置Redis连接池(如JedisPoolConfig)和连接工厂;在Service层使用`@Cacheable`注解标记缓存方法,指定缓存名和键生成策略;最后,在主配置类启用缓存注解。通过这些步骤,可以利用Spring的注解实现Redis缓存。
18 2
|
9天前
|
安全 Java 测试技术
Spring Security应用中的部分代码示例2
【6月更文挑战第12天】Spring Security应用中的部分代码示例2
18 5
|
5天前
|
Java Linux Spring
在 Linux 系统中将 Spring Boot 应用作为系统服务运行
【6月更文挑战第11天】最近由于一些原因,服务器经常会重启,每次重启后需要手动启动 Spring Boot 的工程,因此我需要将其配置成开启自启动的服务。
25 1
|
9天前
|
安全 Java 数据库
Spring Security应用代码示例
【6月更文挑战第12天】Spring Security应用代码示例
17 3
|
11天前
|
JSON 前端开发 Java
Spring MVC 级联对象参数校验
【6月更文挑战第6天】在 Spring MVC 的使用过程中,我们会发现很多非常符合直觉的功能特性,但往往我们会习惯这种「被照顾得很好」的开发方式,依靠直觉去判断很多功能特性的用法。
16 1
|
10天前
|
Java Serverless 应用服务中间件
Serverless 应用引擎产品使用合集之Web函数启动的Spring Boot项目可以通过什么方式配置Nginx
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
3天前
|
前端开发 Java Maven
如何在Spring MVC中实现图片的上传和下载功能
如何在Spring MVC中实现图片的上传和下载功能
|
3天前
|
人工智能 前端开发 Java
基于Spring框架的GPT应用
基于Spring框架的GPT应用
13 0