Фильтр ответов Spring boot для реструктуризации ответа контроллера перед отправкой клиенту - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть пара контроллеров пружинной загрузки, и я хочу, чтобы стандартная структура ответа 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

Чтобы создать обобщенную c оболочку ответа, я создал ниже класс util 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 () .

Что я хотел исследовать, так это то, что если есть какой-то более чистый способ достижения этого с использованием фильтров сервлетов или АОП?

PS: я попробовал параметр фильтра, но не мог понять, как его обойти. Застрял после получения response.getOutputStream () в doFilter ().

Надеюсь, кто-нибудь может помочь?

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Просто оберните все ваши ответы в объект декоратора.

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

Затем оберните эту оболочку ответа в ResponseEntity

0 голосов
/ 18 апреля 2020

Ответ.getOutputStream, который вы использовали, и фильтры - это классы, связанные с сервлетами, и я думаю, что вы можете сделать это без них. Просто создайте свой собственный класс ответа и добавьте поля так, как вы хотите, чтобы ваш ответ. Чем в контроллере, просто вернуть новый ResponseEntity (HttpStatus.OK, «ваше сообщение»): я не знаю, если это поведение, которое вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...