JavaRush /Blog Java /Random-MS /Gambaran keseluruhan REST. Bahagian 3: Mencipta Perkhidma...

Gambaran keseluruhan REST. Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring

Diterbitkan dalam kumpulan
Ini adalah bahagian akhir penghuraian REST. Dalam bahagian sebelumnya: Gambaran keseluruhan REST.  Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring - 1

Mencipta Projek

Dalam bahagian ini, kami akan mencipta aplikasi RESTful kecil menggunakan Spring Boot. Aplikasi kami akan melaksanakan operasi CRUD (Buat, Baca, Kemas Kini, Padam) pada pelanggan daripada contoh dari bahagian terakhir analisis. Mula-mula, mari buat aplikasi Spring Boot baharu melalui menu File -> New -> Project... Dalam tetingkap yang terbuka, pilih Spring Initializr dan tentukan Project SDK: Gambaran keseluruhan REST.  Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring - 2Klik butang Next. Dalam tetingkap seterusnya, tentukan jenis projek Maven, tentukan Kumpulan dan Artifak: Gambaran keseluruhan REST.  Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring - 3Klik butang Seterusnya. Dalam tetingkap seterusnya, kita perlu memilih komponen Rangka Kerja Spring yang diperlukan untuk projek itu. Spring Web akan mencukupi untuk kami: Gambaran keseluruhan REST.  Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring - 4Klik butang Seterusnya. Seterusnya, yang tinggal hanyalah untuk menentukan nama projek dan lokasinya dalam sistem fail: Gambaran keseluruhan REST.  Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring - 5Klik butang Selesai. Projek telah dibuat, kini kita dapat melihat strukturnya: Gambaran keseluruhan REST.  Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring - 6IDEA telah menghasilkan untuk kita deskriptor penggunaan sistem bina Maven - pom.xml dan kelas aplikasi utama: RestExampleApplication. Inilah kod mereka:
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.javarush.lectures</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);
   }

}

Mencipta fungsi REST

Aplikasi kami menguruskan pelanggan. Jadi perkara pertama yang perlu kita lakukan ialah mencipta entiti pelanggan. Ini akan menjadi kelas POJO. Mari buat pakej modeldi dalam pakej com.javarush.lectures.rest_example. modelMari buat kelas di dalam pakej Client:
public class Client {

   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;
   }
}
Perkhidmatan ini akan melaksanakan operasi CRUD pada pelanggan. Langkah seterusnya ialah mencipta perkhidmatan yang akan melaksanakan operasi ini. Dalam pakej com.javarush.lectures.rest_examplekami akan mencipta pakej service, di dalamnya kami akan mencipta antara muka ClientService. Berikut ialah kod antara muka dengan ulasan:
public interface ClientService {

   /**
    * Создает нового клиента
    * @param client - клиент для создания
    */
   void create(Client client);

   /**
    * returns список всех имеющихся клиентов
    * @return список клиентов
    */
   List<client> readAll();

   /**
    * returns клиента по его ID
    * @param id - ID клиента
    * @return - an object клиента с заданным ID
    */
   Client read(int id);

   /**
    * Обновляет клиента с заданным ID,
    * в соответствии с переданным клиентом
    * @param client - клиент в соответсвии с которым нужно обновить данные
    * @param id - id клиента которого нужно обновить
    * @return - true если данные были обновлены, иначе false
    */
   boolean update(Client client, int id);

   /**
    * Удаляет клиента с заданным ID
    * @param id - id клиента, которого нужно удалить
    * @return - true если клиент был удален, иначе false
    */
   boolean delete(int id);
}
Seterusnya kita perlu membuat pelaksanaan antara muka ini. Sekarang ia akan bertindak sebagai repositori klien Map<Integer, Client>. Kunci kad ialah id pelanggan, dan nilainya ialah pelanggan itu sendiri. Ini dilakukan untuk tidak membebankan contoh dengan spesifik bekerja dengan pangkalan data. Walau bagaimanapun, pada masa hadapan kami akan dapat menulis satu lagi pelaksanaan antara muka di mana ia akan menjadi mungkin untuk menyambung pangkalan data sebenar. Dalam pakej servicekami akan membuat pelaksanaan antara muka ClientService:
@Service
public class ClientServiceImpl implements ClientService {

   // Хранorще клиентов
   private static final Map<Integer, Client> CLIENT_REPOSITORY_MAP = new HashMap<>();

   // Переменная для генерации ID клиента
   private static final AtomicInteger CLIENT_ID_HOLDER = new AtomicInteger();

   @Override
   public void create(Client client) {
       final int clientId = CLIENT_ID_HOLDER.incrementAndGet();
       client.setId(clientId);
       CLIENT_REPOSITORY_MAP.put(clientId, client);
   }

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

   @Override
   public Client read(int id) {
       return CLIENT_REPOSITORY_MAP.get(id);
   }

   @Override
   public boolean update(Client client, int id) {
       if (CLIENT_REPOSITORY_MAP.containsKey(id)) {
           client.setId(id);
           CLIENT_REPOSITORY_MAP.put(id, client);
           return true;
       }

       return false;
   }

   @Override
   public boolean delete(int id) {
       return CLIENT_REPOSITORY_MAP.remove(id) != null;
   }
}
Anotasi @Servicememberitahu Spring bahawa kelas ini ialah perkhidmatan. Ini ialah jenis kelas khas di mana beberapa logik perniagaan aplikasi dilaksanakan. Selepas itu, terima kasih kepada anotasi ini, Spring akan memberikan kami contoh kelas ini di tempat yang diperlukan menggunakan Suntikan Ketergantungan. Kini tiba masanya untuk mencipta pengawal. Kelas khas di mana kami melaksanakan logik untuk memproses permintaan pelanggan untuk titik akhir (URI). Untuk menjadikannya lebih jelas, kami akan membuat kelas ini dalam bahagian. Mula-mula, mari kita cipta kelas itu sendiri dan perkenalkan pergantungan padanya ClientService:
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }
}
Mari kita jelaskan anotasi: @RestController - memberitahu Spring bahawa kelas ini ialah pengawal REST. Itu. kelas ini akan melaksanakan logik untuk memproses permintaan pelanggan @Autowired - memberitahu Spring bahawa kebergantungan perlu disuntik di tempat ini. Kami menghantar antara muka kepada pembina ClientService. Kami menandakan pelaksanaan perkhidmatan ini dengan anotasi @Servicelebih awal, dan kini Spring akan dapat menghantar contoh pelaksanaan ini kepada pembina pengawal. Seterusnya, kami akan langkah demi langkah melaksanakan setiap kaedah pengawal untuk memproses operasi CRUD. Mari kita mulakan dengan operasi Cipta. Untuk melakukan ini, mari tulis kaedah create:
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
   clientService.create(client);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Mari lihat kaedah ini: @PostMapping(value = "/clients")- di sini kami maksudkan bahawa kaedah ini memproses permintaan POST ke alamat /clients. Kaedah mengembalikan ResponseEntity<?>. ResponseEntity- kelas khas untuk membalas respons. Menggunakannya, kami kemudian boleh mengembalikan kod status HTTP kepada pelanggan. Kaedah mengambil parameter @RequestBody Client client, nilai parameter ini digantikan daripada badan permintaan. Abstrak bercakap tentang ini @RequestBody. Di dalam badan kaedah, kami memanggil kaedah cipta pada perkhidmatan yang dibuat sebelum ini dan menyampaikannya kepada pengawal klien yang diterima dalam parameter. Kemudian kami mengembalikan status 201 Created dengan mencipta objek baharu ResponseEntitydan memberikan nilai enum yang diperlukan kepadanya HttpStatus. Seterusnya, kami melaksanakan operasi Read: Pertama, kami melaksanakan operasi mendapatkan senarai semua pelanggan yang tersedia:
@GetMapping(value = "/clients")
public ResponseEntity<List<Client>> read() {
   final List<Client> clients = clientService.readAll();

   return clients != null &&  !clients.isEmpty()
           ? new ResponseEntity<>(clients, HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Mari mulakan analisis: @GetMapping(value = "/clients")- semuanya serupa dengan anotasi @PostMapping, hanya sekarang kami memproses permintaan GET. Kali ini kami kembali ResponseEntity<List<Client>>, hanya kali ini, sebagai tambahan kepada status HTTP, kami juga akan mengembalikan badan respons, yang akan menjadi senarai pelanggan. Dalam pengawal Spring REST, semua objek POJO, serta koleksi objek POJO yang dikembalikan sebagai badan tindak balas, disiri secara automatik kepada JSON melainkan dinyatakan sebaliknya secara eksplisit. Kami cukup gembira dengan ini. Di dalam kaedah, menggunakan perkhidmatan kami, kami mendapat senarai semua pelanggan. Seterusnya, jika senarai itu tidak batal atau kosong, kami mengembalikan ResponseEntitysenarai pelanggan dan status HTTP 200 OK menggunakan kelas. Jika tidak, kami hanya mengembalikan status HTTP 404 Not Found. Seterusnya, kami akan melaksanakan keupayaan untuk mendapatkan pelanggan dengan idnya:
@GetMapping(value = "/clients/{id}")
public ResponseEntity<Client> read(@PathVariable(name = "id") int id) {
   final Client client = clientService.read(id);

   return client != null
           ? new ResponseEntity<>(client, HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Sesuatu yang baharu ialah kita kini mempunyai pembolehubah laluan. Pembolehubah yang ditakrifkan dalam URI. value = "/clients/{id}". Kami menunjukkannya dalam pendakap kerinting. Dan dalam parameter kaedah kami menerimanya sebagai intpembolehubah menggunakan anotasi @PathVariable(name = "id"). Kaedah ini akan menerima permintaan untuk uri dalam bentuk /clients/{id}, yang sebaliknya {id}boleh terdapat sebarang nilai berangka. Nilai ini kemudiannya dihantar kepada pembolehubah int id—parameter kaedah. Dalam badan kita menerima objek Clientmenggunakan perkhidmatan kami dan diterima id. Dan kemudian, dengan analogi dengan senarai, kami mengembalikan sama ada status 200 OK dan objek itu sendiri Client, atau hanya status 404 Not Found, jika tiada idklien dengan ini dalam sistem. Ia kekal untuk melaksanakan dua operasi - Kemas Kini dan Padam. Berikut ialah kod untuk kaedah ini:
@PutMapping(value = "/clients/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Client client) {
   final boolean updated = clientService.update(client, id);

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

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

   return deleted
           ? new ResponseEntity<>(HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
Tiada apa-apa yang baru dalam kaedah ini, jadi kami akan melangkau penerangan terperinci. Satu-satunya perkara yang patut disebut ialah kaedah updatememproses permintaan PUT (anotasi @PutMapping), dan kaedah deletememproses permintaan DELETE (anotasi DeleteMapping). Berikut ialah kod pengawal lengkap:
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }

   @PostMapping(value = "/clients")
   public ResponseEntity<?> create(@RequestBody Client client) {
       clientService.create(client);
       return new ResponseEntity<>(HttpStatus.CREATED);
   }

   @GetMapping(value = "/clients")
   public ResponseEntity<List<Client>> read() {
       final List<client> clients = clientService.readAll();

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

   @GetMapping(value = "/clients/{id}")
   public ResponseEntity<Client> read(@PathVariable(name = "id") int id) {
       final Client client = clientService.read(id);

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

   @PutMapping(value = "/clients/{id}")
   public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Client client) {
       final boolean updated = clientService.update(client, id);

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

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

       return deleted
               ? new ResponseEntity<>(HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
   }
}
Akibatnya, struktur projek kami kelihatan seperti ini: Gambaran keseluruhan REST.  Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring - 7

Pelancaran dan ujian

Untuk menjalankan aplikasi kami, jalankan sahaja kaedah maindalam kelas RestExampleApplication. Dan untuk menguji perkhidmatan web RESTful, anda perlu memuat turun perisian baharu) Hakikatnya permintaan GET agak mudah dihantar dari penyemak imbas biasa, tetapi untuk POST, PUT dan DELETE pelayar biasa tidak mencukupi. Jangan risau: anda boleh menggunakan Posman untuk menghantar sebarang permintaan HTTP. Anda boleh memuat turunnya dari sini . Selepas memuat turun dan memasang, kami mula menguji aplikasi kami. Untuk melakukan ini, buka program dan buat permintaan baharu: Gambaran keseluruhan REST.  Bahagian 3: Mencipta Perkhidmatan RESTful dalam But Spring - 9Klik butang Baharu di penjuru kiri sebelah atas. Seterusnya, pilih Permintaan: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 10Seterusnya, beri nama dan simpannya. Mari cuba hantar permintaan POST ke pelayan dan buat klien pertama: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 11Kami mencipta beberapa pelanggan dengan cara ini. Kemudian kami menukar jenis permintaan kepada GET dan menghantarnya ke pelayan: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 12

Keputusan umum

Tahniah: kami telah membincangkan topik REST. Semua bahan ternyata besar, tetapi kami berharap ia berguna untuk anda:
  1. Kami belajar apa itu REST.

  2. Kami berkenalan dengan sejarah REHAT.

  3. Kami bercakap tentang batasan dan prinsip gaya seni bina ini:

    • membawa seni bina kepada model pelayan-pelanggan;
    • kekurangan keadaan;
    • caching;
    • keseragaman antara muka;
    • lapisan;
    • kod atas permintaan (sekatan pilihan).
  4. Kami meneliti kelebihan yang disediakan oleh REST

  5. Kami meneliti secara terperinci bagaimana pelayan dan klien berinteraksi antara satu sama lain menggunakan protokol HTTP.

  6. Mari kita lihat lebih dekat pada permintaan dan respons. Komponen mereka telah dibongkar.

  7. Akhirnya, kami terus berlatih dan menulis aplikasi RESTful kecil kami sendiri dalam Spring Boot. Dan kami juga belajar bagaimana untuk mengujinya menggunakan program Posmen.

Fuh. Ia ternyata banyak, tetapi masih ada sesuatu yang perlu dilakukan sebagai kerja rumah.

Kerja rumah

Cuba yang berikut:
  1. Mengikuti penerangan di atas, cipta projek Spring Boot anda sendiri dan laksanakan logik yang sama di dalamnya seperti dalam kuliah. Ulang semua 1 dalam 1.
  2. Lancarkannya. permohonan.
  3. Muat turun dan sediakan Postman (atau sebarang alat lain untuk menghantar permintaan, malah curl).
  4. Uji permintaan POST dan GET dengan cara yang sama seperti yang diterangkan dalam kuliah.
  5. Uji PUT dan DELETE permintaan sendiri.
Bahagian 1: Apakah itu REST Bahagian 2: Komunikasi antara pelanggan dan pelayan
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION