CodeGym /Blog Java /rawak /Gambaran keseluruhan REST. Bahagian 3: Membina perkhidmat...
John Squirrels
Tahap
San Francisco

Gambaran keseluruhan REST. Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot

Diterbitkan dalam kumpulan
Ini adalah bahagian akhir gambaran keseluruhan kami tentang REST. Dalam bahagian sebelumnya, kami membincangkan: Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 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 di bahagian gambaran keseluruhan sebelumnya . Untuk memulakan, kami akan mencipta aplikasi Spring Boot baharu melalui menu: Fail -> Baharu -> Projek... Dalam tetingkap yang terbuka, pilih Spring Initializr dan tentukan SDK Projek: Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 2Klik butang "Seterusnya". Dalam tetingkap seterusnya, tentukan "Projek Maven" sebagai jenis projek, tentukan "Kumpulan" dan "Artifak": Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 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: Membina perkhidmatan RESTful pada Spring Boot - 4Klik butang "Seterusnya". Sekarang yang tinggal hanyalah untuk menunjukkan nama projek dan lokasinya dalam sistem fail: Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 5Klik butang "Selesai". Projek ini dicipta dan kini kita boleh melihat strukturnya: Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 6IDEA menghasilkan deskriptor penggunaan Maven (pom.xml) dan kelas utama aplikasi ( RestExampleApplication) untuk kita. Inilah rupa 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.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);
   }

}

Mencipta fungsi REST

Aplikasi kami ialah sistem pengurusan pelanggan. Jadi, perkara pertama yang perlu kita lakukan ialah mencipta entiti pelanggan. Ia akan menjadi kelas POJO (objek Java lama biasa). Buat modelpakej di dalam com.codegym.lessons.rest_examplepakej. Di dalam modelpakej, buat 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;
   }
}
Perkhidmatan ini akan melaksanakan operasi CRUD ke atas pelanggan. Langkah seterusnya ialah mencipta perkhidmatan yang akan melaksanakan operasi ini. Dalam com.codegym.lessons.rest_examplepakej, buat servicepakej. Dan di dalamnya, buat CustomerServiceantara muka. Berikut ialah kod antara muka dengan ulasan:

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);
}
Seterusnya, kita perlu melaksanakan antara muka ini. Kini Map<Integer, Customer>akan menyimpan pelanggan kami. Kunci peta ialah ID pelanggan dan nilainya ialah pelanggan itu sendiri. Ini dilakukan supaya tidak membebankan contoh ini dengan spesifik bekerja dengan pangkalan data sebenar. Walau bagaimanapun, pada masa hadapan kami akan dapat menulis satu lagi pelaksanaan antara muka, yang akan memungkinkan untuk menyambung ke pangkalan data sebenar. Dalam servicepakej, buat pelaksanaan antara CustomerServicemuka:

@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;
   }
}
Anotasi @Servicememberitahu musim bunga bahawa kelas ini ialah perkhidmatan. Ini ialah jenis kelas khas yang melaksanakan beberapa logik aplikasi perniagaan. Selepas itu, terima kasih kepada anotasi ini, Spring akan menggunakan suntikan kebergantungan untuk memberikan kami contoh kelas ini di semua tempat di mana ia diperlukan. Kini tiba masanya untuk mencipta pengawal. Ini ialah kelas khas di mana kami akan melaksanakan logik untuk memproses permintaan pelanggan yang dihantar ke titik akhir (URI). Untuk membuat semua ini lebih jelas, kami akan mencipta kelas ini secara berperingkat. Pertama, buat kelas itu sendiri dan tambahkan pergantungan pada CustomerService:

@RestController
public class CustomerController {

   private final CustomerService customerService;

   @Autowired
   public CustomerController(CustomerService customerService) {
       this.customerService = customerService;
   }
}
Mari jelaskan anotasi: @RestController memberitahu Spring bahawa kelas ini ialah pengawal REST. Dengan kata lain, kelas ini melaksanakan logik untuk memproses permintaan pelanggan. @Autowired memberitahu Spring bahawa kebergantungan perlu ditambah di sini. Kami menghantar CustomerServiceantara muka kepada pembina. Terdahulu, kami menandakan pelaksanaan perkhidmatan ini dengan @Serviceanotasi, dan kini Spring akan dapat menghantar contoh pelaksanaan ini kepada pembina pengawal. Seterusnya, kami akan melaksanakan setiap kaedah pengawal untuk mengendalikan operasi CRUD. Mari kita mulakan dengan operasi cipta. Untuk melakukan ini, kami menulis createkaedah:

@PostMapping(value = "/customers")
public ResponseEntity<?> create(@RequestBody Customer customer) {
   customerService.create(customer);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Mari analisa kaedah ini: @PostMapping(value = "/customers")bermakna kaedah ini memproses permintaan POST yang dihantar ke alamat "/pelanggan". Kaedah mengembalikan a ResponseEntity<?>. A ResponseEntityialah kelas khas untuk membalas respons. Kemudian, kami akan menggunakannya untuk mengembalikan kod status HTTP kepada pelanggan. Kaedah ini mempunyai @RequestBody Customer customerparameter. Nilai parameter ini datang daripada badan permintaan. Anotasi @RequestBodymenunjukkan ini. Di dalam badan kaedah, kami memanggil create()kaedah pada perkhidmatan yang dibuat sebelum ini dan menyampaikannya kepada pengawal pelanggan yang diterima dalam parameter. Kemudian kami mengembalikan status "201 Created" dengan mencipta ResponseEntityobjek baharu dan menghantar HttpStatusmedan enum yang sepadan kepadanya. Seterusnya, kami akan melaksanakanreadoperasi: Pertama, kami akan melaksanakan operasi untuk mendapatkan senarai semua pelanggan yang tersedia:

@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);
}
Mari kita selami: @GetMapping(value = "/customers")— semuanya di sini serupa dengan @PostMappinganotasi, tetapi kini kami sedang memproses permintaan GET. Kali ini kami mengembalikan ResponseEntity<List<Customer>>, dan sebagai tambahan kepada status HTTP, kami juga akan mengembalikan badan respons, yang akan menjadi senarai pelanggan. Dalam pengawal REST Spring, semuanya ialah objek POJO dan koleksi objek POJO, yang dikembalikan sebagai badan tindak balas dan disiri secara automatik ke dalam JSON, melainkan dinyatakan sebaliknya. Ini sangat sesuai dengan kita. Di dalam kaedah, kami menggunakan perkhidmatan kami untuk mendapatkan senarai semua pelanggan. Seterusnya, jika senarai itu tidak batal dan tidak kosong, maka kami menggunakanResponseEntitykelas untuk mengembalikan senarai pelanggan dan kod status HTTP "200 OK". Jika tidak, kami hanya mengembalikan kod status HTTP "404 Not Found". Kini kami akan melaksanakan keupayaan untuk mendapatkan pelanggan menggunakan IDnya:

@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);
}
Satu perkara baharu di sini ialah pembolehubah laluan. Pembolehubah ditakrifkan dalam URI: value = "/customers/{id}". Kami menunjukkannya dalam pendakap kerinting. Dan kami menerimanya sebagai intparameter kaedah menggunakan @PathVariable(name = "id")anotasi. Kaedah ini akan menerima permintaan yang dihantar kepada URI dalam bentuk /customers/{id}, yang {id}mewakili sebarang nilai berangka. Nilai ini kemudiannya dihantar melalui int idpembolehubah kepada parameter kaedah. Di dalam badan, kami mendapat Customerobjek menggunakan perkhidmatan kami dan yang diterima id. Dan kemudian, dengan analogi dengan senarai, kami mengembalikan sama ada status "200 OK" dan Customerobjek itu sendiri, atau hanya status "404 Tidak Ditemui" jika sistem tidak mempunyai pelanggan dengan itu id. Kami masih perlu melaksanakan dua operasi: kemas kini dan padam. Berikut ialah kod untuk kaedah ini:

@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);
}
Tiada apa-apa yang baru dalam kaedah ini, jadi kami akan melangkau penerangan terperinci. Satu-satunya perkara yang patut disebut ialah update()kaedah mengendalikan permintaan PUT ( @PutMappinganotasi), dan delete()kaedah mengendalikan permintaan DELETE ( DeleteMappinganotasi). Berikut ialah kod penuh untuk pengawal:

@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);
   }
}
Hasilnya, struktur projek kami adalah seperti berikut: Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 7

Pelancaran dan ujian

Untuk memulakan aplikasi kami, jalankan sahaja main()kaedah dalam RestExampleApplicationkelas. Tetapi untuk menguji perkhidmatan web RESTful, kami perlu memuat turun perisian tambahan. Hakikatnya ialah permintaan GET agak mudah untuk dihantar daripada pelayar biasa, tetapi pelayar biasa tidak boleh menghantar permintaan POST, PUT dan DELETE. Jangan risau: anda boleh menggunakan program yang dipanggil Postman untuk menghantar sebarang permintaan HTTP. Anda boleh memuat turunnya di sini . Selepas memuat turun dan memasang Posman, kami mula menguji aplikasi kami. Untuk melakukan ini, buka program dan buat permintaan baharu: Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 9Klik butang "Baharu" di penjuru kiri sebelah atas. Seterusnya, pilih "Permintaan": Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 10Seterusnya, beri nama dan simpannya. Sekarang mari cuba hantar permintaan POST ke pelayan dan buat pelanggan pertama: Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 11Kami mencipta beberapa pelanggan dengan cara ini. Kemudian kami menukar jenis permintaan kepada GET dan menghantar permintaan ke pelayan: Gambaran keseluruhan REST.  Bahagian 3: Membina perkhidmatan RESTful pada Spring Boot - 12

Ringkasan

tahniah! Kami telah melindungi REST secukupnya. Terdapat sejumlah besar bahan, tetapi semoga ia berguna untuk anda:
  1. Kami belajar apa itu REST.

  2. Kami belajar tentang cara REST wujud.

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

    • seni bina pelayan-pelanggan
    • tidak bernegara
    • caching
    • antara muka seragam
    • lapisan
    • kod atas permintaan (pilihan)
  4. Kami meneroka faedah yang disediakan oleh REST

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

  6. Kami melihat lebih dekat pada permintaan dan respons. Kami membedah bahagian konstituen mereka.

  7. Akhirnya, kami mendapat pengalaman praktikal dengan menulis aplikasi RESTful kecil kami sendiri menggunakan Spring Boot. Dan kami juga belajar cara mengujinya menggunakan Posmen.

Fuh. Itu banyak, tetapi masih ada sesuatu untuk anda lakukan sebagai kerja rumah.

Kerja rumah

Cuba yang berikut:
  1. Mengikuti penerangan di atas, cipta projek Spring Boot anda sendiri dan laksanakan logik yang sama seperti dalam pelajaran. Ulang semua betul-betul.
  2. Lancarkan aplikasi.
  3. Muat turun dan konfigurasikan Posman (atau sebarang alat lain untuk menghantar permintaan, contohnya, curl).
  4. Uji permintaan POST dan GET dengan cara yang sama yang diterangkan dalam pelajaran.
  5. Uji PUT dan DELETE permintaan sendiri.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION