封装响应体、自定义异常、全局异常处理、工具类返回响应体
异常设置
创建自己的异常继承运行异常 使用 构造函数 接收错误信息 和 错误code代码
理解:
在运行时 用户输入错误 所以要继承运行异常
断言类 抛出异常
assert a == 1 那么 xxx
-
throwIf 创建断言工具类 工具类 方法接收 布尔类型(判断) + 运行异常(可以输出异常信息)
只能抛出运行异常
throwIf 重载
-
接收布尔类型 + 错误通用代码
给BusinessException传入errorCode 抛出 自定义异常BusinessException`
-
借用上面的throwIf 传入condition + 运行异常的子类生意异常 让抛出运行异常
-
异常不仅携带 errorCode设置的异常信息 还要有自己设置的异常信息 再次封装 布尔 + errorCode(给BusinessException BusinessException 构造函数接收 传给自己父亲 设置自己的code码) + 自己写的信息
以后不用if 和 new异常了而是直接放进throwIf 里面会自己抛出异常

核心还是这个
设置自定义异常
package com.pioneak.picturepioneakbackend.exception;
/*
what;
生意异常
how:
状态码 错误信息传给给父亲运行异常
careOut:
如果 final 变量在声明时没有赋值,那么必须在该类的每个构造函数中对其进行赋值。这是因为构造函数是对象初始化的地方,在对象创建过程中,每个构造函数都会被调用一次,保证 final 变量在对象创建时就被赋予一个确定的值,之后就不能再修改了。
*/
public class BusinessException extends RuntimeException {
private final int code;
/*
错误码 错误信息
*/
BusinessException(int code, String message) {
super(message);
this.code = code;
}
/*
what:
通用错误代码 不携带自己信息构造 接收errorCode对象的错误信息
*/
BusinessException(ErrorCode errorCode)
{
super(errorCode.getMessage());
this.code = errorCode.getCode();
}
/*
what:
通用错误代码 自己也有话说
*/
BusinessException(ErrorCode errorCode, String message){
super(message);
this.code = errorCode.getCode();
}
}
优雅封装抛出异常
package com.pioneak.picturepioneakbackend.exception;
/*
what:
异常判断直接抛出类
*/
public class throwUtils {
/*
what;
接收布尔类型 运行异常选择抛出异常
异常底部用最高RuntimeException来接受
最根本的接收异常 抛出去 其他为多态
*/
public static void throwIf(boolean condition,RuntimeException runtimeException)
{
if(condition){
throw runtimeException;
}
}
/*
what;
接收布尔类型、通用状态码 抛出生意异常(自定义异常) 自定义异常又有三种构造方式
*/
public static void throwIf(boolean condition, ErrorCode errorCode)
{
this(condition,new BusinessException(errorCode));
}
/*
what;
接收布尔类型 通用代码 自己要说的话(给runtime初始化 输出)
*/
public static void throwIf(boolean condition,ErrorCode errorCode,String message)
{
throwIf(condition,new BusinessException(errorCode,message));
}
}
以后使用
直接设置是否抛出异常 +
// http://127.0.0.1:8080/hello?name=lisi
@RequestMapping("/hello")
@ResponseBody
public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name) {
try{
throwUtils.throwIf(true, ErrorCode.NO_AUTH_ERROR);
}catch (RuntimeException e){
System.out.println("捕获runtime异常" + e.getMessage());
}
return "Hello " + name;
}
全局通用响应类
返回给前端 固定格式的设置
code data message 三个信息
构造函数:
三个信息都由外部传入
不需要message
异常了只传入errorCode
那么以后返回类型 是 BaseResponse<T> 类型 传给前端

但是以后我们还是需要自己返回new对象吗? 不够优雅
新同事不知道成功代码是200 还是 201 封装工具类 不用自己设置200 或者201

使用泛型方法接收泛型对象 设置返回data类型 设置返回对象的参数
以后需要返回对象 直接

example:
package com.pioneak.picturepioneakbackend.common;
import com.pioneak.picturepioneakbackend.exception.ErrorCode;
import java.io.Serializable;
/*
what;
基础响应类 响应的通用模板 可能携带各种数据(携带泛型) 序列化传输前端
*/
public class BaseResponse<T> implements Serializable {
private int code;
private T data;
private String message;
/*
what;
构造函数设置返回信息(基础版)
*/
BaseResponse(int code,T data, String message)
{
this.code = code;
this.data = data;
this.message = message;
}
/*
what;
返回成功数据 不需要携带信息
*/
BaseResponse(int code,T data)
{
this(code,data,"");
}
/*
what;
只返回错误信息 没有数据
*/
BaseResponse(ErrorCode errorCode)
{
this(errorCode.getCode(),null,errorCode.getMessage());
}
}
返回异常工具:以后全部异常返回都使用他
package com.pioneak.picturepioneakbackend.common;
import com.pioneak.picturepioneakbackend.exception.ErrorCode;
/*
what:
优雅返回响应体
*/
public class ResultUtils {
/*
what:
返回成功 携带数据
*/
public static <T> BaseResponse<T> success(T data)
{
/*
careOut:
传入data后确定T 类型 那么之后的T类型即可确定
*/
BaseResponse<T> ok = new BaseResponse<>(0, data, "ok");
return ok;
}
/*
what;
返回失败响应体 失败不需要携带数据 或者说不用确定数据 不需要确定响应体中类型
*/
public static BaseResponse<?> error(ErrorCode errorCode)
{
BaseResponse<Object> objectBaseResponse = new BaseResponse<>(errorCode);
return objectBaseResponse;
}
/*
what;
返回失败响应体 外部提供 状态码 错误信息 数据为空
careOut:
枚举类型通常情况下确实不能使用new关键字来创建实例
*/
public static BaseResponse<?> error(int node,String message)
{
return new BaseResponse<>(node,null,message);
}
/*
what;
返回失败通用代码 想携带的信息
careOut:
errorCode一定是外部传进来的errorCode类型 一定是已经设立好的success 等 枚举对象
*/
public static BaseResponse<?> error(ErrorCode errorCode, String message)
{
BaseResponse<Object> objectBaseResponse = new BaseResponse<>(errorCode.getCode(), null, message);
return objectBaseResponse;
}
}
全局异常处理器
why:
更优雅处理未料想过的的异常
how:
返回响应类对象 接收某类异常

example:
异常响应
package com.pioneak.picturepioneakbackend.common;
import com.pioneak.picturepioneakbackend.exception.ErrorCode;
import lombok.Data;
import java.io.Serializable;
/*
what;
基础响应类 响应的通用模板 可能携带各种数据(携带泛型) 序列化传输前端
careOut:
@Data 帮助传输给前端信息!!!!
*/
@Data
public class BaseResponse<T> implements Serializable {
private int code;
private T data;
private String message;
/*
what;
构造函数设置返回信息(基础版)(成功)
*/
BaseResponse(int code,T data, String message)
{
this.code = code;
this.data = data;
this.message = message;
}
/*
what;
返回成功数据 不需要携带信息
*/
BaseResponse(int code,T data)
{
this(code,data,"");
}
/*
what;
只返回错误信息 没有数据 失败
*/
BaseResponse(ErrorCode errorCode)
{
this(errorCode.getCode(),null,errorCode.getMessage());
}
}
how use: 产生运行异常
@RequestMapping("/user")
@ResponseBody
public User user() {
User user = new User();
user.setName("theonefx");
user.setAge(666);
System.out.println(1/0);
return user;
}
封装
分页请求类
what param:
参数current pageSize sortField sortOrder 用于设置分页时候的参数
how use:
以后在controller层 接收参数 接收对象分页即可
@Data
public class PageRequest {
/**
* 当前页号
*/
private int current = 1;
/**
* 页面大小
*/
private int pageSize = 10;
/**
* 排序字段
*/
private String sortField;
/**
* 排序顺序(默认降序)
*/
private String sortOrder = "descend";
}
删除请求类
what:
通用删除id请求
what param:
id
how use:
接收时 接收对象 获取参数即可
example:
@Data
public class DeleteRequest implements Serializable {
/**
* id
*/
private Long id;
private static final long serialVersionUID = 1L;
}
跨域
what:
端口号不一致 浏览器同源策略 发送请求端口 和 接收请求不在一个端口
solve:
-
后端支持跨域
-
代理
-
访问localhost:5173 代理 成localhost:8123发请求
-
nginx 第三方工具代理
-
how:

example:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 覆盖所有请求
registry.addMapping("/**")
// 允许发送 Cookie
.allowCredentials(true)
// 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突)
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("*");
}
}
健康检查
what:
是否正常运行

example:
package com.pioneak.picturepioneakbackend.controller;
import com.pioneak.picturepioneakbackend.common.BaseResponse;
import com.pioneak.picturepioneakbackend.common.ResultUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/*
what:
健康检查
基础路径 @RequestMapping("/")
*/
@RestController
@RequestMapping("/")
public class MainController {
/*
what:
健康检查 返回响应体
*/
@GetMapping("/health")
public BaseResponse<String> health()
{
BaseResponse<String> ok = ResultUtils.success("ok");
return ok;
}
}
