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

记录一点开发技巧

记录一个开发常见的风格

1.RESTful

好的,我们来详细讲解一下 RESTful(通常写作 RESTfulREST)架构风格。这是现代 Web 服务和 API 设计的核心范式。


什么是 RESTful?

RESTREpresentational State Transfer)是一种软件架构风格,由 Roy Fielding 在 2000 年提出。它定义了一套约束条件,用于创建可扩展、松耦合的网络服务(Web APIs)。

RESTful 是指符合 REST 原则的 API 或服务。


RESTful API 关键设计

1. 资源(Resources)
  • 所有数据抽象为资源(用户、订单、产品等)
  • URI(统一资源标识符) 定位资源
    示例
    • /books → 所有书籍
    • /books/42 → ID=42 的书籍
2. HTTP 方法(动词)
方法作用幂等性示例
GET获取资源GET /users
POST创建新资源POST /users
PUT更新/替换整个资源PUT /users/1
PATCH部分更新资源PATCH /users/1
DELETE删除资源DELETE /users/1

幂等性:多次执行效果相同(如重复 PUT 不改变结果)

3. 状态码(Status Codes)

用 HTTP 状态码表示结果:

  • 200 OK:成功
  • 201 Created:资源创建成功
  • 400 Bad Request:客户端错误
  • 401 Unauthorized:未认证
  • 404 Not Found:资源不存在
  • 500 Internal Server Error:服务器错误

一个完整的 RESTful 示例

用户管理 API
功能HTTP 方法URI说明
获取所有用户GET/users返回用户列表
创建用户POST/users提交新用户数据
获取单个用户GET/users/{id}返回 ID 对应的用户
更新用户PUT/users/{id}替换整个用户数据
部分更新PATCH/users/{id}只更新指定字段(如邮箱)
删除用户DELETE/users/{id}删除该用户

常见误区

  • ❌ 用动词命名 URI(如 /getUser → 应改用 GET /users
  • ❌ 忽略 HTTP 状态码(所有响应都返回 200
  • ❌ 在 GET 请求中使用 Body 传递参数
  • ❌ 返回 HTML 页面而非结构化数据(JSON/XML)

示例代码:

@Data
public class Result<T> implements Serializable {private Integer code; //编码:1成功,0和其它数字为失败private String msg; //错误信息private T data; //数据public static <T> Result<T> success() {Result<T> result = new Result<T>();result.code = 1;return result;}public static <T> Result<T> success(T object) {Result<T> result = new Result<T>();result.data = object;result.code = 1;return result;}public static <T> Result<T> success(String msg,T object) {Result<T> result = new Result<T>();result.data = object;result.msg = msg;result.code = 1;return result;}public static <T> Result<T> error(String msg) {Result result = new Result();result.msg = msg;result.code = 0;return result;}}@PostMapping("/upload")public Result<String> uploadFile(@RequestParam("file") MultipartFile file) {boolean saved = markdownDocsService.saveFile(file);if (saved)return Result.success("上传成功");return Result.error("上传失败");}

2.全局异常处理

1.我们定义一个异常的枚举类用来返回异常信息

@Getter
@AllArgsConstructor
@ToString
public enum ResponseEnum {SUCCESS(1, "成功"),ERROR(-1, "服务器内部错误"),//-1xx 服务器错误BAD_SQL_GRAMMAR_ERROR(-101, "sql语法错误"),SERVLET_ERROR(-102, "servlet请求异常"), //-2xx 参数校验DELETE_FILE_FAILED(103, "删除文件错误"),UPLOAD_ERROR(-103, "文件上传错误"),EXPORT_DATA_ERROR(104, "数据导出失败"),DATA_NOt_EXISITS(105, "数据不存在"),PARAM_IS_NULL_ERROR(-105, "参数不能为空"),IMPORT_DATA_ERROR(106, "数据导入失败"),FILE_IS_EMPTY(107, "上传文件内容为空"),DISALLOW_DELETE_DATA(108, "该数据有关联数据不能删除"),TOO_MANY_REQUESTS(109, "请求太频繁了"),//-2xx 参数校验USRE_ID_NULL_ERROR(-201, "用户Id不能为空"),MOBILE_NULL_ERROR(-202, "手机号码不能为空"),MOBILE_ERROR(-203, "手机号码不正确"),PASSWORD_NULL_ERROR(204, "密码不能为空"),CODE_NULL_ERROR(205, "验证码不能为空"),CODE_ERROR(206, "验证码错误"),MOBILE_EXIST_ERROR(207, "手机号已被注册"),LOGIN_MOBILE_ERROR(208, "用户不存在"),LOGIN_PASSWORD_ERROR(209, "密码错误"),LOGIN_LOKED_ERROR(210, "用户被锁定"),LOGIN_AUTH_ERROR(-211, "未登录"),REGISTER_FAIL(212, "注册失败"),USER_REPEAT(-212, "重复注册"),USER_PWD_ERROR(213, "用户密码错误"),ACCOUNT_UNREGISTER(-213, "用户未注册"),ACCOUNT_UNLOGIN(214, "用户未登录"),USER_NOT_EXIST(215, "用户不存在"),USER_ISNOT_ROLE(215, "用户角色不匹配"),USERNAME_IS_EXIST(216, "用户名已存在"),ORG_NOT_EXIST(217, "机构信息不存在"),DELETE_SUCCESS(218, "删除成功"),DELETE_FAIL(219, "删除失败"),UPDATE_SUCCESS(220, "更新成功"),UPDATE_FAIL(221, "更新失败"),UPDATE_ERROR(222, "更新操作异常"),USER_BIND_IDCARD_EXIST_ERROR(-301, "身份证号码已绑定"),USER_NO_BIND_ERROR(302, "用户未绑定"),LEND_INVEST_ERROR(305, "当前状态无法投标"),LEND_FULL_SCALE_ERROR(306, "已满标,无法投标"),NOT_SUFFICIENT_FUNDS_ERROR(307, "余额不足,请充值"),PAY_UNIFIEDORDER_ERROR(401, "统一下单错误"),ALIYUN_SMS_LIMIT_CONTROL_ERROR(-502, "短信发送过于频繁"),//业务限流ALIYUN_SMS_ERROR(-503, "短信发送失败"),//其他失败WEIXIN_CALLBACK_PARAM_ERROR(-601, "回调参数不正确"),WEIXIN_FETCH_ACCESSTOKEN_ERROR(-602, "获取access_token失败"),WEIXIN_FETCH_USERINFO_ERROR(-603, "获取用户信息失败"),USER_TYPE_ERROR(-604, "用户信息异常"),;private final Integer code;//状态码private final String message;//消息ResponseEnum(int code, String message) {this.code = code;this.message = message;}
}

2.自定义一个异常类

/*** 业务异常*/
@Getter
public class BusinessException extends RuntimeException {//状态码private Integer code;public BusinessException(String message, Integer code) {super(message);this.code = code;}public BusinessException(ResponseEnum responseEnum) {super(responseEnum.getMessage());this.code = responseEnum.getCode();}public BusinessException(ResponseEnum responseEnum, Throwable cause) {super(responseEnum.getMessage(),cause);this.code = responseEnum.getCode();}
}

3.全局异常处理

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 未定义异常处理*/@ExceptionHandler(Exception.class)public Result<Object> exception(Exception e) {log.error(e.getMessage(), e);return Result.error("系统异常");}/*** 参数绑定异常处理*/@ExceptionHandler(BindException.class)public Result<Object> handleBindException(BindException e) {return Result.error(e.getMessage());}@ExceptionHandler(ExecutionException.class)public Result<Object> handleExecutionException(ExecutionException e) {log.error(e.getMessage(), e);Result<Object> result = new Result<>();result.setMsg(REGISTER_FAIL.getMessage());result.setCode(REGISTER_FAIL.getCode()); // 设置特定错误码return result;}/*** 自定义业务异常处理*/@ExceptionHandler(BusinessException.class)public Result<Object> handleBusinessException(BusinessException e) {log.error(e.getMessage(), e.getCause());Result<Object> result = Result.error(e.getMessage());result.setCode(e.getCode()); // 设置自定义错误码return result;}@ExceptionHandler(NotLoginException.class)public Result <Object> handleNotLoginException(NotLoginException e) {log.error(e.getMessage(), e);Result<Object> result = Result.error(ResponseEnum.ACCOUNT_UNLOGIN.getMessage());result.setCode(ResponseEnum.ACCOUNT_UNLOGIN.getCode()); // 设置特定错误码return result;}@ExceptionHandler(SQLException.class)public Result<Object> handleSQLException(SQLException e) {log.error(e.getMessage(), e);Result<Object> result = Result.error(ResponseEnum.IMPORT_DATA_ERROR.getMessage());result.setCode(ResponseEnum.IMPORT_DATA_ERROR.getCode()); // 设置特定错误码return result;}/*** Servlet请求相关异常处理*/@ExceptionHandler({NoHandlerFoundException.class,HttpRequestMethodNotSupportedException.class,HttpMediaTypeNotSupportedException.class,MissingPathVariableException.class,MissingServletRequestParameterException.class,HttpMessageNotReadableException.class,HttpMessageNotWritableException.class,MethodArgumentNotValidException.class,HttpMediaTypeNotAcceptableException.class,ServletRequestBindingException.class,ConversionNotSupportedException.class,MissingServletRequestPartException.class,AsyncRequestTimeoutException.class})public Result<Object> handleServletException(Exception e) {log.error(e.getMessage(), e);Result<Object> result = Result.error(ResponseEnum.SERVLET_ERROR.getMessage());result.setCode(ResponseEnum.SERVLET_ERROR.getCode()); // 设置特定错误码return result;}}

4.在处理业务是我们就可以利用抛出异常的方法处理错误情况


public MarkdownDocsServiceImpl() {try {// 使用 ClassPathResource 确保路径正确指向 resources/document 目录ClassPathResource resource = new ClassPathResource(MD_SAVE_PATH);this.rootLocation = resource.getFile().toPath();} catch (Exception e) {throw new RuntimeException("初始化文件存储路径失败: " + MD_SAVE_PATH, e);}}

3.讲到这里了,再给大家讲一个 ClassPathResour

这个我也是今天刚用,很神奇,我的业务需求是我想存储前端的md文件到我的项目中下次启动的时候可以进行处理,当然还要立刻处理一下,存储是为了持久化,数据库我也想过,暂时还没有实现,我先尝试了这一种

ClassPathResource resource = new ClassPathResource(MD_SAVE_PATH);
String MD_SAVE_PATH ="classpath:document"

他会把文件存储到target的classes里面,很神奇我还在研究它的原理,

http://www.dtcms.com/a/268380.html

相关文章:

  • Spring Boot 3.x 整合 Swagger(springdoc-openapi)实现接口文档
  • class类和style内联样式的绑定 + 事件处理 + uniapp创建自定义页面模板
  • React Ref 指南:原理、实现与实践
  • 深度学习篇---Yolov系列
  • 远程桌面启动工具
  • Flutter 每日翻译之 Widget
  • Day53GAN对抗生成网络思想
  • MySQL主从复制与读写分离概述
  • 一文了解PMI、CSPM、软考、、IPMA、PeopleCert和华为项目管理认证
  • Protein FID:AI蛋白质结构生成模型评估新指标
  • Redis-主从复制-分布式系统
  • 算法学习day15----蓝桥杯--进制转换
  • Web攻防-XMLXXE无回显带外SSRF元数据DTD实体OOB盲注文件拓展
  • 大数据Hadoop之——Flink1.17.0安装与使用(非常详细)
  • 桥梁桥拱巡检机器人cad+【4张】设计说明书+绛重+三维图
  • 了解微服务
  • JVM的内存区域划分,类加载器和GC
  • Modbus 与 BACnet 协议互操作:工业协议转换方案(一)
  • JavaSE -- 泛型详细介绍
  • 【机器学习笔记 Ⅱ】2 神经网络中的层
  • HCIA-生成数协议(STP)
  • Debezium日常分享系列之:Debezium管理平台
  • 【Elasticsearch入门到落地】15、DSL排序、分页及高亮
  • golang 协程 如何中断和恢复
  • WHAT - 依赖管理工具 CocoaPods
  • 从小白到进阶:解锁linux与c语言高级编程知识点嵌入式开发的任督二脉(1)
  • 如何确保Kafka集群的高可用?
  • 【MySQL】DTS机制对触发器时间的影响
  • Python-可视化学习笔记
  • 【机器学习笔记Ⅰ】3 代价函数