| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- package com.pharmacopoeia.config;
- import com.pharmacopoeia.dto.ApiResponse;
- import org.springframework.core.MethodParameter;
- import org.springframework.http.MediaType;
- import org.springframework.http.converter.HttpMessageConverter;
- import org.springframework.http.server.ServerHttpRequest;
- import org.springframework.http.server.ServerHttpResponse;
- import org.springframework.web.bind.annotation.RestControllerAdvice;
- import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
- /**
- * 对标记了 {@link UnifiedResponse} 的 Controller / 方法,
- * 自动将返回值包装为统一的 {@link ApiResponse} 格式:
- * {@code {code: 200, message: "ok", data: <原返回值> }}。
- *
- * <ul>
- * <li>已经是 ApiResponse → 不包装</li>
- * <li>流式(Flux / SSE)→ 不会进入此 Advice</li>
- * </ul>
- */
- @RestControllerAdvice
- public class UnifiedResponseBodyAdvice implements ResponseBodyAdvice<Object> {
- @Override
- public boolean supports(MethodParameter returnType,
- Class<? extends HttpMessageConverter<?>> converterType) {
- // 类或方法上有 @UnifiedResponse 才包装
- if (returnType.getMethodAnnotation(UnifiedResponse.class) != null) {
- return true;
- }
- return returnType.getContainingClass().getAnnotation(UnifiedResponse.class) != null;
- }
- @Override
- public Object beforeBodyWrite(Object body, MethodParameter returnType,
- MediaType selectedContentType,
- Class<? extends HttpMessageConverter<?>> selectedConverterType,
- ServerHttpRequest request, ServerHttpResponse response) {
- if (body instanceof ApiResponse || body instanceof byte[]) {
- return body;
- }
- if (body instanceof String) {
- return body;
- }
- return ApiResponse.success(body);
- }
- }
|