Я бы порекомендовал вам создать GenericReponse , который обернет все ваши ответы, это очень хорошо для внешнего интерфейса, также потому что вы сталкиваетесь с фиксированным шаблоном.
Так что через В этом решении вы можете обернуть любой объект и отправить его в ответ.
Я закодировал сценарий так:
1- Создайте класс GenericResponse
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class GenericResponse {
private Boolean error;
private List<ErrorPayload> errorPayload;
private Object payload;
public GenericResponse(Boolean error) {
this.error = error;
}
public static GenericResponse ok() {
return new GenericResponse(false);
}
public GenericResponse payload(Serializable o) {
this.payload = o;
return this;
}
//Getters and Setters and other Constructors
2-Create ErrorPayload Class
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ErrorPayload {
private String errorMessage;
private String errorType;
//Getters and Setters and Constructors
}
3-Create ExceptionConverter Service (Используется, когда у нас есть исключение)
@Service
public class ExceptionConverterService {
public GenericResponse convert(Exception x) {
GenericResponse genericResponse = new GenericResponse();
genericResponse.setError(true);
String exceptionType = x.getClass().getSimpleName();
String exceptionMessage = x.getClass().getSimpleName();
genericResponse.setErrorPayload(Collections.singletonList(new ErrorPayload(exceptionType, exceptionMessage)));
return genericResponse;
}
}
4-Измените свой сценарий с помощью GenericResponse
Все, что вам нужно сделать, это:
- Создать вышеупомянутые классы (Скопировать код что я написал в 1, 2 и 3)
- Измените форму ответа
List<Map<String, Object>>
на GenericResponse
- Оберните ваши типы возврата в
GenericResponse
Я изменил ваш код следующим образом (просто измените 3 строки)
@RestController
public class TestController {
@Autowired
private ExceptionConverterService exceptionConverter;
@GetMapping("/runquery")
@ResponseBody
//Changed (Change Return type to GenericResponse )
public GenericResponse runQuery(@RequestParam(name = "queryId") String queryId, @RequestParam(name = "formData") String formData, HttpServletResponse response) throws IOException {
try {
//Your code
}
} catch (Exception e) {
//Changed (Create GenericResponse for Exception)
GenericResponse genericResponse = exceptionConverter.convert(e);
return genericResponse;
}
//Changed (Create GenericResponse for main result)
return GenericResponse.ok().payload(queryResultFinal);
}
}
Примеры для двух сценариев ios (сначала без Ион и второй за исключением)
Образец 1
Контроллер с GenericResponse (У нас нет исключений в этом примере)
@RestController
public class TestController {
@GetMapping(value = "/getNameAndFamily")
public GenericResponse getNameAndFamily() {
Map<String, String> person = new HashMap<>();
person.put("name", "foo");
person.put("family", "bar");
return GenericResponse.ok().payload((Serializable) person);
}
}
Результат выглядит следующим образом:
{
"error": false,
"payload": {
"name": "foo",
"family": "bar"
}
}
Пример 2
контроллер с GenericResponse, когда у нас есть Исключение в бизнесе
@RestController
public class TestController {
@Autowired
private ExceptionConverterService exceptionConverter;
@GetMapping(value = "/getNameAndFamily")
public GenericResponse getNameAndFamily() {
try {
//Create Fake Exception
int i = 1 / 0;
return GenericResponse.ok();
} catch (Exception e) {
//Handle Exception
GenericResponse genericResponse = exceptionConverter.convert(e);
return GenericResponse.ok().payload((Serializable) genericResponse);
}
}
}
Результат как следует:
{
"error": true,
"errorPayload": [
{
"errorType": "ArithmeticException"
}
]
}