JavaWeb-请求响应

三、请求响应

JavaWeb-请求响应_第1张图片

​ 我们之前写的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方式的请求

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

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

3.1.1 简单参数

  • 原始方式

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

JavaWeb-请求响应_第2张图片

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

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

JavaWeb-请求响应_第3张图片

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

JavaWeb-请求响应_第4张图片

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

JavaWeb-请求响应_第5张图片

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

JavaWeb-请求响应_第6张图片

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

/*
对于上面的代码,返回的值为
NULL:19
*/

JavaWeb-请求响应_第7张图片

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

​ 如果参数是可选择的,可以将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
*/

JavaWeb-请求响应_第8张图片

JavaWeb-请求响应_第9张图片

JavaWeb-请求响应_第10张图片

3.1.2 实体参数

简单实体

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

JavaWeb-请求响应_第11张图片

  //实体参数
    @RequestMapping("simplePojo")
    public String simplePojo(User user){
        System.out.println(user);
        return "OK";
    }
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 +
                '}';
    }
}

JavaWeb-请求响应_第12张图片

JavaWeb-请求响应_第13张图片

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

JavaWeb-请求响应_第14张图片

​ 那么得到的就是null:19

在这里插入图片描述

复杂实体

JavaWeb-请求响应_第15张图片

 @RequestMapping("complexPojo")
    public String complexPojo(User user){
        System.out.println(user);
        return "OK";
    }
//创建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 + '\'' +
                '}';
    }
}

//修改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 +
                '}';
    }
}

​ 参数跟结果如下图

JavaWeb-请求响应_第16张图片

在这里插入图片描述

3.1.3 数组集合参数

数组参数

JavaWeb-请求响应_第17张图片

 @RequestMapping("/arrayParam")
    public String arrayParam(String[] hobby){
        System.out.println(Arrays.toString(hobby));
        return "OK";
    }

JavaWeb-请求响应_第18张图片

JavaWeb-请求响应_第19张图片

集合参数

JavaWeb-请求响应_第20张图片

 @RequestMapping("/listParam")
    public String listParam(@RequestParam List<String> hobby){
        System.out.println(hobby);
        return "OK";
    }

JavaWeb-请求响应_第21张图片

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

3.1.4 日期参数

JavaWeb-请求响应_第22张图片

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

JavaWeb-请求响应_第23张图片

JavaWeb-请求响应_第24张图片

3.1.5 json参数

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

JavaWeb-请求响应_第25张图片

 @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 + '\'' +
                '}';
    }
}

{
    "name":"砂狼白子",
    "age":16,
    "address":{
        "province":"阿斯硫拜",
        "city":"BA"
    }
}

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

JavaWeb-请求响应_第26张图片

输出结果
User{name='砂狼白子', age=16, address=Address{province='阿斯硫拜', city='BA'}}

3.1.6 路径参数

JavaWeb-请求响应_第27张图片

 //路径参数
    @RequestMapping("/path/{id}")
    public String pathParam(@PathVariable Integer id){
        System.out.println(id);
        return "OK";
    }

JavaWeb-请求响应_第28张图片

在这里插入图片描述

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

JavaWeb-请求响应_第29张图片

在这里插入图片描述

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

3.2 响应

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

JavaWeb-请求响应_第30张图片

@ResponseBody

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

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

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

JavaWeb-请求响应_第31张图片

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

//响应一个JSON格式的数据

JavaWeb-请求响应_第32张图片

//返回值为集合对象
 @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集合

JavaWeb-请求响应_第33张图片

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

统一响应数据

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

JavaWeb-请求响应_第34张图片

你可能感兴趣的:(java)