Izrada prilagođene bilješke u Javi

1. Uvod

Java napomene su mehanizam za dodavanje podataka o metapodacima u naš izvorni kod. Moćan su dio Jave i dodani su u JDK5. Bilješke nude alternativu upotrebi XML deskriptora i sučelja markera.

Iako ih možemo priložiti paketima, klasama, sučeljima, metodama i poljima, bilješke same po sebi nemaju utjecaja na izvršavanje programa.

U ovom uputstvu usredotočit ćemo se na to kako stvoriti prilagođene bilješke i kako ih obraditi. Više o bilješkama možemo pročitati u našem članku o osnovama napomena.

2. Izrada prilagođenih bilješki

Stvorit ćemo tri prilagođene bilješke s ciljem serializacije objekta u JSON niz.

Koristit ćemo prvu na razini klase, kako bismo ukazali kompajleru da se naš objekt može serializirati. Dalje ćemo primijeniti drugo na polja koja želimo uključiti u JSON niz.

Konačno, upotrijebit ćemo treću napomenu na razini metode da odredimo metodu kojom ćemo inicijalizirati svoj objekt.

2.1. Primjer bilješke na razini razreda

Prvi korak ka stvaranju prilagođene bilješke je da to proglasi pomoću @sučelje ključna riječ:

javni @interface JsonSerializable {}

Sljedeći je korak dodajte meta-bilješke da odredite opseg i cilj naše prilagođene bilješke:

@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.Type) public @interface JsonSerializable {}

Kao što vidimo, naša prva napomena ima vidljivost izvršavanja i možemo je primijeniti na vrste (klase). Štoviše, on nema metode, pa stoga služi kao jednostavan marker za označavanje klasa koje se mogu serializirati u JSON.

2.2. Primjer bilješke na razini polja

Na isti način izrađujemo i drugu napomenu kako bismo označili polja koja ćemo uključiti u generirani JSON:

@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.FIELD) public @interface JsonElement {public String key () default ""; }

Bilješka deklarira jedan parametar Stringa s imenom "ključ" i praznim nizom kao zadanu vrijednost.

Prilikom izrade prilagođenih bilješki s metodama, trebali bismo biti svjesni da to metode ne smiju imati parametre i ne mogu izbaciti iznimku. Također, vrste povratka ograničene su na primitive, String, Class, enume, napomene i nizove ovih tipova,a zadana vrijednost ne može biti null.

2.3. Primjer bilješke na razini metode

Zamislimo da, prije serializacije objekta u JSON niz, želimo izvršiti neku metodu za inicijalizaciju objekta. Iz tog ćemo razloga stvoriti bilješku kako bismo obilježili ovu metodu:

@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface Init {}

Proglasili smo javnu napomenu s vidljivošću izvođenja koju možemo primijeniti na metode naših predavanja.

2.4. Primjena bilješki

Sada, da vidimo kako možemo koristiti naše prilagođene bilješke. Na primjer, zamislimo da imamo objekt tipa Osoba da želimo serializirati u JSON niz. Ova vrsta ima metodu koja velikim slovom stavlja prvo slovo imena i prezimena. Morat ćemo pozvati ovu metodu prije serializacije objekta:

@JsonSerializable javna klasa Osoba {@JsonElement private String firstName; @JsonElement private String lastName; @JsonElement (key = "personAge") private String dob; privatna string adresa; @Init private void initNames () {this.firstName = this.firstName.substring (0, 1) .toUpperCase () + this.firstName.substring (1); this.lastName = this.lastName.substring (0, 1) .toUpperCase () + this.lastName.substring (1); } // Standardni getteri i postavljači}

Korištenjem naših prilagođenih bilješki ukazujemo na to da možemo serializirati a Osoba objekt JSON nizu. Uz to, izlaz bi trebao sadržavati samo ime, prezime, i dob polja tog objekta. Štoviše, mi želimo initNames () metoda koja se poziva prije serializacije.

Postavljanjem ključ parametar @JsonElement napomena na “personAge”, naznačujemo da ćemo koristiti ovo ime kao identifikator polja u JSON izlazu.

Radi demonstracije napravili smo initNames () private, tako da ne možemo inicijalizirati svoj objekt pozivanjem ručno, a ni naši ga konstruktori ne koriste.

3. Obrada bilješki

Do sada smo vidjeli kako stvoriti prilagođene bilješke i kako ih koristiti za ukrašavanje Osoba razred. Sada, vidjet ćemo kako ih iskoristiti pomoću Java-ovog Reflection API-ja.

Prvi korak bit će provjeriti je li naš objekt null ili ne, kao i to ima li njegov tip @JsonSerializable napomena ili ne:

private void checkIfSerializable (objektni objekt) {if (Objects.isNull (objekt)) {throw new JsonSerializationException ("Objekt za serializaciju je null"); } Klasa klazz = object.getClass (); if (! clazz.isAnnotationPresent (JsonSerializable.class)) {throw new JsonSerializationException ("Klasa" + clazz.getSimpleName () + "nije označena sa JsonSerializable"); }}

Zatim tražimo bilo koju metodu s oznakom @Init i izvršavamo je kako bismo inicijalizirali polja našeg objekta:

private void initializeObject (objektni objekt) baca iznimku {Class clazz = object.getClass (); za (Metoda metode: clazz.getDeclaredMethods ()) {if (method.isAnnotationPresent (Init.class)) {method.setAccessible (true); method.invoke (objekt); }}}

Zov od metoda.setAccessible(pravi) omogućuje nam izvršenje privatnog initNames () metoda.

Nakon inicijalizacije, prelistavamo polja našeg objekta, dohvaćamo ključ i vrijednost JSON elemenata i stavljamo ih na mapu. Zatim na karti kreiramo JSON niz:

private String getJsonString (objektni objekt) baca iznimku {Class clazz = object.getClass (); Mapa jsonElementsMap = novi HashMap (); za (Polje polja: clazz.getDeclaredFields ()) {field.setAccessible (true); if (field.isAnnotationPresent (JsonElement.class)) {jsonElementsMap.put (getKey (polje), (String) field.get (objekt)); }} Niz jsonString = jsonElementsMap.entrySet () .stream () .map (entry -> "\" "+ entry.getKey () +" \ ": \" "+ entry.getValue () +" \ "") .collect (Collectors.joining (",")); vrati "{" + jsonString + "}"; }

Opet, koristili smo polje.setAccessible(true) jer Osoba polja objekta su privatna.

Naša klasa JSON serializatora kombinira sve gore navedene korake:

javna klasa ObjectToJsonConverter {javni niz convertToJson (objektni objekt) baca JsonSerializationException {try {checkIfSerializable (objekt); initializeObject (objekt); vrati getJsonString (objekt); } catch (Exception e) {throw new JsonSerializationException (e.getMessage ()); }}}

Konačno, pokrećemo jedinstveni test kako bismo provjerili je li naš objekt serializiran kako je definirano našim prilagođenim bilješkama:

@Test public void givenObjectSerializedThenTrueReturned () baca JsonSerializationException {Person person = new Person ("soufiane", "cheouati", "34"); JsonSerializer serializer = novi JsonSerializer (); Niz jsonString = serializer.serialize (osoba); assertEquals ("{\" personAge \ ": \" 34 \ ", \" firstName \ ": \" Soufiane \ ", \" lastName \ ": \" Cheouati \ "}", jsonString); }

4. Zaključak

U ovom smo članku vidjeli kako stvoriti različite vrste prilagođenih bilješki. Zatim smo razgovarali o tome kako ih koristiti za ukrašavanje naših predmeta. Na kraju smo pogledali kako ih obraditi pomoću Java-ovog API-ja za refleksiju.

Kao i uvijek, cjeloviti kôd dostupan je na GitHub-u.