【发布时间】:2020-08-01 04:16:53
【问题描述】:
我有几个 Spring Boot 休息控制器,我希望将标准 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
为了创建一个通用的响应包装器,我在响应工具类下面创建了。
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() {
}
}
现在的问题是我来自控制器的响应应该以标准方式序列化。下面显示的是我的控制器方法。
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;
}}
对于当前的实现,我必须在我的控制器中通过调用 ResponseUtil.createApplicationResponse() 来转换响应。这将使用 createApplicationResponse() 方法调用来处理整个控制器方法。
我想探索的是,是否有任何更简洁的方法可以使用 servlet 过滤器或 AOP 来实现这一点?
PS:我尝试了过滤选项,但不明白如何处理它。在 doFilter() 中检索 response.getOutputStream() 后卡住了。
希望有人能帮忙?
【问题讨论】:
-
也许可以更改 Jackson ObjectMapper 或注册自定义转换器?
标签: java spring spring-boot servlets