抛出异常时将异常信息返给前端

2023-05-16

 

全局异常处理器负责将抛出的异常,以统一的格式返给前端。在这里起主要作用的注解是@RestControllerAdvice。

@RestControllerAdvice主要配合@ExceptionHandler使用,统一处理异常情况。
1、@RestControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。
2、@RestControllerAdvice 是组件注解,他使得其实现类能够被classpath扫描自动发现,如果应用是通过MVC命令空间或MVC Java编程方式配置,那么该特性默认是自动开启的。

例如:

 当抛出BizException时,会自动返回ReturnResult.error(...)。这样,在真正的业务中,我们只需要返回ReturnResult.success(...)就可以了。

目录结构:

 

具体代码:

import com.sugon.cloud.lowcode.result.ReturnResult;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.naming.AuthenticationException;
import javax.servlet.http.HttpServletRequest;

import static com.sugon.cloud.lowcode.constants.SplitCharacter.LEFT_PARENTHESES;
import static com.sugon.cloud.lowcode.constants.SplitCharacter.RIGHT_PARENTHESES;
import static com.sugon.cloud.lowcode.result.CodeMessageEnum.*;

/**
 *  全局异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

  /**
   * 业务异常类
   *
   */
  @ExceptionHandler(value = BizException.class)
  @ResponseBody
  public ReturnResult bizExceptionHandler(HttpServletRequest req, BizException e) {
    log.error("发生业务异常: {}, 请求接口: {}", e.getMessage(), req.getRequestURI());
    return ReturnResult.error(e.getCode(), e.getMessage());
  }


  /**
   * 空指针异常
   *
   * @param e 异常信息
   * @param req 请求
   */
  @ExceptionHandler(value = NullPointerException.class)
  @ResponseBody
  public ReturnResult exceptionHandler(HttpServletRequest req, NullPointerException e) {
    log.error("空指针异常信息: {}, 请求接口: {}", e, req.getRequestURI());
    return ReturnResult.error(
        NULL_POINT_ERROR_EXCEPTION.getCode(),
        NULL_POINT_ERROR_EXCEPTION.getMessage()
            + RIGHT_PARENTHESES
            + e.getMessage()
            + LEFT_PARENTHESES);
  }

  /**
   * 接口请求方法异常
   *
   */
  @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
  @ResponseBody
  public ReturnResult methodNotSupportedExceptionHandler(HttpServletRequest req, Exception e) {
    log.error("请求方法异常信息: {},请求接口: {}", e, req.getRequestURI());
    return ReturnResult.error(
        REQUEST_METHOD_ERROR.getCode(),
        REQUEST_METHOD_ERROR.getMessage() + RIGHT_PARENTHESES + e.getMessage() + LEFT_PARENTHESES);
  }

  /**
   * SQL 语法错误异常
   *
   */
  @ExceptionHandler(value = MyBatisSystemException.class)
  @ResponseBody
  public ReturnResult sqlSyntaxErrorExceptionHandler(HttpServletRequest req, Exception e) {
    log.error("MyBatis系统异常信息: {},请求接口: {}", e, req.getRequestURI());
    return ReturnResult.error(
        INNER_FRAME_EXCEPTION.getCode(),
        INNER_FRAME_EXCEPTION.getMessage() + RIGHT_PARENTHESES + e.getMessage() + LEFT_PARENTHESES);
  }

  @ExceptionHandler(value = AuthenticationException.class)
  public ReturnResult incorrectCredentialsException(
      HttpServletRequest request, AuthenticationException e) {
    log.error("用户名或密码不正确: {}, 请求接口: {}", e, request.getRequestURI());
    return ReturnResult.error(USER_CREDENTIALS_ERROR);
  }

  @ExceptionHandler(value = UserException.class)
  public ReturnResult incorrectUserException(HttpServletRequest request, UserException e) {
    log.error("用户信息异常: {}, 请求接口: {}", e, request.getRequestURI());
    return ReturnResult.error(e.getCode(), e.getMessage());
  }

  /**
   * 其他异常信息
   *
   * @param req
   * @param e
   */
  @ExceptionHandler(value = Exception.class)
  @ResponseBody
  public ReturnResult exceptionHandler(HttpServletRequest req, Exception e) {
    e.printStackTrace();
    log.error("未知异常: {}, 请求接口: {}", e, req.getRequestURI());
    return ReturnResult.error(
        INTERNAL_SERVER_ERROR.getCode(),
        INTERNAL_SERVER_ERROR.getMessage() + RIGHT_PARENTHESES + e.getMessage() + LEFT_PARENTHESES);
  }
}

自定义的业务异常类:

import com.sugon.cloud.lowcode.result.BaseResultInterface;
import com.sugon.cloud.lowcode.result.CodeMessageEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

/**
 * @desc 业务异常类
 */
@ApiModel(description= "业务异常数据")
public class BizException extends RuntimeException implements BaseResultInterface {

    private static final long serialVersionUID = 1L;


    /**
     * 错误码
     */
    @ApiModelProperty(value = "错误码")
    private String code;

    /**
     * 错误信息
     */
    @ApiModelProperty(value = "错误信息")
    private String message;

    public BizException() {
        super();
    }

    public BizException(CodeMessageEnum codeMessageEnum) {
        super(codeMessageEnum.getCode());
        this.code = codeMessageEnum.getCode();
        this.message = codeMessageEnum.getMessage();
    }

    public BizException(CodeMessageEnum codeMessageEnum, Throwable cause) {
        super(codeMessageEnum.getCode(), cause);
        this.code = codeMessageEnum.getCode();
        this.message = codeMessageEnum.getMessage();
    }

    public BizException(CodeMessageEnum codeMessageEnum, String message, Throwable cause) {
        super(codeMessageEnum.getCode(), cause);
        this.code = codeMessageEnum.getCode();
        this.message = message;
    }

    public BizException(String message) {
        super(message);
        this.message = message;
    }

    public BizException(String code, String message) {
        super(code);
        this.code = code;
        this.message = message;
    }

    public BizException(String code, String message, Throwable cause) {
        super(code, cause);
        this.code = code;
        this.message = message;
    }

    @Override
    public Throwable fillInStackTrace() {
        return this;
    }


    @Override
    public String getCode() {
        return this.code;
    }

    @Override
    public String getMessage() {
        return this.message;
    }
}


对象返回到前端以及异常抛出的接口类:

/**
 * @desc 对象返回到前端以及异常抛出的接口类
 */
public interface BaseResultInterface {

    /**
     * 获取返回代码值
     *
     * @author zby
     * @datetime 2022/11/29 15:23
     */
    String getCode();
    
    /**
     * 获取返回信息
     *
     * @author zby
     * @datetime 2022/11/29 10:26
     */
    String getMessage();
}

异常枚举类:

package com.sugon.cloud.lowcode.result;

import com.sugon.cloud.lowcode.entity.vo.CodeVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;

import static org.apache.commons.lang3.StringUtils.isBlank;

/**
 * @desc 定义错误码编码的枚举类
 */
@ApiModel(description = "code码类")
@Api(tags = "code码管理")
public enum CodeMessageEnum implements BaseResultInterface {

  /** ********* 0000成功 *************** */
  SUCCESS("0000", "成功!"),
  SUCCESS_LOGIN("0001", "用户登录成功"),
  SUCCESS_LOGOUT("0002", "用户退出成功"),

  /* 默认失败 */
  COMMON_FAIL("999", "失败"),

  /** ********* 1xxx系统错误 *************** */
  SERVER_BUSY("1001", "服务器正忙,请稍后再试!"),
  INTERNAL_SERVER_ERROR("1002", "服务器内部错误"),
  NOT_FOUND("1003", "未找到该资源!"),
  REQUEST_METHOD_ERROR("1004", "接口请求方法异常"),
  SQL_SYNTAX_ERROR_EXCEPTION("1005", "SQL语法错误异常"),
  NULL_POINT_ERROR_EXCEPTION("1006", "空指针异常信息"),
  INNER_FRAME_EXCEPTION("1007", "内部框架执行异常"),
  PARSE_TOKEN_EXCEPTION("1008", "解析token异常"),
  TOKEN_NOT_EXIST("1009", "token不存在"),
  TOKEN_SIGNATURE_EXCEPTION("1010", "token签名异常"),
  TOKEN_EXPIRE("1011", "token过期,请重新登录"),
  IMG_TYPE_NOT_CONFIG("1012", "请配置图片类型"),
  NOT_CONFIG_FILE_DIR("1013", "请配置文件路径"),
  UPLOAD_FILE_ERROR("1014", "文件上传失败"),
  FILE_NOT_EXIST("1015", "文件不存在"),
  FILE_HAS_DELETED("1016", "文件已被删除"),
  DRIVER_CLASS_NOT_FOUND("1017", "数据库的连接驱动正在加载中..."),
  TRY_CONNECT_DATABASE_ERROR("1018", "尝试连接数据库失败"),
  CLOSE_CONNECT_DATABASE_ERROR("1019", "关闭数据库连接失败"),
  DATABASE_NAME_NOT_EXIST("1020", "数据库名称不存在"),
  CLOSE_DATASOURCE_ERROR("1021", "释放数据库资源异常"),
  DRUID_DATASOURCE_ERROR("1022", "数据源创建中..."),
  CREATE_DATABASE_ERROR("1023", "创建数据库失败"),
  CREATE_TABLE_ERROR("1024", "创建表失败"),
  UPDATE_TABLE_FIELD_ERROR("1025", "更新表字段失败"),
  DELETE_TABLE_FIELD_ERROR("1026", "删除表字段失败"),
  QUERY_ROLE_ERROR("1027", "查询角色失败"),
  UPDATE_GROUP_ERROR("1028", "更新接口组失败"),
  DELETE_GROUP_ERROR("1029", "删除接口组失败"),
  SAVE_INTERFACE_ERROR("1030", "保存接口信息失败"),

  /**
   * ******2xxx参数错误 *********************
   */
  BODY_NOT_MATCH("2001", "请求的数据格式不符"),
  SIGNATURE_NOT_MATCH("2002", "请求的数字签名不匹配!"),
  REQUEST_PATH_NOT_MATCH("2003", "当前请求路径没有权限!"),
  NOT_UPLOAD_FILE_NAME_ERROR("2004", "上传的文件名不存在,请重新上传"),
  NOT_SUPPORT_IMG_TYPE("2005", "图片格式不正确,请重新上传"),
  NOT_SUPPORT_USERNAME_TYPE("2006", "excel用户名不能为空"),
  NOT_SUPPORT_ROLE_TYPE("2007", "角色不存在"),
  NOT_SUPPORT_DEPT_TYPE("2008", "部门不存在"),
  SQL_INJECT_NOT_ALLOWED("2009", "参数中存在数据库关键字,请修改"),
  TABLE_FIELD_NOT_EXIST("2010", "表字段不存在"),

  /** *********** 3xxx用户错误 ******************* */
  USER_NOT_LOGIN("3001", "用户未登录"),
  USER_ACCOUNT_EXPIRED("3002", "账号已过期"),
  USER_CREDENTIALS_ERROR("3003", "用户名或密码错误"),
  USER_CREDENTIALS_EXPIRED("3004", "密码过期"),
  USER_ACCOUNT_NOT_BIND_ENTERPRISE("3005", "当前账号未绑定企业"),
  USER_ACCOUNT_LOCKED("3006", "账号被锁定"),
  USER_ACCOUNT_NOT_EXIST("3007", "账号不存在"),
  USER_ACCOUNT_ALREADY_EXIST("3008", "账号已存在"),
  USER_ACCOUNT_USE_BY_OTHERS("3009", "账号下线"),
  USER_NO_PERMISSION("3010", "当前账号没有此权限"),
  USERNAME_NOT_BLANK("3011", "用户不能为空"),
  USER_LOGIN_ERROR("3012", "用户登录失败"),
  USER_LOGOUT_ERROR("3013", "用户退出失败"),
  USER_ACCOUNT_USE_BY_OTHERS_ERROR("3014", "账号下线异常"),
  USER_ACCESS_DENIED("3015", "权限认证失败"),
  USERNAME_EXIST_ERROR("3016", "用户名重名"),

  ROLE_NAME_ALREADY_EXIST("3101", "角色已存在"),

  /** ********** 4xxx业务错误 *********************** */
  ENTERPRISE_NOT_EXIST("4001", "当前企业不存在"),
  APP_KEY_EXIST("4002", "应用key已存在"),
  APP_NOT_EXIST("4003", "应用不存在"),
  APP_PAGE_NAME_EXIST("4004", "当前页面名称已存在"),
  APP_PAGE_KEY_EXIST("4005", "当前页面key已存在"),
  APP_PAGE_NOT_EXIST("4006", "当前页面不存在,或已删除"),
  APP_PAGE_TYPE_ERROR("4007", "页面类型有误"),
  APP_PAGE_HOME_IS_NOT_EXIST("4008", "请设置首页"),
  CAN_NOT_DELETE_HOME_PAGE("4009", "请勿删除首页"),
  DELETE_PAGE_ERROR("4010", "删除页面失败"),
  CONFIG_CUSTOM_ERROR("4011", "配置自定义页面失败"),
  APP_PAGE_PARENT_NOT_EXIST("4012", "当前页面的父级页面不存在,或已删除"),
  DATASOURCE_NAME_EXIST("4013", "当前数据源名称已经存在,请修改后重试"),
  DATASOURCE_NOT_EXIST("4014", "当前数据源不存在"),
  DATASOURCE_HAS_DELETED("4015", "当前数据源已删除"),
  MODEL_NOT_EXIST("4016", "当前模型不存在"),
  MODEL_HAS_DELETED("4017", "当前模型已删除"),
  MODEL_NAME_HAS_EXIST("4018", "当前模型名称已存在"),
  DATASOURCE_NOT_CONFIG("4019", "数据源配置为空,请联系管理员"),
  DATASOURCE_NOT_CONFIG_DIALECT("4020", "未配置数据源的类型"),
  DATASOURCE_NOT_CONFIG_DRIVER_CLASS_NAME("4021", "未配置数据源的驱动"),
  DEPT_USER_EXIST("4022", "部门下存在用户"),
  NOT_CONFIG_PAGE_BUTTON_TYPE("4023", "未配置按钮雷星"),
  MODEL_PAGE_RELATION_MODEL("4024", "已关联当前模型页面"),
  MODEL_PAGE_NOT_EXIST("4025", "模型页面不存在或已被删除"),
  MODEL_HAS_RELATION_MODEL_PAGE("4026", "当前模型已关联模型页面,不允许删除"),
  FORM_NOT_EXIST("4027", "模型表单不存在"),
  READ_FILE_ERROR("4028", "读取模型页面的模板文件失败"),
  MODEL_PAGE_CONTENT_NULL("4029", "未配置模型页面的模板文件"),
  NOT_CONFIG_QUERY_SQL("4030", "未配置查询语句"),
  APP_PAGE_BUTTON_OPTION_VALUE_ERROR("4031", "未配置接口"),
  DELETE_COLUMN_ERROR("4032", "删除当前失败"),
  INSERT_DATA_ERROR("4033", "新建数据失败"),
  EDIT_DATA_ERROR("4034", "编辑数据失败"),
  DATASOURCE_HAS_MODELS("4035", "当前数据源存在模型,不允许删除"),
  NOT_CONFIG_FORM_API("4036", "未配置模型表单页的接口信息"),
  PLEASE_WRITE_AT_LEAST_DATA("4037", "请至少填写一行数据"),
  AMIS_PAGE_ERROR("4038", "分页参数异常"),
  QUERY_APP_PAGE_QUERY_FIELD_ERROR("4039", "查询搜素参数异常"),
  REQUEST_PARAM_NOT_IN_APP_PAGE_QUERY_FIELD("4040", "请求参数不在查询数据表中"),
  STYLE_LANGUAGE_ON_CSS("4041", "自定义css中的样式语言不能为空"),
  APP_CONFIG_TYPE_NOT_EXIST("4042", "不支持当前应用设置的类型"),
  APP_CONFIG_NOT_EXIST_OR_DELETED("4043", "当前设置不存在或已被删除"),
  APP_HAS_CONFIG_ON_THIS_TYPE("4044", "当前应用设置的类型已存在,请更新"),
  NOT_SUPPORT_COMPONENT_FRAME("4045", "不支持当前组件框架"),
  NOT_SUPPORT_COMPONENT_TYPE("4046", "不支持当前组件类型"),
  CURRENT_APP_KEY_EXIST("4047", "当前应用的组件key已存在"),
  CREATE_CUSTOM_COMPONENT_ERROR("4048", "新增自定义组件失败"),
  APP_CUSTOM_COMPONENT_NOT_EXIST("4049", "当前组件不存在或已被删除"),
  UPDATE_CUSTOM_COMPONENT_ERROR("4050", "更新自定义组件失败"),
  DELETED_CUSTOM_COMPONENT_ERROR("4051", "删除自定义组件失败"),
  INSERT_COMPONENT_DEPENDENCE_ERROR("4052", "新增自定义组件依赖项失败"),
  DELETE_COMPONENT_DEPENDENCE_ERROR("4053", "删除自定义组件依赖项失败"),
  CURRENT_COMPONENT_DEPENDENCE_NOT_EXIST("4054", "当前自定义组件依赖项不存在或已被删除"),
  CURRENT_APP_NAME_EXIST("4055", "当前应用的组件名称已存在"),
  NOT_SUPPORT_DATASOURCE_FROM("4056", "不支持当前的数据库来源"),
  JDBC_CONFIG_ERROR("4057", "平台内置的数据源配置有误"),
  NOT_SUPPORT_MODEL_TYPE("4058", "不支持当前的页面模板"),
  NOT_SUPPORT_CUSTOM_PAGE("4059", "暂不支持自定义页面"),
  FORM_PAGE_ON_DEVELOPING("4060", "自定义页面的该功能正在开发中..."),
  APP_PAGE_QUERY_FIELD_NOT_EXIST("4061", "当前查询条件不存在,或已被删除"),
  APP_PAGE_BUTTON_NOT_EXIST("4062", "当前页面按钮不存在,或已被删除"),
  TABLE_KEY_MORE_THEN_ONE("4063", "主键超过一个"),
  TABLE_KEY_LESS_THEN_ONE("4064", "主键必须存在"),
  TABLE_KEY_MUST_BE_INT("4065", "主键必须为整数类型"),
  TABLE_FIELD_MUST_EXIST("4066", "必须存在表字段"),
  CURRENT_MODEL_PAGE_HAS_CONVERSION_CUSTOM_PAGE("4067", "当前模型页面已转成自定义页面"),
  NOT_SUPPORT_RELEASE_STATUS("4068", "发布版本状态有误"),
  APP_FORM_BUTTON_NOT_EXIST("4067", "当前表单按钮不存在,或已被删除"),
  DATASOURCE_KEY_EXIST_ERROR("4068","数据源key已存在")
  ;

  CodeMessageEnum(String code, String message) {
    this.code = code;
    this.message = message;
  }

  /** 返回到前端的code值 */
  private String code;

  /** 返回到前端的code对应的message值 */
  private String message;

  @Override
  public String getCode() {
    return this.code;
  }

  @Override
  public String getMessage() {
    return this.message;
  }

  public static CodeVo getJsonObjectByCode(String code) {
    CodeVo codeVo = new CodeVo();
    if (isBlank(code)) {
      return codeVo;
    }
    for (CodeMessageEnum enumObj : CodeMessageEnum.values()) {
      if (enumObj.getCode().equals(code)) {
        return new CodeVo(code, enumObj.message);
      }
    }
    return codeVo;
  }
}

统一给前端的结果格式:

import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

import static com.sugon.cloud.lowcode.result.CodeMessageEnum.*;

/**
 * @author zby
 * @datetime 2022/12/2 10:23
 * @desc 返回给前端的对象值
 */
@Setter
@Getter
@ApiModel(description= "返回响应数据")
public class ReturnResult<T> {

  /** 响应代码 */
  @ApiModelProperty(value = "状态码")
  private String code;

  /** 响应消息 */
  @ApiModelProperty(value = "响应信息")
  private String message;

  /** 响应结果 */
  @ApiModelProperty(value = "响应对象")
  private T result;

  /** 返回成功还是失败 */
  @ApiModelProperty(value = "是否成功")
  private boolean success = true;

  public ReturnResult() {}

  public ReturnResult(CodeMessageEnum codeMessageEnum) {
    this.code = codeMessageEnum.getCode();
    this.message = codeMessageEnum.getMessage();
  }

  /**
   * 返回成功
   *
   * @author zby
   * @datetime 2022/12/2 10:29
   */
  public static ReturnResult success() {
    return success(null);
  }

  /**
   * 返回成功
   *
   * @param data 返回到前端的对象
   * @author zby
   * @datetime 2022/12/2 13:33
   */
  public static <T> ReturnResult<T> success(T data) {
    return success(SUCCESS, data);
  }

  /**
   * 登录成功
   *
   * @param data 返回到前端的对象
   * @author zby
   * @datetime 2022/12/2 13:50
   */
  public static <T> ReturnResult<T> loginSuccess(T data) {
    return success(SUCCESS_LOGIN, data);
  }

  /**
   * 退出成功
   *
   * @author zby
   * @datetime 2022/11/30 14:53
   */
  public static ReturnResult loginOutSuccess() {
    return success(SUCCESS_LOGOUT, null);
  }

  private static <T> ReturnResult<T> success(CodeMessageEnum codeMessageEnum, T data) {
    ReturnResult<T> result = new ReturnResult<>();
    result.setCode(codeMessageEnum.getCode());
    result.setMessage(codeMessageEnum.getMessage());
    result.setResult(data);
    return result;
  }

  /**
   * 返回失败
   *
   * @param codeMessageEnum 基础返回接口
   * @author zby
   * @datetime 2022/12/2 14:50
   */
  public static ReturnResult error(CodeMessageEnum codeMessageEnum) {
    return error(codeMessageEnum.getCode(), codeMessageEnum.getMessage());
  }

  /**
   * 返回失败
   *
   * @param codeMessageEnum
   * @param message
   * @author zby
   * @datetime 2022/11/30 14:50
   */
  public static ReturnResult error(CodeMessageEnum codeMessageEnum, String message) {
    return error(codeMessageEnum.getCode(), message);
  }

  /**
   * 返回失败
   *
   * @param code
   * @param message
   * @author zby
   * @datetime 2022/11/28 16:23
   */
  public static ReturnResult error(String code, String message) {
    ReturnResult result = new ReturnResult();
    result.setCode(code);
    result.setMessage(message);
    result.setSuccess(false);
    return result;
  }

  /**
   * 重写toString方法
   *
   * @author zby
   * @datetime 2022/11/29 13:44
   */
  @Override
  public String toString() {
    return JSONObject.toJSONString(this);
  }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

抛出异常时将异常信息返给前端 的相关文章

  • 毕业论文格式(图片题注引用,表格,公式格式)

    本科毕业论文差不多写完了 xff0c 记录一下一些格式 xff0c 以后写作可能会用到 xff0c 就可以翻起来看看 首先 xff0c 如果可以找到一篇格式符合要求的word文档的话 xff0c 最简单的方法就是在这个文档的基础上进行内容的
  • 图像处理——相位恢复(GS,TIE,改进型角谱迭代法)(已更新代码)

    利用GS xff0c TIE xff0c 改进型角谱迭代算法进行相位恢复 角谱传播理论 角谱传播理论可以翻阅傅里叶光学的书 xff0c 就能找到定量分析的计算公式 xff0c 可以分析某个平面的角谱垂直传播到另外一个平面的角谱 xff0c
  • 串口应用:遵循uart协议,发送多个字节的数据(状态机)

    上一节中 xff0c 我们遵循uart协议 xff0c 它发送一次只能发送6 7 8位数据 xff0c 我们不能随意更改位数 xff08 虽然在代码上可行 xff09 xff0c 不然就不遵循uart协议了 xff0c 会造成接收端无法接收
  • 数码管动态显示Verilog实现(参考小梅哥教程)(视觉暂留)

    一个数码管有八个引脚 xff0c 控制八段二极管的亮灭 xff0c 用以显示需要的数字 当有N个数码管时 xff0c 一个一个控制的话需要N x 8 个引脚 xff0c 消耗资源较多 因此可以利用动态显示的方案通过人眼的视觉暂留特性达到静态
  • 彻底理解DDS(信号发生器)的fpga实现(verilog设计代码)

    DDS xff08 Direct Digital Synthesis xff09 是一种把一系列数字信号通过D A转换器转换成模拟信号的数字合成技术 它有查表法和计算法两种基本合成方法 在这里主要记录DDS查表法的fpga实现 查表法 xf
  • HDMI/DVI

    一 基础知识 1 历史 早期在FPGA芯片上实现HDMI控制显示是使用HDMI发送芯片 xff0c eg xff1a ADV7513 sil9022 xff0c CH7301等 用之前VGA控制中输出的RGB信号 行场同步信号和使能信号输入
  • HDMI/DVI____TMDS编码

    一 编码步骤 xff1a 基本方法 xff1a 取第一位数据为初值 xff0c 接下来输入的每一位与前一导出的位 xff08 根据判断条件 xff09 进行异或XOR或者同或XNOR xff08 最小化传输 xff0c 减少0 1翻转 xf
  • HDMI/DVI____串行发送器

    一 功能 xff1a 把10bit数据转化为串行数据在一个时钟周期全部输出 xff08 先输出高位 xff0c 再输出低位 xff09 二 框图 二 思路 对于TMDS编码器 xff0c 在每一个输入时钟周期 xff0c 输入一次数据到TM
  • keil添加新文件.c.h

    文章目录 添加文件到组中1 双击组名称2 点击快捷键 添加头文件路径 h1 点击魔术棒快捷键2 头文件加 添加文件到组中 1 双击组名称 双击组名称 xff0c 打开弹窗 xff0c 然后选择相应的组中的新文件 xff0c 在点击ADD 2
  • QT常用控件(二)——自定义控件封装

    引言 Qt已经提供了很多的基础控件供开发使用 xff0c 而Qt原生的控件有时候并不能满足我们的需求 xff0c 特别是在工业的运用上 xff0c 比如我们需要一个日期时间的选择器 xff0c Qt虽然已经提供了原生的QDateTime控件
  • STM32之串口通信USART模块学习(1)

    一 通信接口 通信的目的 xff1a 将一个设备的数据传送到另一个设备 xff0c 扩展硬件系统通信协议 xff1a 制定通信的规则 xff0c 通信双方按照协议规则进行数据收发 单端信号通信的双方必须要共地 xff0c 因为都是对GND的
  • 2019电赛总结(一)

    2019电赛总结 xff08 一 xff09 文章目录 2019电赛总结 xff08 一 xff09 4 那之前5 电赛初期6 电赛中期7 电赛强化练习8 电赛预热阶段8月初9 那以后 4 那之前 2019电赛总结 序 xff09 5 电赛
  • 统计从键盘输入的一行字符中小写字母,大写字母,数字字符和其它字符的个数。

    统计从键盘输入的一行字符中小写字母 xff0c 大写字母 xff0c 数字字符和其它字符的个数 C语言实现 vs 2019 span class token macro property span class token directive
  • c语言求1~10的阶乘和

    求1 43 2 43 3 43 43 10 的和 span class token macro property span class token directive keyword include span span class toke
  • C和Cpp区别

    1 输入 xff0c 输出不同 xff08 out xff0c put xff09 c语言 xff1a include lt stdio h gt scanf 34 d 34 amp a printf 34 a 61 d n 34 a cp
  • C++实现基于顺序搜索的动态分区分配算法

    目录 1 需求分析 2 代码实现 3 测试用例 4 总结与收获 1 需求分析 动态分区分配又称为可变分区分配 xff0c 他是根据进程的实际需要 xff0c 动态地为之分配内存空间 在实现动态分区分配时 xff0c 将涉及到分区分配中所有的
  • C语言实现TCP编程

    C语言实现TCP编程 1 主机字节序和网络字节序2 套接字的地址结构IP地址转化的方法 3 TCP的网络接口4 TCP服务器端的编程流程5 TCP客户端的编程流程6 运行结果 1 主机字节序和网络字节序 主机字节序 xff1a 不同的芯片
  • QT---用户登录注册案例实现

    用户登录 注册 span class token macro property span class token directive hash span span class token directive keyword include
  • C++中list详解

    list详解 list的介绍list函数说明成员类型构造函数元素访问迭代器容量修改器操作 vector和list区别总结vector和list的使用场景 仿写END xff01 96 在这里插入代码片 96 list的介绍 list是序列容

随机推荐

  • sip response 摘要认证

    详解摘要认证 1 什么是摘要认证 摘要认证与基础认证的工作原理很相似 xff0c 用户先发出一个没有认证证书的请求 xff0c Web服务器回复一个带有WWW Authenticate头的响应 xff0c 指明访问所请求的资源需要证书 但是
  • Prim算法实现最小生成树

    Prim算法实现最小生成树 1 最小生成树是什么2 最小生成树的用途3 Prim算法描述4 Prim算法演示最小生成树过程5 Prim算法实现END 1 最小生成树是什么 对连通图进行遍历 过程中所经过的边和顶点的组合可看做是一棵普通树 通
  • 哈夫曼树,哈夫曼编码及应用——(代码实现)

    哈夫曼树 xff0c 哈夫曼编码及应用 1 哈夫曼树1 1 什么是哈夫曼树 2 如何构造哈夫曼树 xff08 哈夫曼算法 xff09 2 1 举例实现哈夫曼树2 1 1手动实现具体步骤2 1 2代码实现具体步骤 3 哈夫曼编码3 1 什么是
  • 二叉排序树详解及实现

    二叉排序树详解及实现 1 什么是二叉排序树2 二叉排序树的数据结构2 1二叉排序树的节点类型2 2二叉排序树中插入某个元素2 3 二叉排序树中按值查找元素2 4 找排序二叉树中的最小值2 5返回排序二叉树中ptr中序遍历的后续节点2 6 寻
  • 平衡二叉树的一系列操作:删除、插入(在二叉排序树中插入新结点后,如何保持平衡)、调整平衡等等等

    平衡二叉树的插入 xff08 在二叉排序树中插入新结点后 xff0c 如何保持平衡 xff09 1 平衡二叉树的定义2 平衡二叉树的插入 xff08 调整最小不平衡子树A xff09 2 1LL xff08 在A的左孩子的左子树中插入导致不
  • 网络 UDP协议(C++|代码通过udp协议实现客户端与服务端之间的通信)

    这里写目录标题 udp通信编程各端的操作流程 xff1a 服务端操作流程 xff1a 客户端操作流程 xff1a 第2 3步与服务端不同 socket接口介绍udp客户服务端代码实现 推荐阅读 socket套接字编程就是在网络程序中编写代码
  • 网络 TCP协议(C++代码|通过tcp协议实现客户端与服务端之间的通信)

    目录 TCP通信编程各端的操作流程 xff1a 服务端操作流程 xff1a 客户端操作流程 xff1a 推荐先学习UDP协议在学习TCP协议 在UDP协议博客中讲解得更详细 xff0c 看懂UDP协议就很容易理解TCP了 网络 UDP协议
  • Matlab学习-箱型图绘制

    1 箱型图简介 xff1a 参考链接 xff1a boxplot函数用法详解 箱型图简介 箱型图主要包括的数据有 xff1a 最大值 最小值 上四分位数 下四分位数和中位数 xff0c 以及异常值 2 箱型图绘制 X span class
  • Matlab学习-CDF(累积分布函数图)绘制

    累积分布函数图绘制 参考链接 xff1a 1 Matlab官方说明 2 参考链接 3 属性设置 CDF xff1a 累积分布函数图 xff0c 顾名思义就是能够直观的反应某组数列分布的概率情况 xff0c 能够非常直观的反应误差精度大小 图
  • Matlab学习-频率分布直方图绘制

    参考链接 xff1a hist xff08 xff09 函数用法 频率分布直方图 xff1a 在数理统计中 xff0c 会经常使用到频率分布直方图 xff0c 能够直观的反应频率分布的范围大小 xff0c 在直角坐标系中 xff0c 横轴为
  • Matlab学习-经纬度在matlab内置地图显示

    已知经纬度坐标 xff0c 将其显示是地图上 参考链接 xff1a 使用matlab绘制世界地图并根据经纬度绘制点位 附m map的下载与安装说明 wm span class token operator 61 span webmap sp
  • ARM存储格式的“大小端”解析

    ARM储存 大端格式和小端格式 所谓的大端模式 xff0c 是指数据的高位 xff0c 保存在内存的低地址中 xff0c 而数据的低位 xff0c 保存在内存的高地址中 xff0c 这样的存储模式有点儿类似于把数据当作字符串顺序处理 xff
  • UBLOX板卡基础设置--F9P板卡配置(基准站和流动站)

    UBLOX F9P板卡配置 基准站 流动站 UBX F9P模块为双频定位芯片 xff0c 是市场上目前最常用的高精定位模块 xff0c 差分定位精度可达厘米级 xff0c 具体参数详见官方文档 官方文档下载链接 xff1a UBX F9P模
  • GIT学习-常用命令

    2 GIT学习 常用命令 在学习git前首先需要对相关名词和概念有基本了解 xff0c git基础知识学习可参考以下资料 xff1a git基础知识 xff1a GIT学习 1 基础知识git下载与配置 xff1a GIT学习 xff08
  • ROS常用命令

    ROS常用命令 1 将话题数据单独导出 将话题数据单独导出为一个文件 rostopic echo b name name p topic name gt save file name ex rostopic echo b test bag
  • Linux常用命令

    Linux常用命令 1 查看电脑IP地址 ifconfig 2 远程连接其他电脑 xff0c 查看是否连接成功 ping IP address 3 通过IP地址远程连接电脑 ssh lcl 64 IP address 4 文件传输 4 1
  • opencv-3.4.1-x86编译安装 -- 超详细

    相关链接 xff1a opencv 3 4 1 arm编译安装 超详细 opencv 3 4 1 x86编译安装 环境1 安装依赖库2 OpenCV源码获取与解压2 1 获取源码2 2 工作目录准备2 3 解压 3 OpenCV配置编译3
  • Qt编程之单例模式——代码复用,一个类供多个类调用

    什么是单例模式 单例模式是一种对象创建模式 xff0c 用于生产一个对象的实例 xff0c 它可以确保系统中一个类只产生一个实例 xff0c 这样做有两个好处 xff1a 1 对于频繁使用的对象 xff0c 可以省略创建对象所花费的时间 x
  • STM32串口数据接收处理,数据分割为整形浮点型数据。

    简介 通过stm32的串口接收数据 xff0c 通过strstr函数分割数据 xff0c 再将字符数据转化为整形数据或浮点数据 比如 xff1a stm32接收到数据 s555s xff0c 分割数据为 555 xff0c 然后转化为int
  • 抛出异常时将异常信息返给前端

    全局异常处理器负责将抛出的异常 xff0c 以统一的格式返给前端 在这里起主要作用的注解是 64 RestControllerAdvice 64 RestControllerAdvice主要配合 64 ExceptionHandler使用