Commit 6b786cce by Patryk Czarnik

Obsługa XML w serwisie RestSpring

parent 535824e8
......@@ -36,6 +36,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
</dependencies>
<build>
......
......@@ -2,6 +2,8 @@ package sklep.model;
import java.io.Serializable;
import jakarta.persistence.*;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigDecimal;
......@@ -12,12 +14,14 @@ import java.math.BigDecimal;
@Entity
@Table(name="products")
@NamedQuery(name="Product.findAll", query="SELECT p FROM Product p")
@XmlRootElement
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="product_id", insertable=false, updatable=false)
@XmlAttribute(name="id")
private Integer productId;
private String description;
......
@XmlAccessorType(XmlAccessType.FIELD)
package sklep.model;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAccessType;
......@@ -27,22 +27,21 @@ public class ProductEndpoint {
this.productRepository = productRepository;
}
@GetMapping
@GetMapping(produces={"application/json", "application/xml"})
public List<Product> getAllProducts() {
return productRepository.findAll();
}
@GetMapping("/{id}")
@GetMapping(path="/{id}", produces={"application/json", "application/xml"})
public Product getOneProduct(@PathVariable("id") Integer id) {
return productRepository
.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
}
// Ta metoda pokazana tylko po to, aby wytłumaczyć, że struktura adresów powinna odpowiadać logicznej strukturze danych.
// W prawdziwej aplikacji raczej nie dochodzi się do poziomu pojedynczych pól. Teoretycznie można.
@GetMapping(path="/{id}/price", produces="text/plain")
@GetMapping(path="/{id}/price", produces="application/json")
public BigDecimal getPrice(@PathVariable Integer id) {
return getOneProduct(id).getPrice();
}
......@@ -79,7 +78,8 @@ public class ProductEndpoint {
* konwencja, że aby dodać nowy rekord do katalogu, wysyła się POST z danymi
* tego rekordu pod ogólny adres całego katalogu.
*/
@PostMapping
@PostMapping(produces={"application/json", "application/xml"},
consumes={"application/json", "application/xml"})
public Product insert(@RequestBody Product product) {
/* Operacja save (a wewnętrznie persist z Hibernate) spowoduje ustawienie nowego ID w obiekcie.
* Warto taką informację przekazać klientowi. Można:
......
package sklep.rest;
import java.math.BigDecimal;
import java.util.List;
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.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.RestController;
import org.springframework.web.server.ResponseStatusException;
import sklep.model.Product;
import sklep.repository.ProductRepository;
@RestController
@RequestMapping("/products.json")
public class ProductEndpointJson {
private ProductRepository productRepository;
public ProductEndpointJson(ProductRepository productRepository) {
this.productRepository = productRepository;
}
@GetMapping
public List<Product> getAllProducts() {
return productRepository.findAll();
}
@GetMapping("/{id}")
public Product getOneProduct(@PathVariable("id") Integer id) {
return productRepository
.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
}
@GetMapping(path="/{id}/price", produces="text/plain")
public BigDecimal getPrice(@PathVariable Integer id) {
return getOneProduct(id).getPrice();
}
@PutMapping("/{id}/price")
public void setPrice(@PathVariable Integer id, @RequestBody BigDecimal newPrice) {
Product product = productRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
product.setPrice(newPrice);
productRepository.save(product);
}
@PostMapping
public Product insert(@RequestBody Product 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).
*/
productRepository.save(product);
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);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment