Commit 08f17d86 by Patryk Czarnik

RProducts w wersji JSON

parent df121cb2
...@@ -45,6 +45,15 @@ public class PhotoUtil { ...@@ -45,6 +45,15 @@ public class PhotoUtil {
} }
} }
public static void writeBytes(int productId, byte[] bytes) {
try {
Path path = getPath(productId);
Files.write(path, bytes);
} catch (Exception e) {
e.printStackTrace();
}
}
private static Path getPath(int productId) throws DBException { private static Path getPath(int productId) throws DBException {
String dir = DBSettings.load().getProperty("photo_dir"); String dir = DBSettings.load().getProperty("photo_dir");
String fileName = productId + EXT; String fileName = productId + EXT;
......
...@@ -78,6 +78,6 @@ public class Sklep { ...@@ -78,6 +78,6 @@ public class Sklep {
} }
public void savePhoto(@WebParam(name="id") int productId, @WebParam(name="bytes") byte[] bytes) throws DBException { public void savePhoto(@WebParam(name="id") int productId, @WebParam(name="bytes") byte[] bytes) throws DBException {
PhotoUtil.writeStream(productId, new ByteArrayInputStream(bytes)); PhotoUtil.writeBytes(productId, bytes);
} }
} }
...@@ -45,6 +45,14 @@ public class PhotoUtil { ...@@ -45,6 +45,14 @@ public class PhotoUtil {
} }
} }
public static void writeBytes(int productId, byte[] bytes) {
try {
Path path = getPath(productId);
Files.write(path, bytes);
} catch (Exception e) {
e.printStackTrace();
}
}
private static Path getPath(int productId) throws DBException { private static Path getPath(int productId) throws DBException {
String dir = DBSettings.load().getProperty("photo_dir"); String dir = DBSettings.load().getProperty("photo_dir");
String fileName = productId + EXT; String fileName = productId + EXT;
......
package sklep.rest;
import java.math.BigDecimal;
import java.util.List;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import sklep.db.DBConnection;
import sklep.db.DBException;
import sklep.db.ProductDAO;
import sklep.db.RecordNotFound;
import sklep.model.Product;
import sklep.photo.PhotoUtil;
@Path("/products")
public class RProduct {
@GET
@Produces("application/json")
public List<Product> readAllProducts() throws DBException {
try(DBConnection db = DBConnection.open()) {
ProductDAO productDAO = db.productDAO();
return productDAO.readAll();
}
}
@GET
@Path("/{id}")
@Produces("application/json")
public Product readOneProduct(@PathParam("id") int productId) throws DBException, RecordNotFound {
try(DBConnection db = DBConnection.open()) {
ProductDAO productDAO = db.productDAO();
return productDAO.findById(productId);
}
}
// W praktyce REST metoda POST jest używana do dodawania nowych rekordów do katalogu.
// Może być także używana w innych celach - gdy klient ma "przysłać dane na serwer", a serwer coś z tym zrobi (podobnie jak to było w SOAP). @POST
// POST w tym miejscu jest lepszy niż PUT, bo zapisując nowy rekord, nie wiemy z góry jakie będzie będzie jego ID,
// czyli nie wiemy, pod adresem zapisze się nowy produkt.
// POST potrafi "dodać rekord do katalogu".
@POST
public void saveProduct(Product product) throws DBException {
try(DBConnection db = DBConnection.open()) {
ProductDAO productDAO = db.productDAO();
productDAO.save(product);
db.commit();
}
}
// Nie praktykuje się tego zbyt często, ale można zdefiniować dedykowane metody dające dostęp
// do poszczególnych pól obiektu (aby nie transferować całego rekordu, gdy potrzebna tylko jedna informacja)
@GET
@Path("/{id}/price")
@Produces("application/json")
public BigDecimal getPrice(@PathParam("id") int productId) throws DBException, RecordNotFound {
return readOneProduct(productId).getPrice();
}
// Operacja HTTP PUT zapisuje zasób pod podanym adresem.
// W zapytaniach typu PUT i POST klient wysyła dane na serwer (treść zapytania: "body" / "entity" / "content" ...)
// W JAX-RS metoda może posiadać tylko jeden parametr bez adnotacji i to właśnie przez ten parametr przekazywana jest treść zapytania
// (te dane, które przysłał klient). Format tych danych opisuje adnotacja @Consumes
@PUT
@Path("/{id}/price")
@Consumes({"application/json", "text/plain"})
public void setPrice(@PathParam("id") int productId, BigDecimal newPrice) throws DBException, RecordNotFound {
try(DBConnection db = DBConnection.open()) {
ProductDAO productDAO = db.productDAO();
Product product = productDAO.findById(productId);
product.setPrice(newPrice);
productDAO.save(product);
db.commit();
}
}
// PUT vs POST
// PUT powinniśmy używać wtedy, gdy z góry wiadomo, pod jakim adresem zostaną zapisane dane.
// W praktyce PUT używa się najczęściej do aktualizacji istniejących danych, ale teoretycznie PUT
// można też użyć do zapisania nowych danych pod konkretnym adresem.
// Gdy wyślemy dane za pomocą PUT pod adres, to następnie GET z tego samego adresu powinien odczytać dane, które wysłał PUT (być może w innym formacie).
// POST używajmy wtedy, gdy nie wiemy z góry pod jakim adresem dane zostaną zapisane, np. gdy id rekordu jest generowane z sekwencji.
// Taka metoda powinna dać w odpowiedzi informację o ID utworzonego rekordu.
// Kilka możliwości:
// 1) odesłanie uzupełnionego rekordu - trochę niewydajne, ale wygodne
// 2) minimalny dokumencik JSON, w którego wnętrzu jest zawarta ta informacja (tak robi wiele usług w praktyce, np. PayU)
// 3) (teraz w tej wersji) - odesłać odpowiedź typu Created z nagłówkiem Location - najlepsze z punktu widzenia standardów/dobrych praktyk
// Aby zwracać taie "techniczne" odpowiedzi, używa się klasy Response.
@DELETE
@Path("/{id}")
public void usun(@PathParam("id") int productId) throws DBException, RecordNotFound {
try(DBConnection db = DBConnection.open()) {
ProductDAO productDAO = db.productDAO();
productDAO.delete(productId);
db.commit();
}
}
@GET
@Path("/{id}/photo")
// przykładowo /api/products/3/photo
@Produces("image/jpeg")
public byte[] getPhoto(@PathParam("id") int productId) throws DBException, RecordNotFound {
return PhotoUtil.readBytes(productId);
}
// @PUT
// @Path("/{id}/photo")
// @Consumes("image/jpeg")
// public void writePhoto(@PathParam("id") int productId, byte[] bajty) {
// PhotoUtil.writeBytes(productId, bajty);
// }
}
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