Spring Boot 2 JSON技術

8206 ワード

得ることと得ることはすべて代価があって、最も孤独で最も苦痛なあの时間は実はあなたの成長速度が最も速い时で、奮闘する年で享受を選んではいけなくて、私达は生命の天秤がいつも合理的な範囲内で揺れていることを知っていて、払ってやっと得る機会があります.
Spring Bootにはjacksonが内蔵されており、JSONのシーケンス化や逆シーケンス化が行われています.また、Redis、MongoDB、Elasticsearchなどのオブジェクトのシーケンス化は、他の技術と統合された場合にデフォルトでjacksonが行われます.
Controllerでメソッド注記を@ResponseBodyとすると,メソッドが返すオブジェクトを自動的にJSONにシーケンス化する.デフォルトの代わりにObjectMapperをカスタマイズする場合は、Java Configを使用し、@Beanを使用して構成できます.
ジャクソンは、ObjectMapperクラスを用いるPOJOオブジェクトをJSON文字列にシーケンス化し、JSON文字列をPOJOオブジェクトに逆シーケンス化することもできる.JackSonは、3つの階層のシーケンス化と逆シーケンス化をサポートします.
  • はJsonParserを用いてJSONを解析し、解析結果は一連のトークンであり、JsonGeneratorを用いてJSONを生成する.これは最下層の方式である.
  • 木遍歴方式を採用し、JSONはJsonNodeオブジェクトに読み込まれ、XML DOMを操作するようにJSONを読み取ることができる.
  • で採用されているDataBind方式は、POJOをJSONにシーケンス化したり、POJOに逆シーケンス化したりするのが最も直接的で最も簡単な方法ですが、ジャクソンの注釈や上記シーケンス化実装クラスを支援してシーケンス化や逆シーケンス化操作を個性化する必要がある場合があります.

  • ジャックソン遍歴
    ツリーループ方式は通常、POJOオブジェクトのないJSONに適しており、コードは以下の通りである.
    @Autowired
    private ObjectMapper mapper;	
    @GetMapping("/readtree.json")
    public @ResponseBody String readTree() throws IOException{
    	String json = "{\"name\":\"lijz\",\"id\":10}";
    	JsonNode node= mapper.readTree(json);
    	String name = node.get("name").asText();
    	int id = node.get("id").asInt();
    	return "name:"+name+",id:"+id;
    }

    readTreeメソッドは,文字列やバイト配列,ファイル,InputStreamなどを受け入れ,ルートノードとしてJsonNodeを返し,XML DOMを操作するようにJsonNodeを操作してデータを取得することができる.
    JsonNodeは以下の方法でJSONデータを読み取ることをサポートします.
  • asXXX、例えばasText、asBoolean、asInt中中等、JsonNode対応の値を読み出す.
  • Arrayは、JsonNodeが配列であるか否かを判断するために用いられ、配列であればGET(私)を呼び出して遍歴し、サイズ()で長さを取得することができる.
  • (文字列)を取得し、現在のノードのバイトポイントを取得し、上記のコードに示すようにJsonNodeを返します.

  • オブジェクトバインド
    アプリケーションでは、JSONデータにバインドするためにJavaオブジェクトを使用することが一般的です.ObjectMapperのreadValueのみを呼び出して実装します.たとえば、前の例では、JSONに対応するPOJOオブジェクトを作成することができます.POJOは次のようになります.
    public class User {
    Long id;
    String name;
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    }

    次にreadValueを使用して、上のJSON文字列を逆シーケンス化します.
    @Autowired
    private ObjectMapper mapper;	
    @GetMapping("/dataBind.json")
    public @ResponseBody String dataBind() throws IOException{
    	String json = "{\"name\":\"lijz\",\"id\":10}";
    	User user = mapper.readValue(json, User.class);
    	return "name:"+user.getName()+",id:"+user.getId();
    }

    POJOをJSONにシーケンス化し、マッピングされたwriteValueAsStringメソッドを使用します.
    @Autowired
    private ObjectMapper mapper;	
    @GetMapping("/serialization.json")
    public @ResponseBody String dataBind() throws IOException{
    	User user = new User();
    	user.setName("scg");
    	user.setId((long) 18);
    	String jsonStr = mapper.writeValueAsString(user);
    	return jsonStr;
    }

    フロー操作
    ツリーモデルとデータバインディングは、JsonParserクラス解析JSONによってJsonTokenストリームを形成するフロー操作に基づいて行われます.
    @Autowired
    private ObjectMapper mapper;
    @GetMapping("/parser.html")
    public @ResponseBody String parser() throws IOException{
    	String json = "{\"name\":\"lijz\",\"id\":10}";
    	JsonFactory fc = mapper.getFactory();
    	String key = null,value = null;
    	JsonParser parser = fc.createParser(json);
    	//{,START_OBJECT,     Token
    	JsonToken token = parser.nextToken();
    	int i =0;
    	String ret = "";
    	while(i

    JsonParserの解析結果は一連のJsonTokenを含み、JsonTokenは列挙タイプであり、よく使われるSTART_である.BOJECTは「{」;START_ARRAYおよびEND_ARRAYは「[」および「」を表し、FIELD_NAMEはJSON Keyを表し、VALUE_STRINGはJSON Value、文字列タイプを表し、VALUE_NUMBER_INTは整数タイプを表す.
    トークンのタイプを判断した後、呼び出されたgetValueAsXxxによってその値を取得し、XXXはその値のタイプである.
    @Autowired
    private ObjectMapper mapper;
    /**
     *    
     */
    @RequestMapping("/generator.html")
    	public @ResponseBody String generator() throws Exception{
    		JsonFactory fc = mapper.getFactory();
    		//   StringWriter
    		StringWriter sw = new StringWriter();
    		JsonGenerator g = fc.createGenerator(sw);
    		g.writeStartObject();
    		//"message","Hello world!"
    		g.writeStringField("name", "scg");
    		g.writeEndObject();
    		g.close();
    		return sw.toString();
    	}

    ジャクソン
    ジャクソンは多くの注釈を含み、シーケンス化と逆シーケンス化操作を個性化するために使用され、主に以下の注釈がある.
    @JsonProperty、属性に作用し、JSON Keyに別名を指定します.
    @JsonProperty("userName")
    private String name;

    @JsonIgnore、この属性を無視するために属性に作用します.
    @JsonIgnore
    private String age;

    @JsonIgnoreProperties、@JsonIgnoreProperties({"ID","写真"})のようなクラスに作用する属性のセットを無視します.
    @JsonIgnoreProperties({"id","photo"})
    public class User {}

    @JsonAnySetterは、あるメソッドにマークされています.このメソッドはキーを受け取り、値の2つのパラメータで、ジャクソンが逆シーケンス化中に見つからない対応する属性がサブメソッドを呼び出すために使用されます.通常、この方法は1つの図で実現される.
    private Map mp = new HashMap();
    @JsonAnySetter
    public void other(String property,String value){
    	mp.put(property, value);
    }

    @JsonAnyGetter、この注記は地図を返す方法に表示され、ジャクソンは地図の各値を取り出してシーケンス化します.
    @JsonFormat、日付の書式設定に使用します.
    @JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")
    private Date d;

    クラスまたは属性に作用する名前付きポリシーを指定する@JsonNaming@JsonPropertyと似ていますが、自動的に名前が付けられます.Jacksonには複数のネーミングポリシーが用意されており、出力されたキーがJavaのネーミング方式から下線ネーミング方法に変換されるなど、独自のネーミングポリシーを実現できます.usernameがUSER_に変換されます.NAME.
    @JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
    public class User {
    ……
    }

    @JsonSerialize、インプリメンテーションクラスを指定してシーケンス化をカスタマイズします.クラスはJsonSerializerインタフェースを実装する必要があります
    public class UserSerializer extends JsonSerializer {
    @Override
    public void serialize(User user, JsonGenerator jgen, SerializerProvider provider) throws IOException {
    	jgen.writeStartObject();
    	jgen.writeStringField("user-name", user.getName());
    	jgen.writeEndObject();
    	}
    }

    JsonGeneratorオブジェクトはジャクソンの下位レベルのシーケンス化実装であり、上のコードではシーケンス化された名前属性のみであり、出力の鍵はユーザー名が注釈@JsonSerializerを使用してユーザーオブジェクトのシーケンス化方法を指定することである.
    @JsonSerialize(using = UserSerializer.class)
    public class User {
    ……
    }

    @JsonDeserialize,ユーザカスタム逆シーケンス化,JsonSerialize,JsonDeserializerインタフェースを実装する必要がある.
    public class UserDeserializer extends JsonDeserializer {
    	@Override
    	public User deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    		JsonNode node = jp.getCodec().readTree(jp);
    		String name = node.get("user-name").asText();
    		User user = new User();
    		user.setName(name);
    		return user;
    	}
    }
    @JsonDeserialize(using = UserDeserializer.class)
    public class User {
    ……
    }

    クラスまたは属性に作用する、シーケンス化グループを定義する@JsonView.Spring MVCのコントローラメソッドは、同じ@JsonViewを使用して、このセットに属する構成をシーケンス化できます.たとえば、ユーザー・オブジェクトの場合、ID属性のみを返す場合がありますが、番号と名前のコードを返す必要がある場合があります.
    public class User {
    	public interface IdView{};
    	public interface IdNameView extends IdView{};
    	
    	@JsonView(IdView.class)
    	private Integer id;
    	@JsonView(IdNameView.class)
    	private String name;
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    }
    
    
    /**
    * controller
     */
    @JsonView(User.IdView.class)
    @RequestMapping("/id.json")
    public @ResponseBody User queryIds(){
    	User user = new User();
    	user.setId(1);
    	user.setName("scg");
    	return user;
    }

    ユーザは2つのインタフェースクラスを定義し、1つはIdViewであり、もう1つはIdName Viewであり、IdViewインタフェースを継承している.この2つのインタフェースは、2つのシーケンス化グループの順位を表します.属性IDは@JsonView(IdView.class)を使用し、属性nameは@JsonView(IdNameView.class)を使用する.Spring MVCのControllerメソッドでは、JsonView()を使用してグループ名を指定できます.シーケンス化されたオブジェクトは、このグループのプロパティのみシーケンス化されます.上記のコードはid属性のみを出力し、@JsonView(User.IdNameView.class)に変換すると名前属性が出力されます.また、ID属性のグループ名IdView.classはIdName Viewだからclassの親クラスも、同様に出力されます.