优化封装
qian封装通用返回对象
给对象补充一些信息 告诉前端这个请求在业务层面上是成功还是失败
{
“name":"Zwww"
}
变成
{
"code": 0 //业务状态码
"data":{
"name":"Zwww"
},
"message":"ok"
}
通用返回类
package com.zwnsyw.bankend.common;
import lombok.Data;
import java.io.Serializable;
/**
* 通用返回类
*
* @author Zwww
*/
@Data
public class BaseResponse<T> implements Serializable {
/**
* 状态码
*/
private int code;
/**
* 数据
*/
private T data;
/**
* 消息
*/
private String message;
/**
* 描述
*/
private String description;
public BaseResponse(int code, T data, String message, String description) {
this.code = code;
this.data = data;
this.message = message;
this.description = description;
}
public BaseResponse(int code, T data, String message) {
this(code, data, message, "");
}
public BaseResponse(int code, T data) {
this(code, data, "", "");
}
public BaseResponse(ErrorCode errorCode) {
this(errorCode.getCode(), null, errorCode.getMessage(), errorCode.getDescription());
}
}
返回工具类
以免每次调用都要传一堆参数 这里再做一层封装 帮助填这些参数
package com.zwnsyw.bankend.common;
/**
* 返回工具类
*
* @author Zwww
*/
public class ResultUtils {
/**
* 成功
*
* @param data
* @param <T>
* @return
*/
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<>(0, data, "ok");
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode) {
return new BaseResponse<>(errorCode);
}
/**
* 失败
*
* @param code
* @param message
* @param description
* @return
*/
public static BaseResponse error(int code, String message, String description) {
return new BaseResponse(code, null, message, description);
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode, String message, String description) {
return new BaseResponse(errorCode.getCode(), null, message, description);
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode, String description) {
return new BaseResponse(errorCode.getCode(), errorCode.getMessage(), description);
}
}
封装全局异常处理
业务逻辑中 之前遇到判定为错误后 都是返回-1或者false 其实是不明确的 加上一些通用的错误码
package com.zwnsyw.bankend.common;
/**
* 错误码
*
* @author Zwww
*/
public enum ErrorCode {
SUCCESS(0, "ok", ""),
PARAMS_ERROR(40000, "请求参数错误", ""),
NULL_ERROR(40001, "请求数据为空", ""),
NOT_LOGIN(40100, "未登录", ""),
NO_AUTH(40101, "无权限", ""),
SYSTEM_ERROR(50000, "系统内部异常", "");
private final int code;
/**
* 状态码信息
*/
private final String message;
/**
* 状态码描述(详情)
*/
private final String description;
ErrorCode(int code, String message, String description) {
this.code = code;
this.message = message;
this.description = description;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public String getDescription() {
return description;
}
}
全局异常处理
定义一个东西来捕获整个业务中的异常 统一处理
自定义异常类
相较于java的异常类 扩充更多字段
自定义构造函数 更灵活快捷设置字段
package com.zwnsyw.bankend.exception;
import com.zwnsyw.bankend.common.ErrorCode;
/**
* 自定义异常类
*
* @author Zwww
*/
public class BusinessException extends RuntimeException {
/**
* 异常码
*/
private final int code;
/**
* 描述
*/
private final String description;
public BusinessException(String message, int code, String description) {
super(message);
this.code = code;
this.description = description;
}
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
this.description = errorCode.getDescription();
}
public BusinessException(ErrorCode errorCode, String description) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
this.description = description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
}
全局异常处理器
捕获代码中所有的异常 集中处理 让前端感知更详细的业务报错/信息
package com.zwnsyw.bankend.exception;
import com.zwnsyw.bankend.common.BaseResponse;
import com.zwnsyw.bankend.common.ErrorCode;
import com.zwnsyw.bankend.common.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理器
*
* @author Zwww
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public BaseResponse<?> businessExceptionHandler(BusinessException e) {
log.error("businessException: " + e.getMessage(), e);
return ResultUtils.error(e.getCode(), e.getMessage(), e.getDescription());
}
@ExceptionHandler(RuntimeException.class)
public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {
log.error("runtimeException", e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, e.getMessage(), "");
}
}
前端对应接口
api.ts
import request from '@/plugins/globalRequest';
/** 获取当前的用户 GET /api/user/current */
export async function currentUser(options?: { [key: string]: any }) {
return request<API.BaseResponse<API.CurrentUser>>('/api/user/current', {
method: 'GET',
...(options || {}),
});
}
/** 退出登录接口 POST /api/user/logout */
export async function outLogin(options?: { [key: string]: any }) {
return request<API.BaseResponse<number>>('/api/user/logout', {
method: 'POST',
...(options || {}),
});
}
/** 登录接口 POST /api/user/login */
export async function login(body: API.LoginParams, options?: { [key: string]: any }) {
return request<API.BaseResponse<API.LoginResult>>('/api/user/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 注册接口 POST /api/user/register */
export async function register(body: API.RegisterParams, options?: { [key: string]: any }) {
return request<API.BaseResponse<API.RegisterResult>>('/api/user/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 搜索用户 GET /api/user/search */
export async function searchUsers(options?: { [key: string]: any }) {
return request<API.BaseResponse<API.CurrentUser[]>>('/api/user/search', {
method: 'GET',
...(options || {}),
});
}
/**
* request 网络请求工具
* 更详细的 api 文档: https://github.com/umijs/umi-request
*/
import {extend} from 'umi-request';
import {message} from "antd";
import {history} from "@@/core/history";
import {stringify} from "querystring";
/**
* 配置request请求时的默认参数
*/
const request = extend({
credentials: 'include', // 默认请求是否带上cookie
prefix: process.env.NODE_ENV === 'production' ? 'http://user-backend.code-nav.cn' : undefined
// requestType: 'form',
});
/**
* 所以请求拦截器
*/
request.interceptors.request.use((url, options): any => {
console.log(`do request url = ${url}`)
return {
url,
options: {
...options,
headers: {},
},
};
});
/**
* 所有响应拦截器
*/
request.interceptors.response.use(async (response, options): Promise<any> => {
const res = await response.clone().json();
if (res.code === 0) {
return res.data;
}
if (res.code === 40100) {
message.error('请先登录');
history.replace({
pathname: '/user/login',
search: stringify({
redirect: location.pathname,
}),
});
} else {
message.error(res.description)
}
return res.data;
});
export default request;
项目分区导航:⬅️ 15-逻辑删除mybatis-plus配置原理 | 16-优化封装 | ➡️ 17-部署
💬 评论