SpringMVC获取请求参数

目录

1、通过ServletAPI获取request对象

2、通过控制器方法的形参获取请求参数

3、使用@RequestParam注解

4、使用@RequestHeader注解

5、使用@CookieValue注解

6、通过POJO获取请求参数

7、解决请求参数的乱码问题


1、通过ServletAPI获取request对象

将HttpServletRequest对象作为控制器方法的形参,此时request对象就是当前请求报文封装后的对象。

示例

模拟传参

ServletAPI传参

控制器方法

@RequestMapping("/testPath2")
public String testPath2(HttpServletRequest request){
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    System.out.println("username = " + username);
    System.out.println("password = " + password);
    return "target";
}

分析,为什么可以用HttpServletRequest作为控制器方法的形参?

普通的方法中,形参需要我们在调用时,为其赋予值,也就是实参。

而控制器方法,调用者是SpringMVC的组件,那么可以认为是SpringMVC根据控制器方法的参数列表,自动为其注入的对应的实参

例如此处,形参类型是HttpServletRequest,需要一个请求对象,SpringMVC就会在调用它时,将当前请求的对象赋值给那个形参。

注意

这种方法不适合rest风格的传参

使用SpringMVC时,能不用原生API就不用

2、通过控制器方法的形参获取请求参数

在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,DispatcherServlet就会将请求参数赋值给相应的形参

示例

模拟传参

控制器形参传参

控制器方法

@RequestMapping("/testPath3")
public String testPath3(String username, String password){
    System.out.println("username = " + username);
    System.out.println("password = " + password);
    return "target";
}

分析,为什么此处 直接将方法的参数列表与请求参数对应,就能自动获取到请求参数?

SpringMVC在调用这个控制器方法时,如果这个方法的形参与请求参数的名称相同,就会自动赋值

如果形参名和请求参数名不一致,则无法自动赋值。

如果请求参数中包含多个同名的请求参数,如何接收?

有两种方式,使用字符串数组或字符串来接收。

  • 若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
  • 若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果

3、使用@RequestParam注解

如果形参名和请求参数名不一致,就不能使用第二种方法,因为无法修改前端的源码。此时应该手动配置映射关系

@RequestParam注解的作用

将请求参数和控制器方法的形参创建映射关系

示例

模拟传参

@RequestParam传参

控制器方法

@RequestMapping("/testPath4")
public String testPath4(@RequestParam("username") String name, @RequestParam("password") String pwd){
    System.out.println("name = " + name);
    System.out.println("pwd = " + pwd);
    return "target";
}

@RequestParam注解如何使用

在控制器方法的参数列表中使用

@RequestParam注解一共有三个属性:

  • value(参数名):指定为形参赋值的请求参数的参数名
  • required(是否必须):设置是否必须传输此请求参数,默认值为true
    • 若设置为true,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置 defaultValue属性,则页面报错400:Required String parameter 'xxx' is not present
    • 若设置为 false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为 null
  • defaultValue(缺省值):不管required属性值为true或false,当value所指定的请求参数没有传输,或传输的值为 "" 时,则使用默认值为形参赋值

为什么要在后端,规定请求参数的必要性和缺省值?

例如注册用户的操作,按理来说前端应该去做表单验证,确保用户名,密码等必填信息都存在才能提交表单。

但如果前端是菜鸟,没有做验证,大量空的用户名和密码涌入数据库,是很要命的。

所以,在后端我们也应该去做这个工作,作为数据库的最后一道防线,确保万无一失。

需要做的工作:

  • 设置关键信息为必须传入的参数
  • 设置所有信息的默认值,避免空值进入数据库造成污染

还有一个原因,接口是对外开放的,不能依赖前端去保障安全性,因为类似PostMan这类的接口测试工具,是可以绕过前端直接调用接口的。

4、使用@RequestHeader注解

@RequestHeader注解的作用

将请求头信息和控制器方法的形参创建映射关系

用于获取请求头的参数。

注意,通过形参获取请求头内容,没有默认映射,必须手动配置。

@RequestHeader注解如何使用

@RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

5、使用@CookieValue注解

@CookieValue注解的作用

将cookie数据和控制器方法的形参创建映射关系

用于获取Cookie中的参数

@CookieValue注解如何使用

@CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

6、通过POJO获取请求参数

可以在控制器方法的形参位置设置一个实体类类型的形参

若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为对应属性赋值

示例

实体类

public class User implements Serializable {

    private String username;
    private String password;
    
    public User() {
    }
    ...
}

模拟传参

POJO传参

控制器方法

@RequestMapping("/testPath5")
public String testPath5(User user){
    System.out.println("user = " + user);
    return "target";
}

注意

Spring是通过反射,获取POJO的无参构造器来创建对象,所以POJO类必须有无参构造器。

7、解决请求参数的乱码问题

为什么会发生乱码

只有post方式会出现乱码问题,因为tomcat8之后的get方法,都做好了处理。

为什么get方式不会发生乱码

Get是URL解码方式。默认解码格式是Tomcat8编码格式,而tomcat8在server.xml中设置,url的编码方式为UTF-8

为什么post方式会发生乱码

Post是实体内容解码方式。默认解码格式是request编码格式。与Tomcat8编码格式无关,默认以ISO8859-1的编码解析数据,所以需要想办法手动设置为UTF-8

如何解决post的乱码问题

必须在获取到请求参数之前,设置请求参数的编码方式,所以应该使用过滤器来处理,而且要配置到其他所有过滤器之前。

解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须在web.xml中进行注册



       CharacterEncodingFilter
       org.springframework.web.filter.CharacterEncodingFilter
       
           encoding
           UTF-8
       
       
           forceResponseEncoding
           true
       


       CharacterEncodingFilter
       /*

SpringMVC中处理编码的过滤器一定要配置到其他过滤器之前,否则无效

你可能感兴趣的:(Java常用框架,java,前端,servlet)