Я использую этот код для генерации ответа от конечной точки REST:
if (result.hasErrors()) {
List<String> errorsList = new ArrayList<>();
List<FieldError> errors = result.getFieldErrors();
for (FieldError error : errors ) {
System.out.println("Validation error in field: " + error.getObjectName()
+ "! Validation error message: " + error.getDefaultMessage()
+ "! Rejected value:" + error.getRejectedValue());
errorsList.add(error.getField() + ": " + error.getDefaultMessage());
}
return ResponseEntity.ok(new StringResponseDTO(errorsList));
}
Объект:
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
@JsonTypeName("response")
public class StringResponseDTO {
private String redirect;
private List<String> errors;
public StringResponseDTO(String redirect) {
super();
this.redirect = redirect;
}
public StringResponseDTO(List<String> errors) {
this.errors = errors;
}
......
}
Теперь я получаю этот ответ:
{
"response" : {
"errors" : [ "expiration_year: must not be null", "default_transaction_type: must not be null"]
}
}
Мне нужно изменить это так:
{
"response" : {
"errors" : [ "expiration_year": "must not be null", "default_transaction_type": "must not be null"]
}
}
Есть ли способ заархивировать его, не добавляя много символов ""?




Символы " — это кавычки, и они необходимы как часть спецификации JSON. Что касается того, почему ваш JSON находится в формате, который вам не нужен, это связано с вашим кодом здесь (а также с вашим соответствующим StringResponseDTO):
errorsList.add(error.getField() + ": " + error.getDefaultMessage());
Вы добавляете строки в список. Вместо этого вы хотите создать список объектов. Каждый объект будет содержать свойство и строковое значение.
То, что вы предложили, недействительно JSON:
{
"response" : {
"errors" : [ "expiration_year": "must not be null", "default_transaction_type": "must not be null"]
}
}
Вместо этого вам нужен этот формат (обратите внимание на символы объекта {):
{
"response" : {
"errors" : [ {"expiration_year": "must not be null"}, {"default_transaction_type": "must not be null"}]
}
}
Формат, который вы указали в результате «требуется», недействителен.
Что вы можете сделать, так это использовать классы Jackson (или GSON, в зависимости от используемой вами библиотеки), например
(Обратите внимание, objectMapper является экземпляром ObjectMapper)
public class StringResponseDTO {
private String redirect;
private TreeNode errors;
public StringResponseDTO(final String redirect) {
this.redirect = redirect;
}
public StringResponseDTO(final Collection<? extends FieldError> errors) {
this.errors =
errors.stream()
.collect(Collector.of(
objectMapper::createObjectNode,
(json, e) -> json.put(e.getField(), e.getDefaultMessage()),
(json, toMerge) -> {
json.setAll(toMerge);
return json;
}
));
}
public String getRedirect() {
return redirect;
}
public TreeNode getErrors() {
return errors;
}
}
Это будет сериализовано в
{
"redirect": "...",
"errors": {
"field1": "err field1",
"field2": "err field2",
"field3": "err field3"
}
}
Или, если хотите, обычное Map<String, String> решение.
public class StringResponseDTO {
private String redirect;
private Map<String, String> errors;
public StringResponseDTO(final String redirect) {
this.redirect = redirect;
}
public StringResponseDTO(final Collection<? extends FieldError> errors) {
this.errors =
errors.stream()
.collect(Collectors.toMap(
FieldError::getField,
FieldError::getDefaultMessage
));
}
public String getRedirect() {
return redirect;
}
public Map<String, String> getErrors() {
return errors;
}
}
Который выведет то же самое
{
"redirect": "...",
"errors": {
"field1": "err field1",
"field2": "err field2",
"field3": "err field3"
}
}
Тебе решать.
Я получаю: конструктор StringResponseDTO(Map<String,String>) не определен
@PeterPenzov, где ты видишь этот конструктор?
Коллекция @PeterPenzov означает, что вам все равно нужно пройти в List<FieldError>, а не в Map
Я получаю эту ошибку в этой строке return ResponseEntity.ok(new StringResponseDTO(errorsList));
@PeterPenzov см. комментарий выше (коллекция означает, что вам все еще нужно пройти в List<FieldError>, а не в Map)
@PeterPenzov, кстати, удалите «final var objectMapper = new ObjectMapper();». Это был остаток.
List<String> errorsдолжен бытьMap<String, String>, но он будет преобразован в объект, так как массивы json не поддерживают ключи