Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
2
20230403
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Patryk Czarnik
20230403
Commits
c38317d2
Commit
c38317d2
authored
May 26, 2023
by
Patryk Czarnik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Kolejne metody w ProductController
parent
5e733702
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
110 additions
and
1 deletions
+110
-1
ProductController.java
...estSpring/src/main/java/sklep/rest/ProductController.java
+110
-1
No files found.
PC36-RestSpring/src/main/java/sklep/rest/ProductController.java
View file @
c38317d2
package
sklep
.
rest
;
package
sklep
.
rest
;
import
java.math.BigDecimal
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Optional
;
import
org.springframework.dao.EmptyResultDataAccessException
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.web.bind.annotation.DeleteMapping
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.PutMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.server.ResponseStatusException
;
import
sklep.model.Product
;
import
sklep.model.Product
;
import
sklep.repository.ProductRepository
;
import
sklep.repository.ProductRepository
;
/* RestController to jest taki Controller, który nie używa szablonów, tylko wyniki metod odsyła w treści odpowiedzi do klienta.
* Inaczej mówiąc działa tak, jakby każda metoda miała @ResponseBody.
*
* Najczęściej na poziomie klasy umieszcza się też @RequestMapping z ogólnym adresem, pod którym działa cała ta klasa.
* Metody wewnątrz mogą mieć podany "dalszy ciąg adresu".
*/
@RestController
@RestController
@RequestMapping
(
"/products"
)
@RequestMapping
(
"/products"
)
public
class
ProductController
{
public
class
ProductController
{
...
@@ -26,6 +43,98 @@ public class ProductController {
...
@@ -26,6 +43,98 @@ public class ProductController {
@GetMapping
(
"/{id}"
)
@GetMapping
(
"/{id}"
)
public
Product
readOne
(
@PathVariable
int
id
)
{
public
Product
readOne
(
@PathVariable
int
id
)
{
return
productRepository
.
findById
(
id
).
get
();
return
productRepository
.
findById
(
id
).
orElseThrow
(()
->
new
ResponseStatusException
(
HttpStatus
.
NOT_FOUND
));
}
// Przykład metody, która "wchodzi w szczegóły rekordu".
// To nie jest częsta praktyka, ale pokazuję to dla lepszego zrozumienia idei REST - adresy URL odpowiadają logicznej strukturze danych.
@GetMapping
(
"/{id}/price"
)
public
BigDecimal
getPrice
(
@PathVariable
Integer
id
)
{
Optional
<
Product
>
product
=
productRepository
.
findById
(
id
);
if
(
product
.
isPresent
())
{
return
product
.
get
().
getPrice
();
}
else
{
throw
new
ResponseStatusException
(
HttpStatus
.
NOT_FOUND
);
}
}
/*
* Operacja PUT służy do zapisania danych POD PODANYM ADRESEM.
* Na przykład PUT products/2/price z wartością 100 powinno ustawić w produkcie nr 2 cenę 100.
* Jeśli PUT zadziała, to następnie GET wysłany pod ten sam adres powinien odczytać te same dane,
* które PUT zapisał (być może w innym formacie - to inny temat)
*
* PUT najczęściej jest używany do aktualizacji istniejących danych
* (pojedynczych wartości albo całych rekordów), ale może być też użyty do
* zapisania nowych danych. To, co najważniejsze, to fakt, że PUT zapisuje dane
* pod konkretnym adresem, do którego jest wysyłany.
*
* Aby odczytać dane, które przysłał klient, metoda ma jeden parametr oznaczony @RequestBody.
* To do tego parametru Spring przekaże dane odczytane z "body" zapytania.
*/
@PutMapping
(
"/{id}/price"
)
public
void
setPrice
(
@PathVariable
Integer
id
,
@RequestBody
BigDecimal
newPrice
)
{
Optional
<
Product
>
product
=
productRepository
.
findById
(
id
);
if
(
product
.
isPresent
())
{
Product
realProduct
=
product
.
get
();
realProduct
.
setPrice
(
newPrice
);
productRepository
.
save
(
realProduct
);
}
else
{
throw
new
ResponseStatusException
(
HttpStatus
.
NOT_FOUND
);
}
}
/*
* PUT może również służyć do zapisania całego rekordu, ale zwn, że musi być
* skierowany pod ten adres, pod którym rekord zostanie faktycznie zapisany, w
* praktyce PUT jest uzywany do aktualizacji rekordów (UPDATE).
*
* Aby w aplikacji Springowej, w której jest włączone security, działały zapytania POST i PUT,
* trzeba wyłączyć zabezpieczenie "CSRF":
* .and().csrf().disable()
*/
@PutMapping
(
"/{id}"
)
public
void
update
(
@PathVariable
(
"id"
)
Integer
productId
,
@RequestBody
Product
product
)
{
// Aby mieć pewność, że zapisujemu produkt o typ ID, wpisuję productId z URL-a.
// Ewentualnie możnaby jeszcze sprawdzić czy rekord istnieje, czy ID się zgadza
// i jeśli coś jest nie tak, to wyrzucić wyjątek.
product
.
setProductId
(
productId
);
productRepository
.
save
(
product
);
}
/*
* POST jest najbardziej ogólną metodą HTTP; oznacza, że klient
* "wysyła jakieś dane na serwer", a serwer odsyła jakąś odpowiedź.
* W zasadzie POST może służyć do wszystkiego.
*
* W praktyce POST bardzo często służy do dodawania nowych rekordów, ponieważ
* gdy tworzymy nowy rekord, to nie znamy z góry jego ID i nie wiemy pod jakim
* URL-em zostanie zapisany (nie da się więc użyć PUT). Stąd wzięła REST-owa
* konwencja, że aby dodać nowy rekord do katalogu, wysyła się POST z danymi
* tego rekordu pod ogólny adres całego katalogu.
*/
@PostMapping
public
Product
insert
(
@RequestBody
Product
product
)
{
// Aby mieć pewność, że zapytanie tworzy nowy rekord, ustawiam productId na null.
product
.
setProductId
(
null
);
productRepository
.
save
(
product
);
/* Operacja save (a wewnętrznie persist z Hibernate) spowoduje ustawienie nowego ID w obiekcie.
* Warto taką informację przekazać klientowi. Można:
* 1) odesłać uzupełniony rekord (i tak zrobimy tutaj),
* 2) odesłać "małego JSON-a" z informacją o tym ID
* (i innymi informacjami, które serwer chce przekazać klientowi)
* 3) tylko nagłówek Location z URL-em nowego rekordu (to zobaczymy w wersji JAX-RS).
*/
return
product
;
}
@DeleteMapping
(
"/{id}"
)
public
void
delete
(
@PathVariable
(
"id"
)
Integer
productId
)
{
try
{
productRepository
.
deleteById
(
productId
);
}
catch
(
EmptyResultDataAccessException
e
)
{
throw
new
ResponseStatusException
(
HttpStatus
.
NOT_FOUND
,
"Brak produktu nr "
+
productId
);
}
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment