SpringMVC(四)Restful软件架构风格

news/2025/3/17 3:38:24/

目录

​编辑

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类,用来放数据库用户的信息

java">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() {}@Overridepublic String toString() {return "Employee{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +'}';}
}

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

java">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);}

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

java">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;// 注入JdbcTemplatepublic EmployeeDaoImpl(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic Employee getEmployeeById(Integer id) {String sql = "select * from first_tb where id = ?";return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Employee.class), id);}@Overridepublic 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());}@Overridepublic 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());}@Overridepublic void deleteEmployee(Integer id) {String sql = "delete from first_tb where id = ?";jdbcTemplate.update(sql, id);}
}

测试类实现:(CRUD)

java">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 {@AutowiredEmployeeDao employeeDao;@Testpublic 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层实现(处理业务逻辑)

结构图:

接口:

java">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);}

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

java">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;// 注入daopublic EmployeeServiceImpl(EmployeeDao EmployeeDao) {this.employeeDao = EmployeeDao;}@Overridepublic Employee getEmployeeById(Integer id) {return employeeDao.getEmployeeById(id);}@Overridepublic void addEmployee(Employee employee) {employeeDao.addEmployee(employee);}@Overridepublic 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);}@Overridepublic void deleteEmployee(Integer id) {employeeDao.deleteEmployee(id);}
}

测试类:

java">    @AutowiredEmployeeService employeeService;@Testpublic void test1() {Employee employee = new Employee();employee.setId(7);employee.setAge(100);employeeService.updateEmployee(employee);}

三 Controller层(处理http请求)

代码实现:

java">    /*** 统一返回JSON* code: 说明:业务状态码,前后端商定不同的业务状态吗* msg: 说明:提示信息,前端根据业务状态码和提示信息进行业务逻辑处理* data: 说明:返回的数据* 前端统一处理业务逻辑,根据业务状态码和提示信息进行业务逻辑处理* 1 前端发送请求* 2 判断状态码,成功就显示数据,失败就提示提示信息(或其它操作)**/
java">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;}}
}

需求类:

java">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.ppmy.cn/news/1579726.html

相关文章

基于变分推理与 Best‑of‑N 策略的元 Prompt 自动生成与优化框架

摘要 本文提出了一种融合变分推理与 Best‑of‑N 策略的元 Prompt 自动生成与优化框架&#xff0c;通过高度参数化的模板、随机扰动采样及多指标评分机制&#xff0c;实现从初始提示生成到最终输出的动态优化。同时&#xff0c;针对实际应用中对自适应参数调整、深层语义理解、…

《黑客攻防从入门到精通:工具篇》全15章万字深度总结——从工具解析到实战攻防,构建完整网络安全知识体系

目录 一、书籍核心逻辑与学习路径 二、核心模块与工具深度解析 模块1&#xff1a;信息收集与网络扫描 模块2&#xff1a;渗透测试与漏洞利用 模块3&#xff1a;密码攻防与身份认证 模块4&#xff1a;恶意程序攻防 模块5&#xff1a;网络追踪与反追踪 模块6&#xff1a;系…

Spring Security 的认证核心组件

文章目录 一、认证体系核心组件1.1 认证令牌&#xff08;Authentication&#xff09;1.1.1 UsernamePasswordAuthenticationToken 的核心参数1.1.2 核心参数详解1.1.2.1 principal&#xff08;身份标识&#xff09;1.1.2.2 credentials&#xff08;凭证信息&#xff09; 1.2 认…

elementui table 自动滚动 纯js实现

startTableScroll() {// 获取表格滚动容器const tableWrapper this.$refs.tableRef.$el.querySelector(.el-table__body-wrapper);if (tableWrapper) {this.scrollInterval setInterval(() > {// 每次滚动 1 像素tableWrapper.scrollTop 1;// 判断是否滚动到底部if (tabl…

DeepSeek + Excel:数据处理专家 具体步骤

将DeepSeek与Excel结合使用&#xff0c;可显著提升数据处理效率&#xff0c;实现智能化的数据分析、清洗、计算及可视化。以下是具体操作步骤及核心技巧的综合指南&#xff1a; 一、接入DeepSeek的两种主要方法 1. 插件接入法&#xff08;推荐&#xff09; 步骤1&#xff1a;…

R语言的链表合并

R语言的链表合并 在计算机科学中&#xff0c;链表是一种常用的数据结构&#xff0c;通过节点&#xff08;node&#xff09;来动态存储数据。与传统的数组不同&#xff0c;链表的每个元素&#xff08;节点&#xff09;都包含指向下一个元素的指针&#xff0c;这种结构使得插入和…

高级线程管理_第九章_《C++并发编程实战》笔记

高级线程管理 1. 线程池&#xff08;Thread Pool&#xff09;1.1 线程池结构要素1.2 线程池实现步骤 2. 线程中断&#xff08;Interruptible Threads&#xff09;2.1 中断机制实现 多选题多选题答案设计题目设计题目答案 1. 线程池&#xff08;Thread Pool&#xff09; 核心目…

论文笔记 - ULTRA-SPARSE MEMORY NETWORK

1、目前Transformer模型现状 dense模型相同激活参数下&#xff0c;性能远低于MOE模型&#xff0c;因此大家倾向于训练MOE模型虽然同激活参数下&#xff0c;MOE性能比dense好&#xff0c;但MOE模型内存访问高&#xff0c;因此推理速度相比dense要慢不少。比如top2的moe&#xf…