当前位置: 首页 > 知识库问答 >
问题:

Spring Boot响应过滤器,用于在发送到客户端之前重构控制器响应

宰修能
2023-03-14

我有两个spring boot rest控制器,我希望向客户端发送一个标准的JSON响应结构。

标准响应将由响应时间、api响应代码、状态、apiName、响应(根据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() {
}
}

现在的问题是,我来自控制器的响应应该以标准方式序列化。下面是我的控制器方法。

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()中的getOutputStream()。

希望有人能帮忙?

共有2个答案

冯宏恺
2023-03-14

您使用的response.getOutputStream和过滤器是servlet相关的类,我认为没有它们您也可以做到这一点。只需制作您的自定义响应类并添加您想要的响应字段。在控制器中,只需返回新的响应实体(Httpstatus. OK,“您的消息”):我不知道这是否是您想要的行为。

张嘉佑
2023-03-14

只需将所有响应封装到一个decorator对象中。

class ResponseDecorator<T> {
  //global.fields (time,code, status.....)
  T response;
}

然后将此响应包装器包装到响应属性中

 类似资料:
  • 我是Spring启动滤镜的新手 我需要将servlet(impl)产生的响应修改成某种模式。 例如,GetProductImpl将给出 所以在它返回给客户端之前,我需要将其修改为(有点像将响应放在模块下)(对于所有servlet的所有响应) 我寻找任何可以让我做到这一点的方法,因为在impl内部做这件事是没有意义的,因为如果像这样,我需要为所有的impl做(这是很多的,不可行的)。 如果任何人有任

  • 我正在使用spring云网关作为边缘服务器。这就是流程 问题是,响应有响应是得到正确的200代码,注入的头是在响应上出现,但数据是不可用的响应。

  • 问题内容: 我正在编辑内置的表单。 我在对话框中显示该表单,然后提交。 数据已正确输入数据库。 但是我不知道是否需要将一些寄回。其实我对事情有点困惑。 假设我在表中使用``jQuery添加了一行,当我提交表单时,然后在提交数据之后,我想发回那些行数据,以便我可以动态添加表行以显示添加的数据。 我很困惑如何获取这些数据。 这是我当前的代码: 这只是带有成功消息的模板。 问题答案: Symfony 2

  • 在JAX-RS(RestEasy)中,我希望实现一个客户机过滤器,在发送请求之前修改头,这样我就不会对每个调用都手动执行此操作。 目前,我正在接收端执行此操作,以便在到达资源之前拦截请求。

  • 我的Spring控制器接受应用程序json响应体作为对象参数。我不知道在Spring控制器接收到json并抱怨它没有强制转换之前,我在哪里可以拦截json来验证这些值。 示例:用户向endpoint-/createUser发送json 期望:{"username":"johndoe","pin": 1234}接收:{"username": 1234,"pin":"johndoe"} 若发送int的