自定义返回结果和异常处理

在Java Web开发中,为了提供更统一、更友好的API接口,我们通常会自定义返回结果和异常处理机制。这样做的好处是可以将业务逻辑与HTTP响应的封装解耦,提高代码的可读性和可维护性。本文将介绍如何在Java Web项目中自定义返回结果和异常处理。

在Java编程中,异常处理是一个非常重要的组成部分。Java标准库提供了一系列的内置异常类,如NullPointerExceptionIOException等。然而,在实际开发中,我们有时需要定义一些与特定业务逻辑或框架相关的异常类。本文将介绍如何在Java中创建自定义异常处理类,并阐述其重要性和用法。

一、自定义返回结果

1. 定义返回结果类

首先我们需要定义一个返回结果类,用于封装API接口的相应数据。这个类通常包含状态码、消息和数据等字段。

首先在创建一个 ResultCodeEnum  枚举类,用来作为前后端状态数据交换状态码:

package com.javaclimb.service.base.result;

import lombok.Getter;
import lombok.ToString;

/**
 * @Author cb
 * @createTime 
 * @Version
 * @注释:前后端数据交换状态码
 */
@Getter
@ToString
public enum ResultCodeEnum {
    SUCCESS(true, 20000, "成功"),
    UNKNOWN_REASON(false, 20001, "未知错误"),

    BAD_SQL_GRAMMAR(false, 21001, "sql 语法错误"),
    JSON_PARSE_ERROR(false, 21002, "json 解析异常"),
    PARAM_ERROR(false, 21003, "参数不正确"),

    FILE_UPLOAD_ERROR(false, 21004, "文件上传错误"),
    FILE_DELETE_ERROR(false, 21005, "文件刪除错误"),
    EXCEL_DATA_IMPORT_ERROR(false, 21006, "Excel 数据导入错误"),

    VIDEO_UPLOAD_ALIYUN_ERROR(false, 22001, "视频上传至阿里云失败"),
    VIDEO_UPLOAD_TOMCAT_ERROR(false, 22002, "视频上传至业务服务器失败"),
    VIDEO_DELETE_ALIYUN_ERROR(false, 22003, "阿里云视频文件删除失败"),
    FETCH_VIDEO_UPLOADAUTH_ERROR(false, 22004, "获取上传地址和凭证失败"),
    REFRESH_VIDEO_UPLOADAUTH_ERROR(false, 22005, "刷新上传地址和凭证失败"),
    FETCH_PLAYAUTH_ERROR(false, 22006, "获取播放凭证失败"),

    URL_ENCODE_ERROR(false, 23001, "URL编码失败"),
    ILLEGAL_CALLBACK_REQUEST_ERROR(false, 23002, "非法回调请求"),
    FETCH_ACCESSTOKEN_FAILD(false, 23003, "获取 accessToken 失败"),
    FETCH_USERINFO_ERROR(false, 23004, "获取用户信息失败"),
    LOGIN_ERROR(false, 23005, "登录失败"),

    COMMENT_EMPTY(false, 24006, "评论内容必须填写"),

    PAY_RUN(false, 25000, "支付中"),
    PAY_UNIFIEDORDER_ERROR(false, 25001, "统一下单错误"),
    PAY_ORDERQUERY_ERROR(false, 25002, "查询支付结果错误"),

    ORDER_EXIST_ERROR(false, 25003, "课程已购买"),

    GATEWAY_ERROR(false, 26000, "服务不能访问"),

    CODE_ERROR(false, 28000, "验证码错误"),

    LOGIN_PHONE_ERROR(false, 28009, "手机号码不正确"),
    LOGIN_MOBILE_ERROR(false, 28001, "账号不正确"),
    LOGIN_PASSWORD_ERROR(false, 28008, "密码不正确"),
    LOGIN_DISABLED_ERROR(false, 28002, "该用户已被禁用"),
    REGISTER_MOBLE_ERROR(false, 28003, "手机号已被注册"),
    LOGIN_AUTH(false, 28004, "需要登录"),
    LOGIN_ACL(false, 28005, "没有权限"),
    SMS_SEND_ERROR(false, 28006, "短信发送失败"),
    SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL(false, 28007, "短信发送过于频繁"),
    DIVIDE_ZERO(false, 29001, "除零错误");

    private final Boolean success;

    private final Integer code;

    private final String message;

    ResultCodeEnum(Boolean success, Integer code, String message) {
        this.success = success;
        this.code = code;
        this.message = message;
    }

}

再创建一个 result.java 类

package com.result;

import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.SchemaProperties;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.apache.ibatis.annotations.Property;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author cb
 * @createTime 
 * @Version
 * @注释:全局统一返回结果
 */
@Data
@Schema(description = "返回码")
public class Result {

    @Schema(description = "是否成功")
    private Boolean success;

    @Schema(description = "返回码")
    private Integer code;

    @Schema(description = "返回消息")
    private String message;

    @Schema(description = "返回数据")
    private Map<String, Object> data = new HashMap<>();

    public Result () {
    }

    public static Result ok() {
        Result r = new Result();
        r.setSuccess(ResultCodeEnum.SUCCESS.getSuccess());
        r.setCode(ResultCodeEnum.SUCCESS.getCode());
        r.setMessage(ResultCodeEnum.SUCCESS.getMessage());
        return r;
    }

    public static Result error() {
        Result r = new Result ();
        r.setSuccess(ResultCodeEnum.UNKNOWN_REASON.getSuccess());
        r.setCode(ResultCodeEnum.UNKNOWN_REASON.getCode());
        r.setMessage(ResultCodeEnum.UNKNOWN_REASON.getMessage());
        return r;
    }

    public static Result setResult(ResultCodeEnum resultCodeEnum) {
        Result r = new Result ();
        r.setSuccess(resultCodeEnum.getSuccess());
        r.setCode(resultCodeEnum.getCode());
        r.setMessage(resultCodeEnum.getMessage());
        return r;
    }

    public Result success(Boolean success) {
        this.setSuccess(success);
        return this;
    }

    public Result message(String message) {
        this.setMessage(message);
        return this;
    }

    public Result code(Integer code) {
        this.setCode(code);
        return this;
    }

    public Result data(String key, Object value) {
        this.data.put(key, value);
        return this;
    }

    public Result data(Map<String, Object> map) {
        this.setData(map);
        return this;
    }
}

 

 

2. 在Controller中使用自定义返回结果

在Controller层,我们可以使用自定义的 result 类来封装响应数据,并返回给前端。

package com.controller.admin;

import com.result.Result;
import com.result.ResultCodeEnum;
import java.util.List;

/**
 *
 * @author cb
 * @since 
 */
@RestController
@RequestMapping("/admin/teacher")
@CrossOrigin
@Tag(name = "文档API",description = "")
public class  TeacherController {

    @Operation(description = "测试接口")
    @GetMapping("/getString")
    public result getTest(){
        return Result.ok().message("测试成功").data("数据值的键",数据值);
    }
}

二、自定义异常处理

1. 定义自定义异常类

当业务逻辑出现错误时,我们可以抛出自定义的异常类,以便进行统一的异常处理。

首先创建一个 ExceptionUtils  类来拿到异常错误信息。

package com.utils;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * @Author cb
 * @createTime 
 * @Version
 * @注释:从异常信息中拿到错误信息栈
 */
public class ExceptionUtils {
    public static String getMessage(Exception e) {
        StringWriter sw = null;
        PrintWriter pw = null;
        try {
            sw = new StringWriter();
            pw = new PrintWriter(sw);
            // 将出错的栈信息输出到printWriter中
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
        } finally {
            if (sw != null) {
                try {
                    sw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (pw != null) {
                pw.close();
            }
        }
        return sw.toString();
    }
}

再创建一个自定义类 JavaclimbException 继承 RuntimeException 

里面就写自定义需要处理的哪一类异常。

package com.exception;

import com.result.ResultCodeEnum;
import lombok.Data;

/**
 * @Author cb
 * @createTime 
 * @Version
 * @注释:自定义异常,用户自己主动抛出的异常
 */
@Data
public class JavaclimbException extends RuntimeException {

    private Integer code;

    public JavaclimbException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }
}

2. 使用@ControllerAdvice进行全局异常处理

package com.admin;

import com.result.Result;
import com.result.ResultCodeEnum;
import com.exception.JavaclimbException;

import java.util.List;

/**
 *
 * @author cb
 * 
 */
@RestController
@RequestMapping("/admin")
@CrossOrigin
@Tag(name = "文档API",description = "")
public class  TeacherController {

    @Operation(description = "测试接口")
    @GetMapping("/getString")
    public Result getTest(){
        return Result.ok().message("测试成功").data("数据值的键",数据值);
    }



    /**
     * 异常测试
     */
    @Operation(description = "异常测试")
    @GetMapping("exceptionTest")
    public R exceptionTest(){
        try {
            int a = 1/0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new JavaclimbException(ResultCodeEnum.DIVIDE_ZERO);
        }
        return Result.ok();
    }


}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值