UnifiedResponseBodyAdvice.java 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. package com.pharmacopoeia.config;
  2. import com.pharmacopoeia.dto.ApiResponse;
  3. import org.springframework.core.MethodParameter;
  4. import org.springframework.http.MediaType;
  5. import org.springframework.http.converter.HttpMessageConverter;
  6. import org.springframework.http.server.ServerHttpRequest;
  7. import org.springframework.http.server.ServerHttpResponse;
  8. import org.springframework.web.bind.annotation.RestControllerAdvice;
  9. import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
  10. /**
  11. * 对标记了 {@link UnifiedResponse} 的 Controller / 方法,
  12. * 自动将返回值包装为统一的 {@link ApiResponse} 格式:
  13. * {@code {code: 200, message: "ok", data: <原返回值> }}。
  14. *
  15. * <ul>
  16. * <li>已经是 ApiResponse → 不包装</li>
  17. * <li>流式(Flux / SSE)→ 不会进入此 Advice</li>
  18. * </ul>
  19. */
  20. @RestControllerAdvice
  21. public class UnifiedResponseBodyAdvice implements ResponseBodyAdvice<Object> {
  22. @Override
  23. public boolean supports(MethodParameter returnType,
  24. Class<? extends HttpMessageConverter<?>> converterType) {
  25. // 类或方法上有 @UnifiedResponse 才包装
  26. if (returnType.getMethodAnnotation(UnifiedResponse.class) != null) {
  27. return true;
  28. }
  29. return returnType.getContainingClass().getAnnotation(UnifiedResponse.class) != null;
  30. }
  31. @Override
  32. public Object beforeBodyWrite(Object body, MethodParameter returnType,
  33. MediaType selectedContentType,
  34. Class<? extends HttpMessageConverter<?>> selectedConverterType,
  35. ServerHttpRequest request, ServerHttpResponse response) {
  36. if (body instanceof ApiResponse || body instanceof byte[]) {
  37. return body;
  38. }
  39. if (body instanceof String) {
  40. return body;
  41. }
  42. return ApiResponse.success(body);
  43. }
  44. }