当前位置:   article > 正文

JavaWeb-请求响应_java providerresponsebadjson message:invalid respo

java providerresponsebadjson message:invalid response

三、请求响应

在这里插入图片描述

​ 我们之前写的HelloController.java文件并不能直接被Tomcat识别,而是被DispatcherServlet(这是一个类),前端浏览器发起的请求会先经过DispatcherServlet识别,然后DispatcherServlet会将收到的请求转给各个xxxController程序,经过Controller处理后,再将处理完的结果返回给DispatcherServlet,然后DispatcherServlet再给浏览器响应,我们一般称DispatcherServlet类为前端控制器。浏览器发出请求时,会携带请求数据(Get xxx xxx,Accept:xxx,Accept-Encoding:xxx这类的),Web服务器会对这些请求数据进行解析,然后将解析的结果封装到一个对象中,这个对象就是HttpServletRequest,也叫请求对象。另外还有一个HttpServletResponse对象,这个对象的作用就是让Web服务器按照HTTP协议的格式来设置响应信息,然后将数据响应给浏览器。

​ 这种浏览器/服务器的模式就叫做BS架构,特点是在地址栏输入地址就能直接访问(这类网站都是BS架构)。

3.1 请求

​ 现在主流的开发模式是:前后端分离开发。前后端人员只需要根据一份接口文档做出相应的开发即可,但我们每开发完一个工程就要对其进行测试,但由于是前后端分离开发,后端测试的时候是看不到页面的,对于GET方式的还行,直接

localhost:8080/hello
对于可以按照上面输入地址直接访问的一般都是GET方式的请求
  • 1
  • 2

就能访问到我们开发的Web应用,如果遇到POST请求,就得自己写前端的代码,然后再进行后端功能的测试,这就很麻烦了。

​ 此时我们需要借助Postman来解决接口测试的需求,基于Postman还衍生出了Apipost、Apifox等应用程序。

3.1.1 简单参数
  • 原始方式

    在原始的Web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取。

在这里插入图片描述

//具体来说就是在Java里面定义一个方法,在形参当中声明一个HttpServletRequest对象,这个对象中封装了请求数据,然后我们调用这个方法来接受获取传递过来的请求参数。
//当然,这种方式比较繁琐,实际开发不会用到,了解即可。
  • 1
  • 2
  • SpringBoot方式

    简单参数:参数名与形参变量名相同,定义形参即可接收参数。

在这里插入图片描述

​ 而对于POST请求,还需要写请求体。

在这里插入图片描述

​ 但不论哪种请求,结果都能在控制台看到。

在这里插入图片描述

​ 如果请求参数名跟形参不匹配,不会报错,但会空值输出(引用数据都是NULL),解决方法是使用@RequestParam注解完成映射。

在这里插入图片描述

@RequestMapping("/simpleParam")
    public String simpleParam(String username,Integer age){
        System.out.println(username+":"+age);//age设为19,name设置为Tom,如下图
        return "OK";
    }

/*
对于上面的代码,返回的值为
NULL:19
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

@RequestMapping("/simpleParam")
    public String simpleParam(@RequestParam(name = "name") String username, Integer age){
        System.out.println(username+":"+age);
        return "OK";
    }
/*
对于现在的代码,输出结果为(测试数据如上图):
Tom:19
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

​ 如果参数是可选择的,可以将required属性设置为false(其默认为true)

@RequestMapping("/simpleParam")
    public String simpleParam(@RequestParam(name = "name",required = false) String username, Integer age){
        System.out.println(username+":"+age);
        return "OK";
    }

/*
在name勾选的情况下,输出的是:
Tom:19

在name未勾选的情况下,输出的是:
null:19
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.1.2 实体参数
简单实体

​ 在简单参数中,前端传递了多少个参数,我们就需要在方法体中声明多少个参数来接收,比如上面的name跟age。前端传递两个参数还好,但如果传递了几十个甚至上百个,那么通过简单参数来接收就显得十分繁琐,而且不利于后期的维护。此时就可以将这些参数封装到一个实体类当中,比如可以将name跟age封装到User当中(见下图代码),要想成功封装,就需要请求参数中的参数名跟对象中的属性名保持一致

在这里插入图片描述

  //实体参数
    @RequestMapping("simplePojo")
    public String simplePojo(User user){
        System.out.println(user);
        return "OK";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
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;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这里插入图片描述

在这里插入图片描述

​ 如果参数没有完全一一对应,比如:

在这里插入图片描述

​ 那么得到的就是null:19

在这里插入图片描述

复杂实体

在这里插入图片描述

 @RequestMapping("complexPojo")
    public String complexPojo(User user){
        System.out.println(user);
        return "OK";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
//创建Address类
public class Address {
    private String province;
    private String city;

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
//修改User类
public class User {
    private String name;
    private Integer age;

    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    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;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

​ 参数跟结果如下图

在这里插入图片描述

在这里插入图片描述

3.1.3 数组集合参数
数组参数

在这里插入图片描述

 @RequestMapping("/arrayParam")
    public String arrayParam(String[] hobby){
        System.out.println(Arrays.toString(hobby));
        return "OK";
    }
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

在这里插入图片描述

集合参数

在这里插入图片描述

 @RequestMapping("/listParam")
    public String listParam(@RequestParam List<String> hobby){
        System.out.println(hobby);
        return "OK";
    }
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

​ 输出结果与数组参数一致。

3.1.4 日期参数

在这里插入图片描述

 @RequestMapping("/dateParam")
    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
        System.out.println(updateTime);
        return "OK";
    }
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

在这里插入图片描述

3.1.5 json参数

​ JSON参数:我们一般会通过实体对象来接收json的数据,但需要json数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用@RequestBody 标识。

在这里插入图片描述

 @RequestMapping("/jsonParam")
    public String jsonParam(@RequestBody User user){
        System.out.println(user);
        return "OK";
    }



//User类
public class User {
    private String name;
    private Integer age;

    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    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;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}


//Address类
public class Address {
    private String province;
    private String city;

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
{
    "name":"砂狼白子",
    "age":16,
    "address":{
        "province":"阿斯硫拜",
        "city":"BA"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

​ 注意JSON参数在Postman的设置位置

在这里插入图片描述

输出结果
User{name='砂狼白子', age=16, address=Address{province='阿斯硫拜', city='BA'}}
  • 1
  • 2
3.1.6 路径参数

在这里插入图片描述

 //路径参数
    @RequestMapping("/path/{id}")
    public String pathParam(@PathVariable Integer id){
        System.out.println(id);
        return "OK";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

在这里插入图片描述

//路径参数
    @RequestMapping("/path/{id}/{name}")
    public String pathParam(@PathVariable Integer id,@PathVariable String name){
        System.out.println(name+":"+id);
        return "OK";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

在这里插入图片描述

特别强调:{…}中的路径参数要和形参名相同

3.2 响应

return值通过@ResponseBody注解响应到浏览器

在这里插入图片描述

@ResponseBody

类型:方法注解、类注解
位置:Controller方法上/类上
作用:将方法返回值直接响应,如果返回值类型是 实体对象/集合 ,将会转换为JSON格式,再响应给客户端(浏览器)
说明:@RestController=@Controller+@ResponseBody
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

​ Postman发送请求数据后,打开控制台,可以看见HTTP协议信息,上下分别为请求信息、响应信息。

 @RequestMapping("/path/{id}/{name}")
    public String pathParam(@PathVariable Integer id,@PathVariable String name){
        System.out.println(name+":"+id);
        return "OK";
    }
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

//返回值实体对象
 @RequestMapping("/getAddr")
    public Address getAddr(){
        Address addr = new Address();
        addr.setProvince("蔚蓝档案");
        addr.setCity("阿斯硫拜");
        return addr;
    }

//响应一个JSON格式的数据
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

//返回值为集合对象
 @RequestMapping("/listAddr")
    public List<Address> listAddr(){
        List<Address> list = new ArrayList<>();
        
        Address addr = new Address();
        addr.setProvince("广东");
        addr.setCity("深圳");
        
        Address addr2 = new Address();
        addr2.setProvince("陕西");
        addr2.setCity("西安");
        
        list.add(addr);
        list.add(addr2);
        return list;
    }
    

//响应值为JSON集合
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这里插入图片描述

​ 在Controller类中暴露在外的方法都是一个个功能接口,而@RequestMapping中的值就是访问接口的路径,以上三个都是

统一响应数据

​ 由于各个功能接口的返回值类型可以任意,如果在实际开发中也是任意的返回值类型,那么前后端的工作成本就会大大增加,为了方便管理和维护,将会对返回值做一个规定,统一返回Result类。

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/973340
推荐阅读
相关标签
  

闽ICP备14008679号