我有几个 Spring Boot Rest Controller ,我希望将标准 JSON 响应结构发送到客户端。
标准响应将由responseTime、apiResponseCode、status、apiName、response(根据api而有所不同)组成。见下文:
{
"responseTime": "2020-04-19T08:36:53.001",
"responseStatus": "SUCCESS",
"apiResponseCode": "SUCCESS",
"apiName": "PROPERTY_STORE_GET_PROPERTIES",
"response": [
{
"propertyName": "app.name",
"propertyValue": "property-store"
}
]
}
为了实现这一点,我创建了以下模型类:
package com.example.response.model;
import java.io.Serializable;
import java.time.LocalDateTime;
import com.example.constants.ApiResponseCode;
import com.example.constants.Status;
public class ApplicationResponse<T> implements Serializable {
private static final long serialVersionUID = -1715864978199998776L;
LocalDateTime responseTime;
Status responseStatus;
ApiResponseCode apiResponseCode;
String apiName;
T response;
public ApplicationResponse(LocalDateTime responseTime, Status status,
ApiResponseCode apiRespCode, String apiName, T response) {
this.responseTime = responseTime;
this.responseStatus = status;
this.apiResponseCode = apiRespCode;
this.apiName = apiName;
this.response = response;
}
// getters and setters
为了创建通用响应包装器,我创建了下面的响应 util 类。
import java.time.LocalDateTime;
import com.example.constants.ApiResponseCode;
import com.example.constants.Status;
import com.example.response.model.ApplicationResponse;
public class ResponseUtil {
public static <T> ApplicationResponse<T> createApplicationResponse(String
apiName, T response) {
return new ApplicationResponse<>(LocalDateTime.now(),
Status.SUCCESS, ApiResponseCode.SUCCESS, apiName,
response);
}
private ResponseUtil() {
}
}
现在的问题是我来自 Controller 的响应应该以标准方式序列化。下面显示的是我的 Controller 方法。
package com.example.propertystore.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RestController;
import com.example.constants.ApiResponseCode;
import com.example.constants.Status;
import com.example.exception.ApplicationException;
import com.example.exception.ApplicationExceptionHelper;
import com.example.propertystore.constants.PropertyStoreApiName;
import com.example.propertystore.dto.PropertyDTO;
import com.example.propertystore.entity.Property;
import com.example.propertystore.service.PropertyStoreService;
import com.example.response.ResponseUtil;
import com.example.response.model.ApplicationResponse;
@RestController
public class PropertyStoreControllerImpl implements PropertyStoreController {
@Autowired
PropertyStoreService propertyStoreService;
@Autowired
ApplicationExceptionHelper exceptionHelper;
@Override
public ApplicationResponse<List<PropertyDTO>> getProperties() throws ApplicationException {
ApplicationResponse<List<PropertyDTO>> response = null;
try {
response = ResponseUtil.createApplicationResponse(
PropertyStoreApiName.PROPERTY_STORE_GET_PROPERTIES.toString(),
propertyStoreService.getProperties());
} catch (Exception e) {
exceptionHelper.raiseApplicationException( HttpStatus.INTERNAL_SERVER_ERROR, Status.FAILURE,
ApiResponseCode.INTERNAL_SERVER_ERROR,
PropertyStoreApiName.PROPERTY_STORE_GET_PROPERTIES.toString(), null);
}
return response;
}}
在当前的实现中,我需要做的是在我的 Controller 中,我必须通过调用ResponseUtil.createApplicationResponse()来转换响应。这将导致整个 Controller 方法与 createApplicationResponse() 方法调用乱七八糟。
我想探索的是,是否有更简洁的方法使用 servlet 过滤器或 AOP 来实现此目的?
PS:我尝试了过滤选项,但无法理解如何继续操作。在 doFilter() 中检索 response.getOutputStream() 后卡住了。
希望有人能帮忙吗?
最佳答案
只需将所有响应包装到装饰器对象中即可。
class ResponseDecorator<T> {
//global.fields (time,code, status.....)
T response;
}
然后将此响应包装器包装到 ResponseEntity
关于java - Spring Boot 响应过滤器,用于在发送到客户端之前重构 Controller 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61292354/