首页 > 解决方案 > SpringBoot:将控制器响应包装到另一个对象中

问题描述

考虑下面的控制器方法,

@GetMapping("/getdata")
public Data getDetails() {
                
    try {
        Data obj = template.getForObject("http://localhost:8090/details/get", Data.class);
        return obj; 

    } catch (Exception e) {
        .....
    }       
}

假设上述端点的响应对象看起来像,

data : {
 name : "ABCD",
 age  : "20"
}

现在我想要实现的是将整个响应对象包装在另一个对象下,所以最终的响应应该是这样的,

{
   status : "SOMETHING",
   response : {
     name : "ABCD",
     age  : "20"
   },
   extra : null
}

所以问题是,我不想在每个控制器方法下创建一个函数来将值发送到这个 Wrapper 对象。我的问题是,Spring Framework 中是否有任何可能性允许我在某处创建一个 Global Wrapper 函数,它会自动选择它并包装来自控制器的响应?

标签: javaspringspring-boot

解决方案


您需要将 a 实现ResponseBodyAdvice@ControllerAdvice. 首先,您需要有一个通用响应模型。

public class GenericResponse<T> {
    private String status;
    private String extra;
    private T response;
}

然后你需要实现它ResponseBodyAdvice本身:

@ControllerAdvice
public class CustomResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object response, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
                                  ServerHttpResponse response) {    
        GenericResponse<Object> genericResponse = new GenericResponse<>();
        output.setStatus("SOMETHING"); // I guess that you need some logic here
        output.setResponse(response);
        return genericResponse;
    }
}

推荐阅读