Spring MVC接收前端数据(@RequestParam、@RequestHeader、@RequestBody)

一、@RequestParam

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}

前端代码:

<form action="student/addStudent" method="post">
    <p>学生姓名:<input type="text" name="username"></p>
    <p>学生密码:<input type="password" name="password"></p>
    <p>学生年龄:<input type="text" name="age"></p>
    <p>学生地址:<input type="text" name="address"></p>
    <p><input type="submit" value="表单提交数据"></p>
</form>

<a href="student/addStudent?username=张三&password=123456&age=28&address=江苏南京">超链接提交数据</a>

后端代码:

package controller;

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

@Controller
// 声明此控制器的请求路径。由于路径类型是String数组,所以可设置多个路径({"..", "..", ..})。
@RequestMapping("/student")
public class StudentController {

    // 如果控制器参数名与前端传递过来的数据的key名称一致,那么@RequestParam注解可省略。此时控制器参数效果与@RequestParam(value = "key", required = false)一致。
    @RequestMapping("/addStudent")
    public void addStudent(@RequestParam(value = "username", required = false) String username,
                           @RequestParam(value = "password", required = false) String password,
                           @RequestParam(value = "age", required = false, defaultValue = "0") Integer age,
                           @RequestParam(value = "address", required = false) String address) {
        System.out.println(username+", "+password+", "+age+", "+address);
    }
}

运行测试:

在这里插入图片描述
在这里插入图片描述
required = true(默认):表单提交未赋值时,它也传递了数据给服务器(传递""字符串),因此String类型参数不会报错。但是intInteger类型会报错,因为""无法转换为intinteger类型(解决方法:设置required = false【此时ageInteger类型时值为null,为int类型时依旧报错,因为null无法赋值给int类型】或者设置默认值defaultValue = "0")。
required = false:表单提交没有赋值的默认传值""(不是null)。上述代码中参数ageint类型,如果没有默认值且表单提交未赋值,那么程序报错,因为""字符串无法强转为int类型(解决方法:将age类型由int改为Integer,此时给age赋值""时,虽然Integer类型不能接收""类型的值,但是它可被null赋值,所以此时age结果为null)。
在这里插入图片描述
在这里插入图片描述
required = true(默认):使用GET提交时所有参数都要加上,否则报错。因为不加参数的话就不会传值给服务端(与表单提交不一样)。
required = false:URL后加键值对提交数据(GET提交数据)时没有写的参数默认值为null。上述代码中参数ageint类型,如果没有默认值且GET提交未写参数,那么程序报错,因为null无法赋值给int类型参数(解决方法:将age类型由int改为Integer,此时给age赋值时,结果为null)。

注意1:在Spring MVC中,接收参数时操作的都是对象,这也是为什么设置了required = false后,如果控制器没有收到参数,其值为null的原因。因此在开发中控制器接收参数时,尽量使用对象类型(Integer等)。

注意2:控制器使用@RequestParam注解接收数据时可接收请求行和编码格式为application/x-www-form-urlencoded的请求体数据,不能接收请求头中的数据。

二、@RequestHeader

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestHeader {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
// 变量与@RequestParam一致,用法也是一样的。

前端代码:

<input type="button" value="AJAX提交数据" id="btn1">
<script type="text/javascript" src="static/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript">
    $("#btn1").click(function () {
        $.ajax({
            <!--在url中使用?key=value传值,此为请求行传值-->
            url:"student/addStudent",

            type:"post",

            <!--此为请求头传值,注意:请求头中值不能有中文,否则执行无反应-->
            headers:{
                username:"lisi",
                password:"123456",
                age:25,
                address:"China"
            },

            <!--回调方法-->
            success:function (res) {
            console.log(res);
            }
        });
    });
</script>

后端代码:

package controller;

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

@Controller
// 声明此控制器的请求路径。由于路径类型是String数组,所以可设置多个路径({"..", "..", ..})。
@RequestMapping("/student")
public class StudentController {

    // 与@RequestParam不同的是,即使控制器参数名与前端传递过来的数据的key名称一致,@RequestHeader注解也不可省略。
    @RequestMapping("/addStudent")
    public void addStudent(@RequestHeader("username") String username,
                           @RequestHeader("password") String password,
                           @RequestHeader("age") Integer age,
                           @RequestHeader("address") String address) {

        System.out.println(username+", "+password+", "+age+", "+address);
    }
}

注意:控制器接收请求头中的数据只能使用@RequestHeader注解。

三、@RequestBody

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
    boolean required() default true;
}

前端代码:

<input type="button" value="AJAX提交数据" id="btn1">
<script type="text/javascript" src="static/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript">
    $("#btn1").click(function () {

        let obj = {};
        obj.username="张三";
        obj.password="123456";
        obj.age=24;
        obj.address="江西省南昌市";

        $.ajax({
            <!--在url中使用?key=value传值,此为请求行传值-->
            url:"student/addStudent",

            type:"post",

            <!--此为请求体传值,一般用来传递一个对象结构,此时需要声明传递的数据类型。如下所示-->
            <!--
                1data: obj,
                2data:JSON.stringify(obj),
                3contentType:"application/json",
                data:obj,
                4contentType:"application/json",
                data:JSON.stringify(obj),
            -->

            <!--回调方法-->
            success:function (res) {
            console.log(res);
            }
        });
    });
</script>

后端代码接收数据的对象:

package model;

import lombok.*;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class Student {
    private String username;
    private String password;
    private Integer age;
    private String address;
}

后端代码1:

package controller;

import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.IOException;

@Controller
@RequestMapping("/student")
public class StudentController {

    // 使用Servlet(需要导入Servlet依赖)读取AJAX发送过来的请求体中的数据。注意前端请求体中发送的数据的编码方式。
    @RequestMapping("/addStudent")
    public void addStudent(HttpServletRequest request) {
        StringBuffer str = new StringBuffer();

        try (ServletInputStream inputStream = request.getInputStream();) {
            byte[] bytes = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(bytes)) != -1) {
                str.append(new String(bytes, 0, len));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 此时需对字符串按照&进行切分,然后判断=左边的key值并将其赋值给Student对象。很麻烦!
        System.out.println(str.toString());
    }
}

1,2,3,4运行结果依次为:

username=%E5%BC%A0%E4%B8%89&password=123456&age=24&address=%E6%B1%9F%E8%A5%BF%E7%9C%81%E5%8D%97%E6%98%8C%E5%B8%82
23-Sep-2023 11:10:39.549 警告 [http-nio-8080-exec-6] org.springframework.web.servlet.DispatcherServlet.noHandlerFound No mapping for POST /javastudy_war_exploded/student/student/addStudent
{"username":"寮犱笁","password":"123456","age":24,"address":"姹熻タ鐪佸崡鏄屽競"}
23-Sep-2023 11:11:02.509 警告 [http-nio-8080-exec-10] org.springframework.web.servlet.DispatcherServlet.noHandlerFound No mapping for POST /javastudy_war_exploded/student/student/addStudent
username=%E5%BC%A0%E4%B8%89&password=123456&age=24&address=%E6%B1%9F%E8%A5%BF%E7%9C%81%E5%8D%97%E6%98%8C%E5%B8%82
23-Sep-2023 11:11:26.794 警告 [http-nio-8080-exec-2] org.springframework.web.servlet.DispatcherServlet.noHandlerFound No mapping for POST /javastudy_war_exploded/student/student/addStudent
{"username":"寮犱笁","password":"123456","age":24,"address":"姹熻タ鐪佸崡鏄屽競"}
23-Sep-2023 11:11:58.561 警告 [http-nio-8080-exec-9] org.springframework.web.servlet.DispatcherServlet.noHandlerFound No mapping for POST /javastudy_war_exploded/student/student/addStudent

后端代码2:

package controller;

import model.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/student")
public class StudentController {

    @RequestMapping("/addStudent")
    public void addStudent(@RequestBody Student student) {
        System.out.println(student);
    }
}

注意:Spring MVC默认采用Jackson解析Json,因此需要导入依赖包。(jackson-databind包含另外两个包,因此只需导入其一个包即可)

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.15.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.15.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>

如果不导入包,那么1,2,3,4运行结果依次为:

23-Sep-2023 10:52:05.173 警告 [http-nio-8080-exec-3] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/x-www-form-urlencoded;charset=UTF-8' is not supported]
23-Sep-2023 10:52:34.162 警告 [http-nio-8080-exec-7] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/x-www-form-urlencoded;charset=UTF-8' is not supported]
23-Sep-2023 10:53:22.281 警告 [http-nio-8080-exec-10] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/json;charset=UTF-8' is not supported]
23-Sep-2023 10:53:48.441 警告 [http-nio-8080-exec-4] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/json;charset=UTF-8' is not supported]

导入包后,1,2,3,4运行结果依次为:

23-Sep-2023 10:56:54.217 警告 [http-nio-8080-exec-5] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/x-www-form-urlencoded;charset=UTF-8' is not supported]
23-Sep-2023 10:57:23.723 警告 [http-nio-8080-exec-9] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/x-www-form-urlencoded;charset=UTF-8' is not supported]
23-Sep-2023 10:58:06.777 警告 [http-nio-8080-exec-2] org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'username': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')]
Student(username=张三, password=123456, age=24, address=江西省南昌市)
23-Sep-2023 10:58:31.156 警告 [http-nio-8080-exec-4] org.springframework.web.servlet.DispatcherServlet.noHandlerFound No mapping for POST /javastudy_war_exploded/student/student/addStudent
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值