当前位置: 首页 > article >正文

SpringMVC(四)Restful软件架构风格

目录

​编辑

API接口设计的架构风格

一 Dao层实现(处理数据库)

二 Sercice层实现(处理业务逻辑)

三 Controller层(处理http请求)

四 补充知识点

1 @PathVariable - 路径变量

2 @CrossOrigin(Origins = "*")允许跨域访问

3 可以在路径之前加上需要访问的路径


restful 概念引入 REST(表现层状态转移Representional State Transfer)是一种软件架构风格。

旨在构建高效、可拓展的分布式系统,尤其适用于Web服务,其核心思想是通过统一的接口和资源操作实现客户端于服务器之间的交互。REST 凭借其简洁、灵活的特点,成为现代 Web 服务的基石。

API接口设计的架构风格

API接口:Web应用暴露出来的让别人访问的请求路径。jar包封装的API接口。

CRUD案例实现:

一 Dao层实现(处理数据库)

结构图

代码实现:

创建一个bean类,用来放数据库用户的信息

package org.example.springmvc.bean;


import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class Employee {

    private Integer id;
    private String name;
    private Integer age;
    private String gender;


    public Employee(Integer id, String name, Integer age, String gender) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public Employee() {
    }

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

定义一个接口里面写上需要的方法

package org.example.springmvc.dao;

import org.example.springmvc.bean.Employee;

public interface EmployeeDao {

    // 查询根据ID查询员工
    Employee getEmployeeById(Integer id);

    // 添加员工
    void addEmployee(Employee employee);

    // 修改员工
    void updateEmployee(Employee employee);

    // 删除员工(根据ID)
    void deleteEmployee(Integer id);

}

接口的实现类(数据库增删改查的具体实现)

package org.example.springmvc.dao.Impl;

import org.example.springmvc.bean.Employee;
import org.example.springmvc.dao.EmployeeDao;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class EmployeeDaoImpl implements EmployeeDao {

    private final JdbcTemplate jdbcTemplate;

    // 注入JdbcTemplate
    public EmployeeDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public Employee getEmployeeById(Integer id) {
        String sql = "select * from first_tb where id = ?";
        return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Employee.class), id);
    }

    @Override
    public void addEmployee(Employee employee) {
        String sql = "insert into first_tb(id,name,age,gender) values(?,?,?,?)";
        jdbcTemplate.update(sql, employee.getId(), employee.getName(), employee.getAge(), employee.getGender());
    }

    @Override
    public void updateEmployee(Employee employee) {
        String sql = "update first_tb set name = ?,age = ?,gender = ? where id = ?";
        jdbcTemplate.update(sql, employee.getName(), employee.getAge(), employee.getGender(), employee.getId());
    }

    @Override
    public void deleteEmployee(Integer id) {

        String sql = "delete from first_tb where id = ?";
        jdbcTemplate.update(sql, id);
    }
}

测试类实现:(CRUD)

package org.example.springmvc;

import org.example.springmvc.bean.Employee;
import org.example.springmvc.dao.EmployeeDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class SpringTest {

    @Autowired
    EmployeeDao employeeDao;

    @Test
    public void test() {
        // 查
        Employee employee = employeeDao.getEmployeeById(1);
        System.out.println(employee);
        // 增删改
        employeeDao.addEmployee(new Employee(7, "超哥", 18, "男"));
        employeeDao.updateEmployee(new Employee(1, "贤哥", 18, "男"));
        employeeDao.deleteEmployee(5);

    }
}

二 Sercice层实现(处理业务逻辑)

结构图:

接口:

package org.example.springmvc.service;

import org.example.springmvc.bean.Employee;

public interface EmployeeService {

    // 根据id查询员工
    Employee getEmployeeById(Integer id);
    // 添加员工
    void addEmployee(Employee employee);
    // 修改员工
    void updateEmployee(Employee employee);
    // 删除员工
    void deleteEmployee(Integer id);
    
}

接口的实现类:(实现更新操作的非空判断)

package org.example.springmvc.service.Impl;


import org.example.springmvc.bean.Employee;
import org.example.springmvc.dao.EmployeeDao;
import org.example.springmvc.service.EmployeeService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    private final EmployeeDao employeeDao;

    // 注入dao
    public EmployeeServiceImpl(EmployeeDao EmployeeDao) {
        this.employeeDao = EmployeeDao;
    }

    @Override
    public Employee getEmployeeById(Integer id) {
        return employeeDao.getEmployeeById(id);
    }

    @Override
    public void addEmployee(Employee employee) {
        employeeDao.addEmployee(employee);
    }

    @Override
    public void updateEmployee(Employee employee) {
        //防空处理,考虑到service是被controller调用的,所以要考虑某些属性是空的,需要进行处理
        //1 去数据库查询到原来的值
        //2 把页面带来的值覆盖原来的值,页面没带的保持原状
        Integer id = employee.getId();
        if (id == null) {
            return;
        }
        // 获取数据库当中的
        Employee employeeById = employeeDao.getEmployeeById(id);
        //传过来的值不是空串,将值传递给数据库
        if (StringUtils.hasText(employee.getName())) {
            employeeById.setName(employee.getName());
        }
        if (StringUtils.hasText(employee.getGender())) {
            employeeById.setGender(employee.getGender());
        }
        if (employee.getAge() != null) {
            employeeById.setAge(employee.getAge());
        }
        employeeDao.updateEmployee(employeeById);

    }

    @Override
    public void deleteEmployee(Integer id) {
        employeeDao.deleteEmployee(id);
    }
}

测试类:

    @Autowired
    EmployeeService employeeService;

    @Test
    public void test1() {
        Employee employee = new Employee();
        employee.setId(7);
        employee.setAge(100);
        employeeService.updateEmployee(employee);
    }

三 Controller层(处理http请求)

代码实现:

    /**
     * 统一返回JSON
     * code: 说明:业务状态码,前后端商定不同的业务状态吗
     * msg: 说明:提示信息,前端根据业务状态码和提示信息进行业务逻辑处理
     * data: 说明:返回的数据
     * 前端统一处理业务逻辑,根据业务状态码和提示信息进行业务逻辑处理
     * 1 前端发送请求
     * 2 判断状态码,成功就显示数据,失败就提示提示信息(或其它操作)
     *
     */
package org.example.springmvc.common;

public class R<T> {
    private final Integer code;
    private final String msg;
    private final T data;

    // 私有化构造器,强制通过静态工厂方法创建对象
    private R(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    // -------------------- 成功响应快捷方法 --------------------
    public static R<?> ok() {
        return new R<>(200, "success", null);
    }

    public static <T> R<T> ok(T data) {
        return new R<>(200, "success", data);
    }

    public static <T> R<T> ok(String msg, T data) {
        return new R<>(200, msg, data);
    }

    // -------------------- 错误响应快捷方法 --------------------
    public static R<?> error(int code, String msg) {
        return new R<>(code, msg, null);
    }

    public static R<?> error(ErrorCode errorCode) {
        return new R<>(errorCode.getCode(), errorCode.getMsg(), null);
    }

    // -------------------- 链式构建方法(可选) --------------------
    public R<T> withMsg(String msg) {
        return new R<>(this.code, msg, this.data);
    }

    public R<T> withData(T data) {
        return new R<>(this.code, this.msg, data);
    }

    // -------------------- Getter --------------------
    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public T getData() {
        return data;
    }

    // -------------------- 状态码枚举(可选) --------------------
    public enum ErrorCode {
        BAD_REQUEST(400, "参数错误"),
        UNAUTHORIZED(401, "未授权"),
        NOT_FOUND(404, "资源不存在"),
        INTERNAL_ERROR(500, "服务器内部错误");

        private final int code;
        private final String msg;

        ErrorCode(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        public int getCode() {
            return code;
        }

        public String getMsg() {
            return msg;
        }
    }
}

需求类:

package org.example.springmvc.controller;

import org.example.springmvc.bean.Employee;
import org.example.springmvc.common.R;
import org.example.springmvc.service.EmployeeService;
import org.springframework.web.bind.annotation.*;

@RestController
public class EmployeeRestController {

    EmployeeService employeeService;

    // 构造器注入
    public EmployeeRestController(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    // 根据id查询员工
    // @RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)
    @GetMapping(value = "/employee/{id}")
    public R get(@PathVariable("id") Integer id) {
        Employee employeeById = employeeService.getEmployeeById(id);
        return R.ok(employeeById);
    }

    // 根据id删除员工
    // @RequestMapping(value = "/employee/{id}", method = RequestMethod.POST)
    @DeleteMapping(value = "/employee/{id}")
    public R delete(@PathVariable("id") Integer id) {
        employeeService.deleteEmployee(id);
        return R.ok();
    }

    // 添加员工,前端发送请求,把 json 数据封装到 Employee 对象中
    @PostMapping(value = "/employee")
    public R add(@RequestBody Employee employee) {
        employeeService.addEmployee(employee);
        return R.ok();
    }

    // 修改员工
    @PutMapping(value = "/employee")
    public R update(@RequestBody Employee employee) {
        employeeService.updateEmployee(employee);
        return R.ok();
    }

}

四 补充知识点

1 @PathVariable - 路径变量

2 @CrossOrigin(Origins = "*")允许跨域访问

3 可以在路径之前加上需要访问的路径


http://www.kler.cn/a/590146.html

相关文章:

  • 【从零开始学习计算机科学】算法分析(三)动态规划 与 贪心算法
  • STM32---FreeRTOS事件标志组
  • 数学建模:MATLAB循环神经网络
  • PostgreSQL教程(二)九大类型
  • 第27周JavaSpringboot git初识
  • 如何在Django中设置CSRF Token?
  • 【计算机网络】浏览器组成、工作原理、页面渲染流程...
  • 什么是 Fisher 信息矩阵
  • JDBC数据库连接池技术详解——从传统连接方式到高效连接管理
  • Android Dagger2 框架注入模块源码深度剖析(四)
  • matlab图论分析之指标计算(二)
  • CSS @media print 使用详解
  • Flutter_学习记录_状态管理之GetX
  • 通过物联网与可视化技术搭建的智慧工地管理云平台,java智慧工地源代码,企业级源码
  • OpenManus 架构的详细技术实现
  • 算法——图论——最短路径(多边权)
  • 优化VsCode终端样式
  • 【前端动态列表渲染:如何正确管理唯一标识符(Key)?】
  • 设计模式Python版 模板方法模式(下)
  • React封装axios请求方法