SpringBootWeb请求响应和三层架构

请求和响应简单来说都是前端和后端互相沟通的一个方式,请求指的是前端程序向后端发送数据“请求”操作,响应指的是后端程序将前端的请求处理后做出的“回应”。

1 请求

1.1 软件选择

 我们要发送请求首先需要有相应的插件,我们这里选择的是Postman。

 Postman操作页面如下,比较简单,用一用就知道了。

后续内容中我们会在英文的基础上加上红字的说明来讲解,方便理解。

1.2 6种参数的写法

1.2.1 简单参数
@RequestMapping("/simpleParam")
public String simpleParam(String name , Integer age ){
    System.out.println(name+"  :  "+age);
    return "OK";
}

如果方法形参名称与请求参数名称不一致,可以在方法形参名前加上 @RequestParam 完成映射

1.2.2 实体参数

简单实体参数:只有一个实体类

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

复杂实体参数:有多个实体类

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

只有在键值对这里有一点不同

1.2.3 数组集合参数

数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型形参即可接收参数

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

集合参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam 绑定参数关系

本质区别不大,除了要加一个注解

@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby){
    System.out.println(hobby);
    return "OK";
}
1.2.4 日期时间参数

需要date就@DateFormat,需要time就@TimeFormat,都需要就@DataTimeFormat

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

前后端通常会使用JSON格式的数据进行传输。

JSON数据键名与形参对象属性名相同,定义POJO(类似javabean)类型形参即可接收参数。需要使用 @RequestBody 标识。

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

1.2.6 路径参数
路径参数:通过请求URL直接传递参数,使用{…}来标识该路径参数,需要使用 @PathVariable 获取路径参数
@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){
    System.out.println(id);
    return "OK";
}

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

2 响应

2.1 响应各种数据

返回字符串数据

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

返回实体对象数据

@RequestMapping("/getUser")
public User getUser(){
    User user = new User();
    user.setName("Tom");
    user.setAge(10);
    return user;
}

 返回集合数据

@RequestMapping("/list")
public List<User> list(){
    User user = new User();
    user.setName("Tom");
    user.setAge(10);

    List<User> userList = new ArrayList<>();
    userList.add(user);
    return userList;
}

2.2 ResposeBody

  • 名称:@ResponseBody
  • 类型:方法注解、类注解
  • 位置:SpringMVC控制器方法上/类上
  • 作用:将当前方法返回值直接返回,如果是 实体/集合 转换为JSON返回

而我们的案例中,并没有直接使用 @ResponseBody,原因是因为我们使用的是 @RestController注解,该注解中已经封装了@ResponseBody注解,已经包含了@ResponseBody注解的作用,我们无需要额外添加。

2.3 统一响应

在真实的项目开发中,无论是增删改查的那种方法,我们都会定义一个统一的返回结果,在这个返回结果中,包含以下信息:

A. 当前请求是成功,还是失败。

B. 当前给页面的提示信息。

C . 返回的数据。

对于上述的这些数据呢,我们一般都会定义在一个实体类Result中。 代码如下:

public class Result {
    private Integer code;//响应码,1 代表成功; 0 代表失败
    private String msg;  //响应码 描述字符串
    private Object data; //返回的数据

    public Result() { }
    public Result(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    //增删改 成功响应
    public static Result success(){
        return new Result(1,"success",null);
    }
    //查询 成功响应
    public static Result success(Object data){
        return new Result(1,"success",data);
    }
    //失败响应
    public static Result error(String msg){
        return new Result(0,msg,null);
    }
}

3 解耦

解耦:简单来说就是减少依赖

依赖:依赖指的是两个类之间的相互依赖关系,我用到你,我就依赖你

3.1 三层架构

分为Controller,Service,Dao三部分,具体实现的功能如下:

  • Controller:接收前端发送的请求,对请求进行处理,并响应数据
  • Service:处理具体的业务逻辑
  • Dao:负责数据的访问操作,包含数据的增、删、改、查

3.2 耦合问题

1).内聚:软件中各个功能模块内部的功能联系。

2).耦合:衡量软件中各个层/模块之间的依赖、关联的程度。

3).软件设计原则:高内聚低耦合。

而在软件开发领域,我们经常会提到一种设计原则:高内聚,低耦合。  高内聚指的是:一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,即 "高内聚"。低耦合指的是:软件中各个层、模块之间的依赖关联程度越低越好。

高内聚、低耦合的目的是使程序模块的可重用性、移植性大大增强。

3.3 IOC&DI

1). 将对象交给容器管理的过程 , 称之为 控制反转。 Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。 而这个容器, 称之为IOC容器,或者Spring容器。

2). 应用程序运行时, 容器为其提供运行时所需要的资源, 这个过程我们称之为依赖注入。 Dependency Injection,简称DI

3). IOC容器中创建、管理的对象,称之为bean

  • Service层 及 Dao层的实现类,交给IOC容器管理。在类上加上 @Component 注解,就是将该类声明为IOC容器中的bean
@Component
public class UserServiceA implements UserService {
    @Autowired
    private UserDao userDao ;

    public List<User> listUser()  {
        //调用 dao 层, 查询数据
        List<User> userList = userDao.listUser();

        //2. 对数据进行逻辑处理
        for (User user : userList) {
            Address address = user.getAddress();
            address.setProvince(address.getProvince()+" 省/市A");
            address.setCity(address.getCity()+" 区/县A");
            user.setAddress(address);
        }
        return userList;
    }
}
@Component
public class UserDaoA implements UserDao {
    public List<User> listUser() {
        //1. 从文件中查询数据
        String file = UserController.class.getClassLoader().getResource("user.xml").getFile();
        List<User> userList = XmlParserUtils.parse(file);
        System.out.println(userList);

        return userList;
    }
}
  • 为Controller及Service注入运行时依赖的对象。在成员变量上加上 @Autowired 注解,表示在程序运行时,Springboot会自动的从IOC容器中找到UserService类型的bean对象,然后赋值给该变量。
@RestController
public class UserController {
    @Autowired
    private UserService userService  ;

    @RequestMapping("/listUser")
    public Result listUser()  {
        List<User> userList = userService.listUser();
        return Result.success(userList);
    }
}
3.3.1 依赖注入问题

但是需要注意:@Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报出如下错误:

我们可以通过如下几种方案来解决:

1). @Primary 注解

当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。

2). @Qualifier 注解

可以通过@Autowired ,配合@Qualifier 来指定我们当前要注入哪一个bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。

3). @Resource注解

通过@Resource注解,并指定其name属性,通过name指定要注入的bean的名称。这种方式呢,是按照bean的名称进行注入。

@Autowird 与 @Resource的区别:

  • @Autowird 属于spring框架,默认按照bean的类型注入。 可以配合 @Qualifier注解,实现按照名称注入。
  • @Resource是JavaEE自带的注解,根据bean的名称进行注入的。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值