SpringBoot请求响应

Web请求响应

简单参数:在向服务器发起请求时,向服务器传递的是一些普通的请求数据。

那么在后端程序中,如何接收传递过来的普通参数数据呢?

简单参数

@RestController
public class RequestController {
    // http://localhost:8080/simpleParam?name=Tom&age=10
    // 第1个请求参数: name=Tom   参数名:name,参数值:Tom
    // 第2个请求参数: age=10     参数名:age , 参数值:10
    
    //springboot方式
    @RequestMapping("/simpleParam")
    public String simpleParam(String name , Integer age ){//形参名和请求参数名保持一致
        System.out.println(name+"  :  "+age);
        return "OK";
    }
}

postman测试( GET 请求):

postman测试( POST请求 ):

实体参数

 定义实体参数User

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

Controller方法:

@RestController
public class RequestController {
    //实体参数:简单实体对象
    @RequestMapping("/simplePojo")
    public String simplePojo(User user){
        System.out.println(user);
        return "OK";
    }
}

Postman测试:

  • 参数名和实体类属性名一致时

  • 参数名和实体类属性名不一致时

复杂实体对象

定义POJO实体类:

  • 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 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;
    }
​
    public Address getAddress() {
        return address;
    }
​
    public void setAddress(Address address) {
        this.address = address;
    }
​
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

Controller方法:

@RestController
public class RequestController {
    //实体参数:复杂实体对象
    @RequestMapping("/complexPojo")
    public String complexPojo(User user){
        System.out.println(user);
        return "OK";
    }
}

Postman测试:

数组参数

@RestController
public class RequestController {
    //数组集合参数
    @RequestMapping("/arrayParam")
    public String arrayParam(String[] hobby){
        System.out.println(Arrays.toString(hobby));
        return "OK";
    }
}

Postman测试:

在前端请求时,有两种传递形式:

方式一: xxxxxxxxxx?hobby=game&hobby=java

方式二:xxxxxxxxxxxxx?hobby=game,java

集合参数

Controller方法:

@RestController
public class RequestController {
    //数组集合参数
    @RequestMapping("/listParam")
    public String listParam(@RequestParam List<String> hobby){
        System.out.println(hobby);
        return "OK";
    }
}

Postman测试:

方式一: xxxxxxxxxx?hobby=game&hobby=java

方式二:xxxxxxxxxxxxx?hobby=game,java

日期参数

Controller方法:

@RestController
public class RequestController {
    //日期时间参数
   @RequestMapping("/dateParam")
    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
        System.out.println(updateTime);
        return "OK";
    }
}

Postman测试:

JSON参数 

实体类:Address

public class Address {
    private String province;
    private String city;
    
    //省略GET , SET 方法
}

实体类:User

public class User {
    private String name;
    private Integer age;
    private Address address;
    
    //省略GET , SET 方法
}    

Controller方法:

@RestController
public class RequestController {
    //JSON参数
    @RequestMapping("/jsonParam")
    public String jsonParam(@RequestBody User user){
        System.out.println(user);
        return "OK";
    }
}

Postman测试:

分层解耦

三层架构

SpringBoot框架支持三层架构模式,这有助于提高代码的可维护性和可扩展性。以下是SpringBoot中三层架构的详细说明:

  1. 表示层(Presentation Layer):也被称为Web层或控制层。这一层主要负责接收客户端的请求并向客户端发送响应。在Spring Boot应用中,这一层通常由Controller组件构成,它们处理HTTP请求,调用业务逻辑层的服务,并返回响应数据。
  2. 业务逻辑层(Business Logic Layer):也称为Service层。它处理应用程序的核心业务逻辑,比如数据的处理和计算。这一层为表示层提供必要的业务方法,并调用数据访问层来持久化数据。
  3. 数据访问层(Data Access Layer):也称为DAO层或持久层。负责与数据库交互,执行数据的增删改查操作。这一层为业务逻辑层提供数据支持,并将业务对象映射到数据库表中。

此外,每一层都有明确的职责,彼此之间通过接口进行通信,确保了系统的高内聚和低耦合。这种分层方式有利于后期的维护和项目的扩展。

耦合问题

在SpringBoot的三层架构中,耦合问题通常指的是不同层之间的依赖关系过于紧密,导致一个层的变动可能会影响到其他层。为了解决这一问题,可以采取以下措施:

  1. 遵循单一职责原则:确保每个类或方法只负责一项任务,这样可以减少不同组件之间的依赖,提高代码的可读性和可维护性。
  2. 使用接口或抽象类:通过定义清晰的接口或抽象类来隔离各层之间的直接依赖,使得上层不需要知道下层的具体实现细节。
  3. 依赖注入:利用Spring框架的依赖注入特性,可以实现层与层之间的松耦合。这样可以在不修改上层代码的情况下,替换或修改下层的实现。
  4. 避免循环依赖:确保不存在从一个层到另一个层的直接或间接的循环依赖关系,这样可以避免复杂的依赖结构。
  5. 分层解耦:保持每一层的职责清晰分离,比如表现层只处理用户交互,业务逻辑层处理业务规则,数据访问层处理数据持久化等。
  6. 编码规范:制定和遵循一套编码规范,确保团队成员在开发时能够一致地应用解耦的最佳实践。
  7. 持续重构:随着项目的进展,不断地对代码进行重构,以提高代码质量,降低耦合度。
  8. 单元测试:编写单元测试可以帮助识别和隔离耦合问题,因为紧密耦合的代码通常难以进行单元测试。
  9. 文档和培训:通过编写文档和进行培训,帮助团队成员理解耦合问题以及如何避免它们,从而提高整个团队的软件开发能力。

IOC&DI

  • Controller层:

@RestController
public class EmpController {
​
    @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpService empService ;
​
    @RequestMapping("/listEmp")
    public Result list(){
        //1. 调用service, 获取数据
        List<Emp> empList = empService.listEmp();
​
        //3. 响应数据
        return Result.success(empList);
    }
}
  • Service层:

@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpServiceA implements EmpService {
​
    @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpDao empDao ;
​
    @Override
    public List<Emp> listEmp() {
        //1. 调用dao, 获取数据
        List<Emp> empList = empDao.listEmp();
​
        //2. 对数据进行转换处理 - gender, job
        empList.stream().forEach(emp -> {
            //处理 gender 1: 男, 2: 女
            String gender = emp.getGender();
            if("1".equals(gender)){
                emp.setGender("男");
            }else if("2".equals(gender)){
                emp.setGender("女");
            }
​
            //处理job - 1: 讲师, 2: 班主任 , 3: 就业指导
            String job = emp.getJob();
            if("1".equals(job)){
                emp.setJob("讲师");
            }else if("2".equals(job)){
                emp.setJob("班主任");
            }else if("3".equals(job)){
                emp.setJob("就业指导");
            }
        });
        return empList;
    }
}
  • Dao层:
@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1. 加载并解析emp.xml
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}

 IOC详解

SpringBoot中的IoC(Inversion of Control,控制反转)是一种设计原则和编程思想,它的核心思想是将对象的创建、配置和管理交给一个外部的容器来完成,而不是由对象自己或者其使用者来控制。

具体来说,IoC在Spring框架中是通过IoC容器来实现的,这个容器负责:

  1. 创建对象:容器负责创建应用程序中所需的各种对象,这些对象通常被称为beans。
  2. 配置管理:容器负责管理这些对象的生命周期,包括它们的初始化、依赖注入以及销毁等。
  3. 依赖注入:容器通过依赖注入的方式将对象之间的依赖关系解耦,使得对象之间不直接相互依赖,而是依赖于抽象接口或配置文件。
  4. AOP支持:除了IoC,Spring还提供了AOP(面向切面编程)的支持,允许开发者在不修改源代码的情况下为程序添加额外的功能。
  5. 整合其他框架:Spring的设计使得它能够方便地与其他框架进行整合,如Hibernate、MyBatis等。
  6. 事务操作:Spring简化了事务操作的处理,提供了声明式事务管理。
  7. API开发:Spring降低了API开发的复杂性,使得开发者可以更加专注于业务逻辑的开发。

总的来说,在SpringBoot应用中,通常会使用@SpringBootApplication注解来标记主类,并通过调用SpringApplication.run()方法来启动IoC容器。通过这种方式,SpringBoot会自动扫描指定包下的组件,并将它们装配到IoC容器中。

 DI详解

依赖注入(Dependency Injection, DI)是Spring框架中的一个核心概念,它也是实现控制反转(Inversion of Control, IoC)的一种手段。以下是对依赖注入的详细解释:

基本概念

  • DI是一种设计模式,用于降低代码之间的耦合度,使得一个对象不需要自己创建或查找它所依赖的其他对象,而是通过外部的方式(如一个配置文件或框架)来提供所需的依赖项。

工作原理

  • 在Spring中,对象的依赖关系是由Spring容器负责管理的。当一个对象需要另一个对象时,它不是自己创建那个对象,而是从容器中获取一个已经配置好的实例。这样做的好处是,如果依赖的对象需要变更,只需要在容器中修改配置,而不用改动依赖它的代码。

实现方式

  • Spring提供了多种方式来实现DI,包括通过XML配置文件、注解(如@Autowired、@Resource等)以及Java配置类。这些方式都可以让开发者指定对象之间的依赖关系。

优点

  • DI提高了代码的可测试性,因为可以很容易地替换或模拟依赖的对象。
  • 它也增加了代码的灵活性和可维护性,因为依赖关系的改变只需要在一个地方(即配置文件或注解)进行调整。

与IoC的关系

  • DI是实现IoC的一种方式。IoC是一种更广泛的概念,它描述了控制流的反转,即对象的创建和生命周期管理由程序员转移到了框架。DI则是这种控制反转的具体实现,确保了对象之间的依赖关系由外部管理。

常见问题

  • 在使用DI时,可能会遇到多个候选bean的情况,这时可以使用@Qualifier注解来指定具体使用哪一个bean,或者使用@Primary注解来标记首选的bean。

与其他注解的区别

  • @Autowired和@Resource都可以用于字段注入,但@Autowired是Spring的注解,而@Resource是J2EE的注解。在没有明确指定注入方式时,@Autowired默认通过byType注入,而@Resource默认通过byName注入。
  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot中,可以使用注解`@RestController`来定义一个控制器类,其中的方法可以处理HTTP请求并返回响应。如果你想要返回一个集合作为响应,可以使用`ResponseEntity`类来封装。 首先,你需要在方法上使用一个合适的HTTP请求注解,如`@GetMapping`、`@PostMapping`等,来定义处理的HTTP方法和路径。然后,你可以在方法体内创建一个集合对象,并将其作为参数传递给`ResponseEntity`的构造函数。最后,将`ResponseEntity`对象作为方法的返回值即可。 下面是一个简单的示例: ```java import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController public class MyController { @GetMapping("/data") public ResponseEntity<List<String>> getData() { List<String> dataList = new ArrayList<>(); dataList.add("Item 1"); dataList.add("Item 2"); dataList.add("Item 3"); return ResponseEntity.ok(dataList); } } ``` 在上面的示例中,`getData`方法使用了`@GetMapping("/data")`注解来处理GET请求,并返回一个包含字符串的集合。通过`ResponseEntity.ok(dataList)`将集合封装为响应实体并返回。 当你发送GET请求到`/data`路径时,将会收到如下响应: ```json ["Item 1", "Item 2", "Item 3"] ``` 这是一个包含三个字符串项的JSON数组。根据你的需求,你可以返回不同类型的集合,如`List<Integer>`、`Set<String>`等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值