JavaRush /Java блогу /Random-KY /RESTге сереп салуу. 3-бөлүк: Жазгы жүктөөдө RESTful кызма...

RESTге сереп салуу. 3-бөлүк: Жазгы жүктөөдө RESTful кызматын түзүү

Группада жарыяланган
Бул REST талдоосунун акыркы бөлүгү. Мурунку бөлүктөрдө: RESTге сереп салуу.  3-бөлүк: Жазгы жүктөөдө RESTful кызматты түзүү - 1

Долбоорду түзүү

Бул бөлүмдө биз Spring Boot аркылуу кичинекей RESTful тиркемесин түзөбүз. Биздин колдонмо анализдин акыркы бөлүгүндөгү мисалдан кардарларга CRUD (Түзүү, окуу, жаңыртуу, жок кылуу) операцияларын ишке ашырат . Биринчиден, File -> New -> Project менюсу аркылуу жаңы Spring Boot тиркемесин түзөлү ... Ачылган терезеден Spring Initializr тандаңыз жана Project SDK дегенди белгилеңиз: RESTге сереп салуу.  3-бөлүк: Жазгы жүктөөдө RESTful кызматты түзүү - 2Кийинки баскычын басыңыз. Кийинки терезеде, Maven долбоорунун түрүн көрсөтүңүз, Топту жана Артефактты белгилеңиз: RESTге сереп салуу.  3-бөлүк: Жазгы жүктөөдө RESTful кызматты түзүү - 3Кийинки баскычын чыкылдатыңыз. Кийинки терезеде биз долбоорго керектүү Spring Framework компоненттерин тандап алышыбыз керек. Жазгы Желе биз үчүн жетиштүү болот: RESTге сереп салуу.  3-бөлүк: Жазгы жүктөөдө RESTful кызматты түзүү - 4Кийинки баскычын чыкылдатыңыз. Андан кийин, долбоордун атын жана файл тутумунда жайгашкан жерин көрсөтүү гана калды: RESTге сереп салуу.  3-бөлүк: Жазгы жүктөөдө RESTful кызматты түзүү - 5Аяктоо баскычын чыкылдатыңыз. Долбоор түзүлдү, эми анын түзүмүн көрө алабыз: RESTге сереп салуу.  3-бөлүк: Жазгы жүктөөдө RESTful кызматты түзүү - 6IDEA биз үчүн Maven куруу тутумун жайылтуу дескрипторун - pom.xml жана негизги тиркеме классын түздү: RestExampleApplication. Бул жерде алардын codeу:
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);
   }

}

REST функциясын түзүү

Биздин колдонмо кардарларды башкарат. Ошентип, биринчи нерсе, биз кардар субъект түзүү болуп саналат. Бул POJO классы болот. modelПакеттин ичинде пакет түзөлү com.javarush.lectures.rest_example. Пакеттин ичинде modelкласс түзөлү 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;
   }
}
Кызмат кардар боюнча CRUD операцияларын ишке ашырат. Кийинки кадам - ​​бул операцияларды ишке ашыра турган кызматты түзүү. Пакетте com.javarush.lectures.rest_exampleбиз пакет түзөбүз service, анын ичинде интерфейс түзөбүз ClientService. Бул жерде комментарийлер менен интерфейс codeу:
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);
}
Андан кийин биз бул интерфейстин ишке ашыруусун түзүшүбүз керек. Эми ал кардар репозиторийинин ролун аткарат Map<Integer, Client>. Картанын ачкычы кардар идентификатору болот, ал эми маани кардар өзү болот. Бул маалымат базасы менен иштөөнүн өзгөчөлүктөрү менен мисалды ашыкча жүктөбөш үчүн жасалган. Бирок, келечекте биз чыныгы маалымат базасын туташтыруу мүмкүн болгон интерфейстин дагы бир ишке ашырууну жаза алабыз. Пакетте serviceинтерфейстин ишке ашырылышын түзөбүз 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;
   }
}
Аннотация @ServiceЖазга бул класстын кызмат экенин айтат. Бул колдонмонун кээ бир бизнес логикасы ишке ашырылган класстын өзгөчө түрү. Кийинчерээк, бул annotationнын аркасында, Жаз бизге көз карандылык инъекциясынын жардамы менен керектүү жерлерде бул класстын үлгүсүн берет. Эми контроллерди түзүүгө убакыт келди. Биз акыркы чекиттер (URI) үчүн кардар суроо-талаптарын иштетүү логикасын ишке ашырган атайын класс. Түшүнүктүү болушу үчүн, биз бул классты бөлүктөргө бөлөбүз. Биринчиден, класстын өзүн түзүп, ага көз карандылыкты киргизели ClientService:
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }
}
Аннотацияларды тактап көрөлү: @RestController - Жазга бул класс REST контроллери экенин айтат. Ошол. бул класс кардарлардын суроо-талаптарын иштеп чыгуу логикасын ишке ашырат @Autowired - Жазга бул жерге көз карандылыкты киргизүү керек экенин айтат. Биз интерфейсти конструкторго өткөрүп беребиз ClientService. Биз бул кызматтын ишке ашырылышын мурда annotation менен белгилегенбиз @Service, эми Spring бул ишке ашыруунун мисалын контроллер конструкторуна өткөрүп бере алат. Андан кийин, биз CRUD операцияларын иштетүү үчүн ар бир контроллердин ыкмасын этап-этабы менен ишке ашырабыз. Келгиле, түзүү операциясынан баштайлы. Бул үчүн, келгиле, бир ыкма жазалы create:
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
   clientService.create(client);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Келгиле, бул ыкманы карап көрөлү: @PostMapping(value = "/clients")- бул жерде бул ыкма POST суроо-талаптарын /кардарлар дарегине иштетет дегенди билдирет.Метод кайтарып берет ResponseEntity<?>. ResponseEntity- жоопторду кайтаруу үчүн атайын класс. Аны колдонуу менен биз кийинчерээк HTTP статус codeун кардарга кайтара алабыз. Метод параметрди алат @RequestBody Client client, бул параметрдин мааниси сурамдын денесинен алмаштырылат. Бул тууралуу реферат айтылат @RequestBody. Методдун корпусунун ичинде биз мурда түзүлгөн сервисте түзүү ыкмасын чакырабыз жана аны параметрлерде кабыл алынган кардар контроллерине өткөрүп беребиз. ResponseEntityАндан кийин биз жаңы an object түзүү жана ага талап кылынган enum маанисин берүү менен түзүлгөн 201 статусун кайтарабыз HttpStatus. Андан кийин, биз операцияны ишке ашырабыз Read: Биринчиден, биз бардык жеткorктүү кардарлардын тизмесин алуу операциясын ишке ашырабыз:
@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")- баары annotationга окшош @PostMapping, азыр гана биз GET сурамдарын иштетип жатабыз. Бул жолу биз кайтып келебиз ResponseEntity<List<Client>>, бул жолу гана, HTTP статусунан тышкары, кардарлардын тизмеси боло турган жооп органын да кайтарабыз. Жазгы REST контроллерлорунда, бардык POJO an objectтери, ошондой эле жооп органдары катары кайтарылган POJO an objectтеринин коллекциялары, эгерде башкасы ачык көрсөтүлбөсө, автоматтык түрдө JSONге сериялаштырылат. Бул бизге абдан туура келет. Методдун ичинде, биздин кызматты колдонуп, биз бардык кардарлардын тизмесин алабыз. ResponseEntityАндан кийин, тизме нөл же бош эмес болсо, классты колдонуу менен кардарлардын тизмесин жана HTTP статусун 200 OK кайтарабыз . Болбосо, биз жөн гана HTTP статусун кайтарабыз 404 Табылган жок. Андан кийин, биз кардарды анын ID боюнча кабыл алуу мүмкүнчүлүгүн ишке ашырабыз:
@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);
}
Жаңы нерсе, бизде азыр жол өзгөрмөсү бар. URIда аныкталган өзгөрмө. value = "/clients/{id}". Биз аны тармал кашаа менен көрсөттүк. Ал эми методдун параметрлеринде биз аны intannotationны колдонуп өзгөрмө катары кабыл алабыз @PathVariable(name = "id"). Бул ыкма форманын uri сурамдарын кабыл алат /clients/{id}, анын ордуна {id}каалаган сандык маани болушу мүмкүн. Бул маани кийинчерээк өзгөрмөгө int id— метод параметрине өтөт. Денеде биз Clientкызматыбызды колдонуп an objectти алабыз жана кабыл алабыз id. Андан кийин, тизмеге окшоштук боюнча, биз 200 OK статусун жана an objectтин өзүн Client, же жөн эле 404 Табылган эмес статусун кайтарабыз, эгерде idсистемада бул кардар жок болсо. Эки операцияны ишке ашыруу калды - Жаңыртуу жана Өчүрүү. Бул ыкмалардын codeу:
@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);
}
Бул методдордо жаңы эч нерсе жок, андыктан биз кеңири сүрөттөөнү өткөрүп жиберебиз. Айта кетүүчү бир гана нерсе, метод updatePUT сурамдарын (annotation @PutMapping) иштетет, ал эми метод deleteDELETE сурамдарын (annotation DeleteMapping) иштетет. Бул жерде толук контроллер codeу болуп саналат:
@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);
   }
}
Натыйжада, биздин долбоордун структурасы төмөнкүдөй болот: RESTге сереп салуу.  3-бөлүк: Жазгы жүктөөдө RESTful кызматты түзүү - 7

Ишке киргизүү жана сыноо

mainБиздин колдонмону иштетүү үчүн класстагы методду иштетиңиз RestExampleApplication. Жана RESTful веб-кызматтарын сыноо үчүн жаңы программалык камсыздоону жүктөп алышыңыз керек) Чындыгында GET суроо-талаптарын кадимки браузерден жөнөтүү оңой, бирок POST, PUT жана DELETE үчүн кадимки браузер жетишсиз. Кабатыр болбоңуз: сиз каалаган HTTP сурамдарын жөнөтүү үчүн Почтачыны колдоно аласыз. Сиз бул жерден жүктөп алсаңыз болот . Жүктөп алып, орноткондон кийин биз колдонмобузду сынап баштайбыз. Бул үчүн, программаны ачып, жаңы суроо түзүңүз: RESTге сереп салуу.  3-бөлүк: Жазгы жүктөөдө RESTful кызматты түзүү - 9Жогорку сол бурчтагы Жаңы баскычын чыкылдатыңыз. Андан кийин, Суранычты тандаңыз: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 10Кийинки, ага ат берип, сактаңыз. Эми serverге POST суроо-талапты жөнөтүп, биринчи кардарды түзүүгө аракет кылалы: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 11Биз бир нече кардарларды ушундай жол менен түзөбүз. Андан кийин биз сурамдын түрүн GETге өзгөртүп, serverге жөнөтөбүз: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 12

Жалпы жыйынтыктар

Куттуктайбыз: биз REST темасын толук чагылдырдык. Бардык материалдар көлөмдүү болуп чыкты, бирок биз сиз үчүн пайдалуу болот деп үмүттөнөбүз:
  1. Биз REST деген эмне экенин билдик.

  2. Биз RESTтин тарыхы менен тааныштык.

  3. Бул архитектуралык стилдин чектөөлөрү жана принциптери жөнүндө сүйлөштүк:

    • архитектураны кардар-server моделине жеткирүү;
    • шарттын жоктугу;
    • кэштөө;
    • интерфейстин бирдейлиги;
    • катмарлар;
    • талап боюнча code (кошумча чектөө).
  4. Биз REST берген артыкчылыктарды карап чыктык

  5. HTTP протоколун колдонуу менен server менен кардар бири-бири менен кантип иштешерин деталдуу карап чыктык.

  6. Келгиле, суроо-талаптарды жана жоопторду кененирээк карап көрөлү. Алардын тетиктери демонтаждалган.

  7. Акыры, биз практикага өтүп, Spring Boot программасына өзүбүздүн кичинекей RESTful тиркемебизди жаздык. Ал тургай, биз Postman программасын колдонуп, аны кантип сынап көрүүнү үйрөндүк.

Фу. Бул көлөмдүү болуп чыкты, бирок ошентсе да үй тапшырмасы катары жасай турган нерсе бар.

Үй тапшырма

Төмөнкүлөрдү байкап көрүңүз:
  1. Жогорудагы сүрөттөмөдөн кийин, өзүңүздүн Spring Boot долбооруңузду түзүңүз жана анда лекциядагыдай логиканы ишке ашырыңыз. Баарын 1де 1 кайталаңыз.
  2. Аны ишке киргизиңиз. колдонмо.
  3. Почтачыны (же суроо-талаптарды жөнөтүү үчүн башка куралды, атүгүл curl) жүктөп алып, орнотуңуз.
  4. POST жана GET суроо-талаптарын лекцияда айтылгандай эле текшериңиз.
  5. PUT жана DELETE сурамдарын өзүңүз текшериңиз.
1-бөлүк: REST деген эмне 2-бөлүк: кардар менен serverдин ортосундагы байланыш
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION