简体   繁体   English

返回具有键值对的JSON

[英]Return JSON with key-value pair

I use this code to generate response from REST endpoint: 我使用以下代码从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));
        }

Object: 宾语:

@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;
    }

    ......
}

Now I get this response: 现在,我得到以下响应:

{
  "response" : {
    "errors" : [ "expiration_year: must not be null", "default_transaction_type: must not be null"]
  }
}

I need to change it like this: 我需要这样更改:

{
      "response" : {
        "errors" : [ "expiration_year": "must not be null", "default_transaction_type": "must not be null"]
      }
    }

Is there someway to archive his without added a lot of "" symbols? 是否可以在不添加很多“”符号的情况下存档他的文件?

The " symbols are quotes, and they are necessary as part of the JSON specification. As for why your JSON is in a format you don't want, it has to do with your code here (and also in your corresponding StringResponseDTO ): "符号是引号,它们是JSON规范的一部分是必需的。至于为什么您的JSON是您不想要的格式,它与这里的代码(以及相应的StringResponseDTO )有关:

errorsList.add(error.getField() + ": " + error.getDefaultMessage());

You are adding strings to a list. 您正在将字符串添加到列表中。 What you want is to create a list of objects, instead. 您想要的是创建一个对象列表。 Each object would contain a property and string value. 每个对象将包含一个属性和字符串值。

What you have proposed is not valid JSON: 您提出的内容无效JSON:

{
  "response" : {
  "errors" : [ "expiration_year": "must not be null", "default_transaction_type": "must not be null"]
      }
}

What you need is this format instead (notice the object { symbols): 您需要的是这种格式(请注意对象{符号):

{
   "response" : {
   "errors" : [ {"expiration_year": "must not be null"}, {"default_transaction_type": "must not be null"}]
      }
}

The format you expressed in the "wanted" result isn't valid. 您在“所需”结果中表示的格式无效。
What you can do is use Jackson (or GSON, depending on the library you're using) classes, for example 您可以做的是使用Jackson类(或GSON,具体取决于您使用的库),例如

(Note, objectMapper is an instance of ObjectMapper ) (注意, objectMapperObjectMapper的实例)

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;
    }
}

That will be serialized to 那将被序列化为

{
    "redirect": "...",
    "errors": {
        "field1": "err field1",
        "field2": "err field2",
        "field3": "err field3"
    }
}

Or, if you prefer, the usual Map<String, String> solution. 或者,如果您愿意,可以使用通常的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;
    }
}

Which will output the same thing 哪个将输出相同的东西

{
    "redirect": "...",
    "errors": {
        "field1": "err field1",
        "field2": "err field2",
        "field3": "err field3"
    }
}

It's up to you. 由你决定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM