123 lines
3.8 KiB
Java
123 lines
3.8 KiB
Java
package com.youlai.boot.common.result;
|
||
|
||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||
import cn.hutool.json.JSONUtil;
|
||
import jakarta.servlet.http.HttpServletResponse;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.http.HttpStatus;
|
||
import org.springframework.http.MediaType;
|
||
|
||
import java.nio.charset.StandardCharsets;
|
||
|
||
/**
|
||
* 响应写入器
|
||
* <p>
|
||
* 用于在过滤器、Security处理器等无法使用 @RestControllerAdvice 的场景中统一写入HTTP响应。
|
||
* 支持写入成功响应和错误响应。
|
||
* 此类为工具类,所有方法均为静态方法,禁止实例化。
|
||
*
|
||
* @author Ray.Hao
|
||
* @since 2.0.0
|
||
*/
|
||
@Slf4j
|
||
public final class ResponseWriter {
|
||
|
||
/**
|
||
* 私有构造函数,防止实例化
|
||
*/
|
||
private ResponseWriter() {
|
||
throw new UnsupportedOperationException("工具类不允许实例化");
|
||
}
|
||
|
||
/**
|
||
* 写入成功响应
|
||
*
|
||
* @param response HttpServletResponse
|
||
* @param data 响应数据(可选)
|
||
*/
|
||
public static void writeSuccess(HttpServletResponse response, Object data) {
|
||
writeResult(response, Result.success(data), HttpStatus.OK.value());
|
||
}
|
||
|
||
/**
|
||
* 写入成功响应(无数据)
|
||
*
|
||
* @param response HttpServletResponse
|
||
*/
|
||
public static void writeSuccess(HttpServletResponse response) {
|
||
writeSuccess(response, null);
|
||
}
|
||
|
||
/**
|
||
* 写入错误响应
|
||
*
|
||
* @param response HttpServletResponse
|
||
* @param resultCode 响应结果码
|
||
*/
|
||
public static void writeError(HttpServletResponse response, ResultCode resultCode) {
|
||
writeError(response, resultCode, null);
|
||
}
|
||
|
||
/**
|
||
* 写入错误响应(带自定义消息)
|
||
*
|
||
* @param response HttpServletResponse
|
||
* @param resultCode 响应结果码
|
||
* @param message 自定义消息(可选,为 null 时使用 resultCode 的默认消息)
|
||
*/
|
||
public static void writeError(HttpServletResponse response, ResultCode resultCode, String message) {
|
||
Result<?> result = message == null
|
||
? Result.failed(resultCode)
|
||
: Result.failed(resultCode, message);
|
||
|
||
int httpStatus = mapHttpStatus(resultCode);
|
||
writeResult(response, result, httpStatus);
|
||
}
|
||
|
||
/**
|
||
* 写入响应结果(通用方法)
|
||
*
|
||
* @param response HttpServletResponse
|
||
* @param result 响应结果对象
|
||
* @param httpStatus HTTP状态码
|
||
*/
|
||
private static void writeResult(HttpServletResponse response, Result<?> result, int httpStatus) {
|
||
try {
|
||
// 设置HTTP状态码
|
||
response.setStatus(httpStatus);
|
||
|
||
// 设置响应编码和内容类型
|
||
response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
|
||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||
|
||
// 写入响应
|
||
JakartaServletUtil.write(response,
|
||
JSONUtil.toJsonStr(result),
|
||
MediaType.APPLICATION_JSON_VALUE
|
||
);
|
||
|
||
} catch (Exception e) {
|
||
log.error("写入响应时发生未知异常: httpStatus={}, result={}", httpStatus, result, e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 根据业务结果码映射HTTP状态码
|
||
* 401: 未认证(token无效/过期)
|
||
* 403: 权限不足
|
||
* 400: 其他业务错误
|
||
*
|
||
* @param resultCode 业务结果码
|
||
* @return HTTP状态码
|
||
*/
|
||
private static int mapHttpStatus(ResultCode resultCode) {
|
||
return switch (resultCode) {
|
||
case ACCESS_UNAUTHORIZED,
|
||
ACCESS_TOKEN_INVALID,
|
||
REFRESH_TOKEN_INVALID -> HttpStatus.UNAUTHORIZED.value();
|
||
case ACCESS_PERMISSION_EXCEPTION -> HttpStatus.FORBIDDEN.value();
|
||
default -> HttpStatus.BAD_REQUEST.value();
|
||
};
|
||
}
|
||
}
|