|
Kierunek
Informatyka |
||||
|
|
||||
|
Instrukcja do ćwiczeń laboratoryjnych nr: |
5 |
Nazwa przedmiotu: |
||
|
Temat Spring Boot |
Tryb studiów: stacjonarny |
|||
|
Czas trwanie ćw. 2x45
min |
||||
|
Autor materiałów: dr Marcin Skuba |
||||
1.
Treści programowe:
Framework Spring
boot, java, web serivce, wstrzykiwanie zależności, postman, http, REST API
2.
Cel zajęć:
Celem zajęć jest opanowanie
podstawowych umiejętność tworzenia aplikacji webowych w środowisku Java Spring
Boot.
3.
Materiały dydaktyczne
REST – (Represential State Transfer) – jest to zestaw
reguł nadający kształt API (nie architektura) określający styl architektury
API – Aplication Programing Interface – interfejs programowania aplikacji.
Jest to zestaw reguł określających komunikację między dwoma systemami
komputerowymi lub między systemem komputerowym a człowiekiem.
REST API – komunikacja najczęściej odbywa się miedzy
aplikacją kliencką a aplikacją serwerową. Aplikacja kliencka może mieć postać
aplikacji webowej, mobilnej i inna.
HTTP
(Hypertext Transfer Protocol) – jest to protokół przeznaczony do komunikacji
między klientem (np. przeglądarką) a serwerem WWW. Służy do przesyłania żądań
udostępnienie klientowi danych z sieci.
- Metody określające rodzaj żądania:

Regułly
architektury REST:
1.
Odseparowanie interfejsu
użytkownika od operacji na serwerze.
Interfejs użytkownika
i operacje na serwerze powinny być wyraźnie oddzielone. W architekturze REST,
klient powinien komunikować się z aplikacją serwerową za pomocą jedynego
wymaganego mechanizmu - REST API. Zapytania klienta muszą zawierać wszystkie
niezbędne informacje do ich przetworzenia po stronie serwera, i odwrotnie -
serwer odpowiada jedynie na zapytania klienta, nie ingerując w interfejs
graficzny czy inne aspekty aplikacji klienta.
2.
Bezstanowość jest kluczowym elementem architektury REST. To
znaczy, że każde zapytanie klienta musi zawierać wszystkie niezbędne
informacje, a serwer nie przechowuje stanu sesji użytkownika po swojej stronie.
W architekturze REST nie istnieją pojęcia takie jak stany użytkownika czy
sesje. Jeśli serwer wymaga uwierzytelnienia, to zapytanie musi zawierać
wszystkie wymagane dane do autentykacji użytkownika, zazwyczaj w postaci tokena
uwierzytelniającego.
3.
W architekturze REST
wykorzystuje się cache, który przyspiesza
odpowiedzi na powtarzające się zapytania. Ważne jest, aby odpowiedzi z REST API
jednoznacznie określały, czy można je cachować, co ma istotne znaczenie dla
aktualności danych. Na przykład, współrzędne geograficzne bieżącej lokalizacji
samolotu nie powinny być przechowywane w cache, ale warto skorzystać z tej
możliwości w przypadku informacji o kolorze czy parametrach technicznych.
4.
Endpointy, czyli adresy zasobów, powinny być klarowne i
precyzyjnie określać, do jakiego zasobu się odnoszą oraz jaką akcję wykonają na
serwerze. Struktura API musi być odseparowana od schematu bazy danych używanej
przez aplikację. Innymi słowy, sposób organizacji tabel w bazie danych nie
powinien wpływać na kształt API.
5.
Separacja warstw oznacza, że konieczne jest rozdzielenie dostępu do
danych, logiki biznesowej oraz prezentacji. Ten sam podział na warstwy powinien
istnieć między aplikacją a dodatkowymi komponentami, takimi jak proxy czy load
balancer. Można również stwierdzić, że aplikacja zgodna z architekturą REST
jest transparentna, co oznacza, że żadna z warstw nie powinna bezpośrednio
oddziaływać na inne warstwy. Implementacja dodatkowych warstw i zewnętrznych
API powinna być ukryta przed użytkownikiem interfejsu programistycznego (API).
6.
Koncepcja umożliwiania
użytkownikom dostępu do skryptów do wykonania jest czasem określana jako
"kod na żądanie". Choć to zasada opcjonalna, często pomijana w
opisach architektury REST.
Contener
IoC i Spring Context – IoC
to podstawowy kontener w Frameworku Spring. W Spring Boot nazywa się Sprong
Context. Kontener pozwala na przechowywanie i zarządzanie obiektami w całym
cyklu życia aplikacji. Obiekty te nazywane są binami. Context Spring możemy
traktować jako magazyn do przechowywania beenów. Beeny to obiekty które
reprezentują wybrane klasy jako pojedyncze instancje, wspólne dla całej
aplikacji.
CDI (Context and Dependency Injection) – jest to mechanizm,
który dostarcza programiście mechanizmy, które automatycznie zarządzają
instancjami klas. Nie ma potrzeby tworzenia klas przy użyciu operatora new.
Takie obiekty są wstrzykiwane do innych klas gdzie jest potrzeba jego użycia.
Opis wybranych adnotacji:
- adnotacje określające rolę klasy
występującej jako pojedyncza instancja zapisana w spring context:
@Service –
Klasa świadczy usługi. Zazwyczaj w tej
klasie zawarta jest logika biznesowa.
@Controler –
Odpowiada za komunikację (między dwoma
serwisami), dedykowany dla warstwy prezentacji.
@RestcControler – Klasa do komunikacji w architekturze
REST, dedykowana dla warstwy prezentacji.
@Repository – Klasa odpowiedzialna za przechowywanie danych
(agregacja danych czyli gromadzenie, wyszukiwanie w celach raportowania,
analizy, prezentacji).
@Component –
Znaczenie ogólne
@Been – Znaczenie ogólne
Adnotacje określające sposób
komunikacji przez protokół http:
@GetMapping – wskazuje metodę w kodzie, która
może być wywołana metodą GET
@PostMapping - wskazuje metodę w kodzie, która może być wywołana
metodą POST
@PutMapping - wskazuje metodę w kodzie, która
może być wywołana metodą PUT
@DeleteMapping
- wskazuje metodę w kodzie, która
może być wywołana metodą DELETE
@PatchMapping
- wskazuje metodę w kodzie, która
może być wywołana metodą PATCH
Adnotacje używane przy przekazywaniu
parametrów z zapytania do funkcji:
@RequestBody
– adnotacja wskazuje, że Spring powinien
deserializować treść żądania do obiektu Java. Obiekt ten jest przekazywany jako
parametr w metodzie obsługi.
@RequestParam – adnotacja pozwala wyodrębnić
parametr zapytania
Wstrzykiwanie zależności (adnotacja @AutoWired), przykłady:
1.
Przez zmienną:

2
Przez konstruktor:

3
Przez seter:

Tworzenie nowego projektu:
Strona www: https://start.spring.io/

---------------------------------------------
Przykład: -----------------------------------------------------
Klasa
Student:
package
com.skuba.SpringBootTest_1;
public
class Student {
private String imie;
private String nazwisko;
private int wiek;
public Student()
{
}
public Student(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko
=
nazwisko;
this.wiek
=
wiek;
}
public String getImie() {
return imie;
}
public void setImie(String imie) {
this.imie = imie;
}
public String getNazwisko() {
return nazwisko;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public int getWiek() {
return wiek;
}
public void setWiek(int wiek) {
this.wiek = wiek;
}
}
Klasa StudentLists:
package com.skuba.SpringBootTest_1;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service public class StudentLists {
private List<Student> students;
StudentLists(){
this.students = new ArrayList<>();
students.add(new Student("Jan", "Kowalski", 33));
students.add(new Student("Piotr", "Nowak", 22));
students.add(new Student("Anna", "Nowakowska", 44));
}
public List<Student> getStudents() {
return students;
}
public boolean addStudent(Student student){
return students.add(student);
}
public void addStudent(String
imie, String nazwisko, int wiek ){
students.add(new Student(imie, nazwisko, wiek));
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
Klasa StudentApi:
package com.skuba.SpringBootTest_1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestControllerpublic class StudentApi {
private StudentLists studentLists;
@Autowired
StudentApi(StudentLists studentLists){
this.studentLists = studentLists;
}
@GetMapping("/hello")
public String sayHello(){
return "Hello";
}
@GetMapping("/hello2")
public String sayHello2(@RequestParam String text){
System.out.println(text);
return text;
}
@GetMapping("/getStudents")
public List<Student> getStudents(){
return studentLists.getStudents();
}
@PostMapping("/addStudent")
public List<Student> addStudent(@RequestBody Student student){
studentLists.addStudent(student);
return studentLists.getStudents();
}
// dodawanie nowego studenta metodą GET np.: http://localhost:8080/addstudent?imie=Jan&nazwisko="Polak"&wiek=99
@GetMapping("/addstudent")
void addStudent(@RequestParam String imie, @RequestParam String nazwisko, @RequestParam int wiek){
studentList.addStudent(imie, nazwisko,
wiek);
}
}
Klasa główna:
package com.skuba.SpringBootTest_1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplicationpublic class SpringBootTest1Application {
public static void main(String[] args) {
SpringApplication.run(SpringBootTest1Application.class, args);
}
} Zapytanie wysłane z przeglądarki internetowej wykorzystującą jedyną metodę GET: Przykładowe dane zwrócone w formacie JSON: Przykład wywołania zapytania zapisującego nowe dane metodą GET z poziomu przeglądarki internetowej lub Postmana: Postman (zapytanie zapisujące nowe dane metodą POST):
Zależność LOMBOK:

@Getter – tworzy getery
@Setter – tworzy setery
@NoArgsConstructor – tworzy konstruktor bezargumentowy
@AllArgsConstructor – tworzy konstruktor z wszystkimi argumentami
Klasa Student napisana z użyciem zależności LONBOK:
package
com.skuba.ZajeciaNTP;
import
lombok.AllArgsConstructor;
import
lombok.Getter;
import
lombok.NoArgsConstructor;
import
lombok.Setter;
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public
class Student {
private String imie;
private String nazwisko;
private int wiek;
}