programing

자바에서 JSON을 유창하게 구축하는 방법은?

sourcejob 2022. 11. 23. 20:13
반응형

자바에서 JSON을 유창하게 구축하는 방법은?

저는 다음과 같은 것을 생각하고 있습니다.

String json = new JsonBuilder()
  .add("key1", "value1")
  .add("key2", "value2")
  .add("key3", new JsonBuilder()
    .add("innerKey1", "value3"))
  .toJson();

이런 종류의 유창한 건물에 가장 적합한 Java JSON 라이브러리는 무엇입니까?

업데이트: GSON을 포장하여 거의 원하는 결과를 얻었습니다... 번의 장애로...

org.json 라이브러리를 사용하고 있는데, 매우 친절하고 편리합니다.

예:

String jsonString = new JSONObject()
                  .put("JSON1", "Hello World!")
                  .put("JSON2", "Hello my World!")
                  .put("JSON3", new JSONObject().put("key1", "value1"))
                  .toString();

System.out.println(jsonString);

출력:

{"JSON2":"Hello my World!","JSON3":{"key1":"value1"},"JSON1":"Hello World!"}

Java EE 7 Json 사양을 참조하십시오.올바른 방법은 다음과 같습니다.

String json = Json.createObjectBuilder()
            .add("key1", "value1")
            .add("key2", "value2")
            .build()
            .toString();

최근에 Gson 객체를 유창하게 만들기 위한 라이브러리를 만들었습니다.

http://jglue.org/fluent-json/

다음과 같이 동작합니다.

  JsonObject jsonObject = JsonBuilderFactory.buildObject() //Create a new builder for an object
  .addNull("nullKey")                            //1. Add a null to the object

  .add("stringKey", "Hello")                     //2. Add a string to the object
  .add("stringNullKey", (String) null)           //3. Add a null string to the object

  .add("numberKey", 2)                           //4. Add a number to the object
  .add("numberNullKey", (Float) null)            //5. Add a null number to the object

  .add("booleanKey", true)                       //6. Add a boolean to the object
  .add("booleanNullKey", (Boolean) null)         //7. Add a null boolean to the object

  .add("characterKey", 'c')                      //8. Add a character to the object
  .add("characterNullKey", (Character) null)     //9. Add a null character to the object

  .addObject("objKey")                           //10. Add a nested object
    .add("nestedPropertyKey", 4)                 //11. Add a nested property to the nested object
    .end()                                       //12. End nested object and return to the parent builder

  .addArray("arrayKey")                          //13. Add an array to the object
    .addObject()                                 //14. Add a nested object to the array
      .end()                                     //15. End the nested object
    .add("arrayElement")                         //16. Add a string to the array
    .end()                                       //17. End the array

    .getJson();                                  //Get the JsonObject

String json = jsonObject.toString();

또한 속성 키를 사용하여 요소를 배열에 추가하거나 속성 이름이 없는 개체에 요소를 추가하려고 하면 제네릭스를 통해 컴파일 오류가 발생합니다.

JsonObject jsonArray = JsonBuilderFactory.buildArray().addObject().end().add("foo", "bar").getJson(); //Error: tried to add a string with property key to array.
JsonObject jsonObject = JsonBuilderFactory.buildObject().addArray().end().add("foo").getJson(); //Error: tried to add a string without property key to an object.
JsonArray jsonArray = JsonBuilderFactory.buildObject().addArray("foo").getJson(); //Error: tried to assign an object to an array.
JsonObject jsonObject = JsonBuilderFactory.buildArray().addObject().getJson(); //Error: tried to assign an object to an array.

마지막으로 API에서는 도메인 개체를 JSON에 매핑할 수 있는 매핑 지원이 있습니다.Java8이 출시되면 다음과 같은 작업을 수행할 수 있습니다.

Collection<User> users = ...;
JsonArray jsonArray = JsonBuilderFactory.buildArray(users, { u-> buildObject()
                                                                 .add("userName", u.getName())
                                                                 .add("ageInYears", u.getAge()) })
                                                                 .getJson();

잭슨 형이랑 같이 쓰시는 분들은JsonNodebuilding in code, 다음과 같은 유틸리티 세트에 관심이 있을 수 있습니다.이러한 기능을 사용하면 구축 중인 JSON의 구조를 보다 잘 보여주는 보다 자연스러운 체인 스타일을 지원할 수 있습니다.

다음은 사용 예를 제시하겠습니다.

import static JsonNodeBuilders.array;
import static JsonNodeBuilders.object;

...

val request = object("x", "1").with("y", array(object("z", "2"))).end();

이는 다음 JSON에 해당합니다.

{"x":"1", "y": [{"z": "2"}]}

클래스는 다음과 같습니다.

import static lombok.AccessLevel.PRIVATE;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;

import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;

/**
 * Convenience {@link JsonNode} builder.
 */
@NoArgsConstructor(access = PRIVATE)
public final class JsonNodeBuilders {

  /**
   * Factory methods for an {@link ObjectNode} builder.
   */

  public static ObjectNodeBuilder object() {
    return object(JsonNodeFactory.instance);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, boolean v1) {
    return object().with(k1, v1);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, int v1) {
    return object().with(k1, v1);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, float v1) {
    return object().with(k1, v1);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, String v1) {
    return object().with(k1, v1);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, String v1, @NonNull String k2, String v2) {
    return object(k1, v1).with(k2, v2);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, String v1, @NonNull String k2, String v2,
      @NonNull String k3, String v3) {
    return object(k1, v1, k2, v2).with(k3, v3);
  }

  public static ObjectNodeBuilder object(@NonNull String k1, JsonNodeBuilder<?> builder) {
    return object().with(k1, builder);
  }

  public static ObjectNodeBuilder object(JsonNodeFactory factory) {
    return new ObjectNodeBuilder(factory);
  }

  /**
   * Factory methods for an {@link ArrayNode} builder.
   */

  public static ArrayNodeBuilder array() {
    return array(JsonNodeFactory.instance);
  }

  public static ArrayNodeBuilder array(@NonNull boolean... values) {
    return array().with(values);
  }

  public static ArrayNodeBuilder array(@NonNull int... values) {
    return array().with(values);
  }

  public static ArrayNodeBuilder array(@NonNull String... values) {
    return array().with(values);
  }

  public static ArrayNodeBuilder array(@NonNull JsonNodeBuilder<?>... builders) {
    return array().with(builders);
  }

  public static ArrayNodeBuilder array(JsonNodeFactory factory) {
    return new ArrayNodeBuilder(factory);
  }

  public interface JsonNodeBuilder<T extends JsonNode> {

    /**
     * Construct and return the {@link JsonNode} instance.
     */
    T end();

  }

  @RequiredArgsConstructor
  private static abstract class AbstractNodeBuilder<T extends JsonNode> implements JsonNodeBuilder<T> {

    /**
     * The source of values.
     */
    @NonNull
    protected final JsonNodeFactory factory;

    /**
     * The value under construction.
     */
    @NonNull
    protected final T node;

    /**
     * Returns a valid JSON string, so long as {@code POJONode}s not used.
     */
    @Override
    public String toString() {
      return node.toString();
    }

  }

  public final static class ObjectNodeBuilder extends AbstractNodeBuilder<ObjectNode> {

    private ObjectNodeBuilder(JsonNodeFactory factory) {
      super(factory, factory.objectNode());
    }

    public ObjectNodeBuilder withNull(@NonNull String field) {
      return with(field, factory.nullNode());
    }

    public ObjectNodeBuilder with(@NonNull String field, int value) {
      return with(field, factory.numberNode(value));
    }

    public ObjectNodeBuilder with(@NonNull String field, float value) {
      return with(field, factory.numberNode(value));
    }

    public ObjectNodeBuilder with(@NonNull String field, boolean value) {
      return with(field, factory.booleanNode(value));
    }

    public ObjectNodeBuilder with(@NonNull String field, String value) {
      return with(field, factory.textNode(value));
    }

    public ObjectNodeBuilder with(@NonNull String field, JsonNode value) {
      node.set(field, value);
      return this;
    }

    public ObjectNodeBuilder with(@NonNull String field, @NonNull JsonNodeBuilder<?> builder) {
      return with(field, builder.end());
    }

    public ObjectNodeBuilder withPOJO(@NonNull String field, @NonNull Object pojo) {
      return with(field, factory.pojoNode(pojo));
    }

    @Override
    public ObjectNode end() {
      return node;
    }

  }

  public final static class ArrayNodeBuilder extends AbstractNodeBuilder<ArrayNode> {

    private ArrayNodeBuilder(JsonNodeFactory factory) {
      super(factory, factory.arrayNode());
    }

    public ArrayNodeBuilder with(boolean value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull boolean... values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(int value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull int... values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(float value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(String value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull String... values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull Iterable<String> values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(JsonNode value) {
      node.add(value);
      return this;
    }

    public ArrayNodeBuilder with(@NonNull JsonNode... values) {
      for (val value : values)
        with(value);
      return this;
    }

    public ArrayNodeBuilder with(JsonNodeBuilder<?> value) {
      return with(value.end());
    }

    public ArrayNodeBuilder with(@NonNull JsonNodeBuilder<?>... builders) {
      for (val builder : builders)
        with(builder);
      return this;
    }

    @Override
    public ArrayNode end() {
      return node;
    }

  }

}

실장에서는 Lombok을 사용하지만 Java 보일러 플레이트를 채우기 위해 쉽게 분리할 수 있습니다.

String json = new JsonBuilder(new GsonAdapter())
  .object("key1", "value1")
  .object("key2", "value2")
  .object("key3")
    .object("innerKey1", "value3")
    .build().toString();

위의 솔루션이 우아하다고 생각되면 Json Builder lib를 사용해 보십시오.다양한 유형의 Json 라이브러리를 위한 json 구조를 한 가지 방법으로 구축할 수 있도록 작성되었습니다.현재 구현에는 Gson, Jackson 및 MongoDB가 포함됩니다.예를 들면.잭슨은 방금 바꿨다:

String json = new JsonBuilder(new JacksonAdapter()).

요청에 따라 기꺼이 다른 사람을 추가할 것이고, 혼자서 실행하는 것도 꽤 쉽습니다.

json-lib에 접속하고 싶은 것 같습니다.

http://json-lib.sourceforge.net/

Douglas Crockford는 JSON을 발명한 사람입니다.Java 라이브러리는 다음과 같습니다.

http://www.json.org/java/

Json-lib의 사람들이 Crockford가 멈춘 곳을 다시 찾은 것 같군요.둘 다 JSON을 완전히 지원하며, JSONObject, JSONArray 및 JSONFunction 구조를 사용합니다.

'도움이 됐으면 좋겠다...

레퍼런스 실장에는, 유창한 인터페이스가 포함되어 있습니다.JSONWriter와 그 toString 구현 하위 클래스 JSONStringer를 확인합니다.

유창한 Json Builder와 함께 휴식 끝점 테스트를 작성할 수 있는 좋은 방법을 찾아 이곳에 왔습니다.제 경우 JSONObject를 사용하여 전문 빌더를 구축했습니다.약간의 인스트루먼트가 필요하지만 사용법은 매우 좋습니다.

import lombok.SneakyThrows;
import org.json.JSONObject;

public class MemberJson extends JSONObject {

    @SneakyThrows
    public static MemberJson builder() {
        return new MemberJson();
    }

    @SneakyThrows
    public MemberJson name(String name) {
        put("name", name);
        return this;
    }

}
MemberJson.builder().name("Member").toString();

org.json을 사용하여 온 디맨드로 json을 만듭니다.기본적인 json 오브젝트를 가지고 있었는데 API로 보내기 전에 하나의 래퍼 요소로 랩해야 합니다.

기능 테스트용 이 json을 생성하기 위한 코드는 다음과 같습니다.

base-request.json 파일의 내용은 다음과 같습니다.

{
  "name":"sanjay"
  "age":32,
  "occupation":"software engineer"
}


String baseRequest = Files.readString(Paths.get("./src/test/resources", "base-request.json"));
    JSONObject baseJsonObject = new JSONObject(baseRequest);
    JSONObject wrappedJsonObject = new JSONObject().put("employee", baseJsonObject);

이제 wrapedJsonObject가 다음 형식으로 요청을 예상하는 API로 전송됩니다.

{
  "employee": {
    "name":"sanjay"
    "age":32,
    "occupation":"software engineer"
  }
}

아래는 테스트 코드입니다.Rest Assured API를 사용하여 Json을 API로 전달합니다.

RequestSpecification request = given()
            .contentType(JSON)
            .body(wrappedJsonObject.toString());
    response = request.post(new URL(HTTP, host, port, endPoint));

그냥 돼요.인터페이스를 사용하면 됩니다.JsonElementInterfacestring toJson() 클래스, " " " "AbstractJsonElement합니다.

요.JSONProperty.JSONValue의 토큰 (임의의 토큰),JSONArray및 ([...]), »JSONObject})

JSONObjectJSONProperty
JSONArrayAbstractJsonElement

는 해당 add vararg를 반환해야 .this

마음에 안 들면 수정하면 돼

인터페이스와 추상 클래스의 장점은 다음과 같습니다.JSONArray수 성성 can can can can can can can can can can can can can can 。JSONProperty 또는 수 .

언더스코어 자바 라이브러리에는 json builder가 있습니다.

import com.github.underscore.U;

public static void main(String[] args) {
  String json = U.objectBuilder()
    .add("key1", "value1")
    .add("key2", "value2")
    .add("key3", U.objectBuilder()
      .add("innerKey1", "value3"))
    .toJson();
  System.out.println(json);
}

Output:
{
  "key1": "value1",
  "key2": "value2",
  "key3": {
    "innerKey1": "value3"
  }
}

Java 템플릿엔진 중 하나를 사용할 수 있습니다.나는 당신이 당신의 논리를 견해와 분리하기 때문에 이 방법을 좋아합니다.

Java 8+:

<dependency>
  <groupId>com.github.spullara.mustache.java</groupId>
  <artifactId>compiler</artifactId>
  <version>0.9.6</version>
</dependency>

Java 6/7:

<dependency>
  <groupId>com.github.spullara.mustache.java</groupId>
  <artifactId>compiler</artifactId>
  <version>0.8.18</version>
</dependency>

템플릿 파일 예시:

{{#items}}
Name: {{name}}
Price: {{price}}
  {{#features}}
  Feature: {{description}}
  {{/features}}
{{/items}}

일부 백업 코드로 전원이 공급될 수 있습니다.

public class Context {
  List<Item> items() {
    return Arrays.asList(
      new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))),
      new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly.")))
    );
  }

  static class Item {
    Item(String name, String price, List<Feature> features) {
      this.name = name;
      this.price = price;
      this.features = features;
    }
    String name, price;
    List<Feature> features;
  }

  static class Feature {
    Feature(String description) {
       this.description = description;
    }
    String description;
  }
}

그 결과 다음과 같은 결과가 초래됩니다.

Name: Item 1
Price: $19.99
  Feature: New!
  Feature: Awesome!
Name: Item 2
Price: $29.99
  Feature: Old.
  Feature: Ugly.
  • 콧수염 : https://github.com/spullara/mustache.java
  • 하지만 진자(https://github.com/HubSpot/jinjava)도 있다.
  • 당근 : https://github.com/codeka/carrot

언급URL : https://stackoverflow.com/questions/8876089/how-to-fluently-build-json-in-java

반응형