CodeGym /Java blog /Véletlen /A REST áttekintése. 3. rész: RESTful szolgáltatás kiépíté...
John Squirrels
Szint
San Francisco

A REST áttekintése. 3. rész: RESTful szolgáltatás kiépítése a Spring Booton

Megjelent a csoportban
Ez a REST áttekintésének utolsó része. Az előző részekben a következőkről volt szó: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 1

Projekt létrehozása

Ebben a részben egy kis RESTful alkalmazást fogunk létrehozni a Spring Boot segítségével. Alkalmazásunk CRUD (Create, Read, Update, Delete) műveleteket valósít meg az ügyfeleken az áttekintés előző részében található példából . Kezdésként létrehozunk egy új Spring Boot alkalmazást a menün keresztül: Fájl -> Új -> Projekt... A megnyíló ablakban válassza ki a Spring Initializr-t és adja meg a Project SDK-t: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 2Kattintson a "Next" gombra. A következő ablakban adja meg a "Maven Project" projekttípust, adja meg a "Csoportot" és az "Artifactot": A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 3Kattintson a "Next" gombra. A következő ablakban ki kell választanunk a projekthez szükséges Spring Framework komponenseket. A tavaszi web elég lesz nekünk: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 4Kattintson a "Tovább" gombra. Most már csak meg kell adni a projekt nevét és helyét a fájlrendszerben: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 5Kattintson a "Befejezés" gombra. A projekt elkészült, és most láthatjuk a szerkezetét: az IDEA létrehozta számunkra A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 6a Maven telepítési leírót (pom.xml) és az alkalmazás fő osztályát ( ). RestExampleApplicationÍgy néznek ki:

pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.2.2.RELEASE</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.codegym.lessons/groupId>
   <artifactId>rest_example</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>rest_example</name>
   <description>REST example project</description>

   <properties>
       <java.version>1.8</java.version>
   </properties>

   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
           <exclusions>
               <exclusion>
                   <groupId>org.junit.vintage</groupId>
                   <artifactId>junit-vintage-engine</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
   </dependencies>

   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
   </build>

</project>
RestExampleApplication:

@SpringBootApplication
public class RestExampleApplication {

   public static void main(String[] args) {
       SpringApplication.run(RestExampleApplication.class, args);
   }

}

REST funkció létrehozása

Alkalmazásunk ügyfélkezelési rendszer. Tehát az első dolog, amit tennünk kell, egy ügyfél entitás létrehozása. Ez egy POJO (sima régi Java objektum) osztály lesz. Hozzon létre egy modelcsomagot a com.codegym.lessons.rest_examplecsomagon belül. modelA csomagon belül hozza létre a következőt Customer:

public class Customer {

   private Integer id;
   private String name;
   private String email;
   private String phone;

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

   public String getEmail() {
       return email;
   }

   public void setEmail(String email) {
       this.email = email;
   }

   public String getPhone() {
       return phone;
   }

   public void setPhone(String phone) {
       this.phone = phone;
   }
}
A szolgáltatás CRUD műveleteket hajt végre az ügyfeleken. A következő lépés egy olyan szolgáltatás létrehozása, amely végrehajtja ezeket a műveleteket. A csomagban com.codegym.lessons.rest_examplehozzon létre egy servicecsomagot. És ezen belül hozzon létre egy CustomerServicefelületet. Íme az interfész kód megjegyzésekkel:

public interface CustomerService {

   /**
    * Creates a new customer
    * @param customer - Customer to be created
    */
   void create(Customer customer);

   /**
    * Returns a list of all existing customers
    * @return List of customers
    */
   List<Customer> readAll();

   /**
    * Returns a customer based on its ID
    * @param id - Customer ID
    * @return - Customer object with the given ID
    */
   Customer read(int id);

   /**
    * Updates the customer with the given ID,
    * according to the passed customer
    * @param customer - Customer to use to update the data
    * @param id - ID of the customer you want to update
    * @return - true if the data has been updated, otherwise false
    */
   boolean update(Customer customer, int id);

   /**
    * Deletes the customer with the given ID
    * @param id - ID of the customer to be deleted
    * @return - true if the customer was deleted, otherwise false
    */
   boolean delete(int id);
}
Ezután ezt a felületet kell megvalósítanunk. Most a Map<Integer, Customer>fog tárolni ügyfeleink. A térkép kulcsai az ügyfél-azonosítók, az értékek pedig maguk az ügyfelek lesznek. Ez azért történik, hogy ne terheljük túl ezt a példát egy valódi adatbázissal való munkavégzés sajátosságaival. A jövőben azonban írhatunk majd egy újabb implementációt az interfésznek, amivel valódi adatbázishoz lehet kapcsolódni. A csomagban servicehozza létre a felület megvalósítását CustomerService:

@Service
public class CustomerServiceImpl implements CustomerService {

   // Customer repository
   private static final Map<Integer, Customer> CUSTOMER_REPOSITORY_MAP = new HashMap<>();
  
   // Variable for generating a customer ID
   private static final AtomicInteger CUSTOMER_ID_HOLDER = new AtomicInteger();

   @Override
   public void create(Customer customer) {
       final int customerId = CUSTOMER_ID_HOLDER.incrementAndGet();
       customer.setId(customerId);
       CUSTOMER_REPOSITORY_MAP.put(customerId, customer);
   }

   @Override
   public List<Customer> readAll() {
       return new ArrayList<>(CUSTOMER_REPOSITORY_MAP.values());
   }

   @Override
   public Customer read(int id) {
       return CUSTOMER_REPOSITORY_MAP.get(id);
   }

   @Override
   public boolean update(Customer customer, int id) {
       if (CUSTOMER_REPOSITORY_MAP.containsKey(id)) {
           customer.setId(id);
           CUSTOMER_REPOSITORY_MAP.put(id, customer);
           return true;
       }

       return false;
   }

   @Override
   public boolean delete(int id) {
       return CUSTOMER_REPOSITORY_MAP.remove(id) != null;
   }
}
A @Servicekommentár azt mondja tavasznak, hogy ez az osztály szolgáltatás. Ez egy speciális osztálytípus, amely bizonyos üzleti alkalmazások logikáját valósítja meg. Ezt követően ennek az annotációnak köszönhetően a Spring a függőségi befecskendezés segítségével biztosítja számunkra ennek az osztálynak a példányát minden olyan helyen, ahol szükség van rá. Most itt az ideje egy vezérlő létrehozásának. Ez egy speciális osztály, ahol megvalósítjuk a végpontokhoz (URI) küldött klienskérések feldolgozásának logikáját. Hogy mindezt világosabbá tegyük, ezt az osztályt fokozatosan hozzuk létre. Először hozza létre magát az osztályt, és adjon hozzá egy függőséget a következőhöz CustomerService:

@RestController
public class CustomerController {

   private final CustomerService customerService;

   @Autowired
   public CustomerController(CustomerService customerService) {
       this.customerService = customerService;
   }
}
Magyarázzuk el a megjegyzéseket: @RestController közli a Spring-rel, hogy ez az osztály egy REST vezérlő. Más szavakkal, ez az osztály valósítja meg az ügyfélkérések feldolgozásának logikáját. Az @Autowired azt mondja Springnek, hogy hozzá kell adni egy függőséget. A felületet átadjuk CustomerServicea konstruktornak. Korábban ennek a szolgáltatásnak a megvalósítását jelöltük a megjegyzéssel @Service, most pedig a Spring átadhatja ennek a megvalósításnak egy példányát a vezérlő konstruktorának. Ezután minden egyes vezérlő módszert implementálunk a CRUD műveletek kezelésére. Kezdjük a létrehozási művelettel. Ehhez írunk egy createmetódust:

@PostMapping(value = "/customers")
public ResponseEntity<?> create(@RequestBody Customer customer) {
   customerService.create(customer);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Elemezzük ezt a módszert: ez @PostMapping(value = "/customers")azt jelenti, hogy ez a módszer feldolgozza a „/customers” címre küldött POST kéréseket. A metódus egy ResponseEntity<?>. Az A ResponseEntityegy speciális osztály a válaszok visszaküldésére. Később egy HTTP állapotkód visszaküldésére fogjuk használni az ügyfélnek. A módszernek van @RequestBody Customer customerparamétere. Ennek a paraméternek az értéke a kérés törzséből származik. Az @RequestBodyannotáció ezt jelzi. create()A metódus törzsén belül a korábban létrehozott szolgáltatáson meghívjuk a metódust és átadjuk a paraméterekben kapott ügyfélkontrollernek. Ezután visszaállítjuk a "201 Created" állapotot egy új objektum létrehozásával ResponseEntityés a megfelelő HttpStatusenum mező átadásával. Ezt követően megvalósítjuk areadművelet: Először is végrehajtjuk a műveletet, hogy megkapjuk az összes elérhető ügyfél listáját:

@GetMapping(value = "/customers")
public ResponseEntity<List<Customer>> read() {
   final List<Customer> customers = customerService.readAll();

   return customers != null &&  !customers.isEmpty()
           ? new ResponseEntity<>(customers, HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Merüljünk el: @GetMapping(value = "/customers")— itt minden hasonló a @PostMappingkommentárhoz, de most a GET kéréseket dolgozzuk fel. Ezúttal egy ResponseEntity<List<Customer>>, és a HTTP-státusz mellett egy választörzset is adunk vissza, ami az ügyfelek listája lesz. A Spring REST vezérlőiben minden POJO-objektum és POJO-objektum-gyűjtemény, amelyek választörzsekként kerülnek visszaadásra, és automatikusan JSON-ba sorakoznak, hacsak nincs másként megadva. Ez nekünk tökéletesen megfelel. A módszeren belül szolgáltatásunkat arra használjuk, hogy minden ügyfélről listát kapjunk. Ezután, ha a lista nem nulla és nem üres, akkor aResponseEntityosztályt, hogy visszaadja az ügyfelek listáját és a "200 OK" HTTP állapotkódot. Ellenkező esetben egyszerűen a „404 Not Found” HTTP-állapotkódot adjuk vissza. Most megvalósítjuk azt a képességet, hogy ügyfelet szerezzünk meg az azonosítójával:

@GetMapping(value = "/customers/{id}")
public ResponseEntity<Customer> read(@PathVariable(name = "id") int id) {
   final Customer customer = customerService.read(id);

   return customer != null
           ? new ResponseEntity<>(customer, HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Egy új dolog itt az útvonalváltozó. A változó az URI-ban van definiálva: value = "/customers/{id}". Göndör zárójelben jelezzük. És megkapjuk metódusparaméterként intaz @PathVariable(name = "id")annotáció segítségével. Ez a metódus elfogadja az URI-kra küldött kéréseket a következő formában /customers/{id}: , ahol {id}bármilyen számértéket jelöl. Ezt az értéket a változón keresztül továbbítják int ida metódus paraméteréhez. A testben Customerszolgáltatásunk segítségével megkapjuk a tárgyat és a kapott id. Ezután a listával analóg módon vagy a "200 OK" állapotot és magát az objektumot, vagy egyszerűen a "404 Nem található" állapotot adjuk vissza, Customerha a rendszernek nincs ilyen ügyfele id. Még mindig két műveletet kell végrehajtanunk: frissítést és törlést. Íme a kód ezekhez a módszerekhez:

@PutMapping(value = "/customers/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Customer customer) {
   final boolean updated = customerService.update(customer, id);

   return updated
           ? new ResponseEntity<>(HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}

@DeleteMapping(value = "/customers/{id}")
public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
   final boolean deleted = customerService.delete(id);

   return deleted
           ? new ResponseEntity<>(HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
Ezekben a módszerekben nincs lényegében újdonság, ezért a részletes leírást kihagyjuk. Csak annyit érdemes megemlíteni, hogy a update()metódus kezeli a PUT kéréseket ( @PutMappingannotation), a delete()metódus pedig a DELETE kéréseket ( DeleteMappingannotation). Itt van a vezérlő teljes kódja:

@RestController
public class CustomerController {

   private final CustomerService customerService;

   @Autowired
   public CustomerController(CustomerService customerService) {
       this.customerService = customerService;
   }

   @PostMapping(value = "/customers")
   public ResponseEntity<?> create(@RequestBody Customer customer) {
       customerService.create(customer);
       return new ResponseEntity<>(HttpStatus.CREATED);
   }

   @GetMapping(value = "/customers")
   public ResponseEntity<List<Customer>> read() {
       final List<Customer> customers = customerService.readAll();

       return customers != null &&  !customers.isEmpty()
               ? new ResponseEntity<>(customers, HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_FOUND);
   }

   @GetMapping(value = "/customers/{id}")
   public ResponseEntity<Customer> read(@PathVariable(name = "id") int id) {
       final Customer customer = customerService.read(id);

       return customer != null
               ? new ResponseEntity<>(customer, HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_FOUND);
   }

   @PutMapping(value = "/customers/{id}")
   public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Customer customer) {
       final boolean updated = customerService.update(customer, id);

       return updated
               ? new ResponseEntity<>(HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
   }

   @DeleteMapping(value = "/customers/{id}")
   public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
       final boolean deleted = customerService.delete(id);

       return deleted
               ? new ResponseEntity<>(HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
   }
}
Ennek eredményeként projektünk felépítése a következő: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 7

Indítás és tesztelés

Alkalmazásunk elindításához csak futtassa a main()metódust az osztályban RestExampleApplication. A RESTful webszolgáltatások teszteléséhez azonban további szoftvereket kell letöltenünk. A helyzet az, hogy a GET kéréseket meglehetősen egyszerű elküldeni egy közönséges böngészőből, de egy közönséges böngésző nem tud POST, PUT és DELETE kéréseket küldeni. Ne aggódjon: a Postman nevű programmal bármilyen HTTP-kérést küldhet. Itt tudod letölteni . A Postman letöltése és telepítése után megkezdjük az alkalmazás tesztelését. Ehhez nyissa meg a programot, és hozzon létre egy új kérést: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 9Kattintson az "Új" gombra a bal felső sarokban. Ezután válassza a „Kérés” lehetőséget: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 10Ezután adjon nevet, és mentse el. Most próbáljunk meg POST kérést küldeni a szervernek, és létrehozzuk az első ügyfelet: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 11Több ügyfelet is létrehozunk így. Ezután módosítjuk a kérés típusát GET-re, és elküldjük a kérést a szervernek: A REST áttekintése.  3. rész: RESTful szolgáltatás kiépítése a Spring Boot-on – 12

Összegzés

Gratulálunk! Eléggé lefedtük a REST-et. Nagy mennyiségű anyag volt, de remélhetőleg hasznos volt az Ön számára:
  1. Megtanultuk, mi az a REST.

  2. Megtudtuk, hogyan jött létre a REST.

  3. Beszéltünk ennek az építészeti stílusnak a korlátairól és alapelveiről:

    • kliens-szerver architektúra
    • hontalan
    • gyorsítótárazás
    • egységes felület
    • rétegek
    • igény szerinti kód (opcionális)
  4. Feltérképeztük a REST által nyújtott előnyöket

  5. Részletesen megvizsgáltuk, hogy a szerver és a kliens hogyan kommunikál egymással a HTTP protokollon keresztül.

  6. Alaposabban megvizsgáltuk a kéréseket és válaszokat. Felbontottuk azok alkotórészeit.

  7. Végül gyakorlati tapasztalatokat szerezhettünk saját kis RESTful alkalmazásunk megírásával a Spring Boot segítségével. És még azt is megtanultuk, hogyan teszteljük a Postman segítségével.

Fú. Ez sok volt, de még mindig van mit csinálni házi feladatként.

Házi feladat

Próbáld ki a következőket:
  1. A fenti leírást követve hozza létre saját Spring Boot projektjét, és hajtsa végre ugyanazt a logikát, mint a leckében. Ismételj meg mindent pontosan.
  2. Indítsa el az alkalmazást.
  3. Töltse le és konfigurálja a Postmant (vagy bármely más kérések küldésére szolgáló eszközt, például curl).
  4. Tesztelje a POST és GET kéréseket a leckében leírt módon.
  5. Tesztelje saját maga a PUT és DELETE kéréseket.
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION