Springboot中接口接收不同的请求数据类型,接口应该如何正确配置

395 阅读4分钟

公司刚来的java自从接手了项目之后,跟前端同学对接口总能吵起来。总是很自信说前端同学传的参数不对,说肯定是前端的问题,自己测试都没问题能收到数据。结果我一看,前端传个json,后端却没有在参数上添加@Responsebody注解,瞬间无语。不过其实这也没什么,毕竟一个系统的前端和后端请求的参数类型都是统一的,直接看之前的代码然后CV一套带走就好。可是谁让咱的系统烂呢!什么类型都有,传什么参数类型全看一个心情。

按请求的类型一般可以分为GETPOST请求,前者的发送的请求内容类型(Content-Type)一般是K=Vform-data形式,后者一般是form-datajson的形式。下面分别演示一下。

GET

  • K=V请求方式
    创建一个简单的controller示例,添加一个Get请求接口/sendKV

    @RestController
    public class TestController {
        @GetMapping("/sendKV")
        public String sendKV(@RequestParam("name") String name,@RequestParam("age") Integer age){
            return name+","+age;
        }
    }
    

    使用PostMan测试接口,看是否能够成功接收并返回请求的数据。

    image.png 由此可见,K=V的请求方式需要将指定的参数定义到方法的形参中,并通过@RequestParam()注解指定要接收的参数名

  • form-data请求方式
    这次先不创建新的接口,后端继续使用上个示例定义的/sendKV接口,直接使用PostMan进行测试

    image.png 成功接收并返回了请求数据,说明这种形式的接口既能接收KV形式的参数,也能接收form-data的请求参数

  • 路径传参的请求的方式
    还有一种请求参数的方式是在请求的url路径上传递参数

    image.png 上面的请求直接将请求参数以路径的形式拼接到接口名后面,这种请求方式的接口定义如下:

    @GetMapping("/sendPath/{name}/{age}")
    public String sendPath(@PathVariable("name") String name, @PathVariable("age") Integer age){
        return name+","+age;
    }
    

    在定义接口名的时候,将路径中的参数名用{}包裹,并且在定义的参数中使用@PathVariable()对应参数的名称。

    以上就是GET的常用请求参数类型,以及如何针对这些不同的报文类型去定义接口。

POST

  • form-data请求方式
    创建接口/sendFormData

    @PostMapping("/sendFormData")
    public String sendFormData(@RequestParam("name") String name,@RequestParam("age") Integer age){
        return name+","+age;
    }
    

    接口的创建方式和Get请求针对参数类型的处理方式是相同的,都是通过@RequestParam()注解来接收参数,只不过将接口设置为了PostMapping。测试一下:

    image.png 请求成功,没有问题。

  • json请求方式
    这次依然先不创建新的接口,后端继续使用上个示例定义的/sendFormData接口,直接使用PostMan进行测试

    image.png 发现请求返回的状态是400,这个状态表示客户端发送的请求数据格式,服务器无法处理。同样的后台也打印出一条异常:Required request parameter 'name' for method parameter type String is not present,意思就是说请求参数name不存在。这就说明,上面的接口定义方式是注定无法处理json请求的。
    现在重新添加一个可以处理json请求的接口/sendJson

    @PostMapping("/sendJson")
    public String sendJson(@RequestBody User user){
        return user.getName()+","+user.getAge();
    }
    

    在日常的开发中,一般使用一个实体类去映射接收到的json数据,实体类中定义了json中包含的字段对应的相同名称的属性。就像下面这样:

    public class User {
        private String name;
        private Integer age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    

    接口请求测试:

    image.png 接口成功处理了请求过来的json数据,并将数据映射到实体类中。

    接口也可以直接使用字符串接收请求的json,然后在对json字符串进行解析json的解析本文不做介绍,接收json字符串接口/sendJsonStr示例:

    @PostMapping("/sendJsonStr")
    public String sendJsonStr(@RequestBody String user){
        return user;
    }
    

    请求测试:

    image.png 可以看到,接口成功使用字符串类型接收了json数据,并成功返回了json字符串