Egyszerű e-kereskedelmi megvalósítás tavasszal

1. E-kereskedelmi alkalmazásunk áttekintése

Ebben az oktatóanyagban egy egyszerű e-kereskedelmi alkalmazást valósítunk meg. Kidolgozunk egy API-t a Spring Boot és egy ügyfélalkalmazás segítségével, amely az API-t az Angular használatával fogyasztja.

Alapvetően a felhasználó képes lesz termékeket felvenni / eltávolítani a terméklistából a bevásárlókosárba / kosárba, és megrendelni.

2. Háttér rész

Az API fejlesztéséhez a Spring Boot legújabb verzióját fogjuk használni. JPA és H2 adatbázist is használunk a dolgok kitartó oldalára.

Ha többet szeretne megtudni a Spring Bootról,megnézheti a Spring Boot cikksorozatunkat és ha szeretné Ha meg szeretné ismerni a REST API felépítését, kérjük, nézzen meg egy másik sorozatot.

2.1. Maven-függőségek

Készítsük elő a projektünket, és importáljuk a szükséges függőségeket a sajátunkba pom.xml.

Szükségünk lesz néhány alapvető Spring Boot függőségre:

 org.springframework.boot spring-boot-starter-data-jpa 2.2.2.RELEASE org.springframework.boot spring-boot-starter-web 2.2.2.RELEASE 

Ezután a H2 adatbázis:

 com.h2database h2 1.4.197 futásidejű 

És végül - a Jackson könyvtár:

 com.fasterxml.jackson.datatype jackson-datatype-jsr310 2.9.6 

A Spring Initializr segítségével gyorsan beállítottuk a projektet a szükséges függőségekkel.

2.2. Az adatbázis beállítása

Bár a memóriában lévő H2 adatbázist már a dobozból is használhatnánk a Spring Boot alkalmazással, mégis elvégezünk néhány beállítást, mielőtt elkezdjük fejleszteni az API-t.

Jól engedélyezze a H2 konzolt miénkben alkalmazás.tulajdonságok fájl így valóban ellenőrizhetjük adatbázisunk állapotát, és megnézhetjük, hogy minden úgy megy-e, ahogy vártuk.

Hasznos lehet SQL lekérdezések naplózása a konzolra a fejlesztés során:

spring.datasource.name = ecommercedb spring.jpa.show-sql = true # H2 beállítások spring.h2.console.enabled = true spring.h2.console.path = / h2-console

E beállítások hozzáadása után az adatbázishoz a következő címen férhetünk hozzá: // localhost: 8080 / h2-console felhasználásával jdbc: h2: mem: ecommercedb mint JDBC URL és felhasználó sa jelszó nélkül.

2.3. A projekt felépítése

A projekt több szabványos csomagba fog szerveződni, az Angular alkalmazás pedig a frontend mappába kerül:

├───pom.xml ├───src ├────main │ ├──── frontend │ ├────java │ │ └────com │ │ └ ─ ─ ─ ─ ─ kereskedelem EcommerceApplication.java │ │ ├─── vezérlő │ └───források │ │ alkalmazás.tulajdonságok │ ├───statikus │ └─── Templates └───test └───java va───com └───baeldung └───ommerce EcommerceApplicationIntegrationTest. Jáva

Meg kell jegyeznünk, hogy az adattárcsomag összes felülete egyszerű és kiterjeszti a Spring Data CrudRepository-ját, ezért ezeket itt nem jelenítjük meg.

2.4. Kivételek kezelése

Szükségünk lesz egy API-ra egy kivételkezelőre, hogy megfelelően kezeljük az esetleges kivételeket.

A témáról további részleteket a REST hibakezelése rugóval és az egyedi hibaüzenetek kezelése a REST API cikkekben talál..

Itt továbbra is a figyelem középpontjában állunk ConstraintViolationException és szokásunk ResourceNotFoundException:

@RestControllerAdvice public class ApiExceptionHandler {@SuppressWarnings ("rawtypes") @ExceptionHandler (ConstraintViolationException.class) public ResponseEntity handle (ConstraintViolationException e) {ErrorResponse errors = new ErrorResponse (); for (ConstraintViolation megsértése: e.getConstraintViolations ()) {ErrorItem hiba = új ErrorItem (); error.setCode (fault.getMessageTemplate ()); error.setMessage (sértés.getMessage ()); hibák.addError (hiba); } return new ResponseEntity (hibák, HttpStatus.BAD_REQUEST); } @SuppressWarnings ("rawtypes") @ExceptionHandler (ResourceNotFoundException.class) public ResponseEntity fogantyú (ResourceNotFoundException e) {ErrorItem hiba = új ErrorItem (); error.setMessage (e.getMessage ()); return new ResponseEntity (hiba, HttpStatus.NOT_FOUND); }}

2.5. Termékek

Ha több ismeretre van szüksége a tavaszi kitartásról, rengeteg hasznos cikk található a Spring Persistence sorozatban.

Alkalmazásunk támogatni fogja csak az adatbázisból származó termékek olvasása, ezért először hozzá kell adnunk néhányat.

Hozzunk létre egy egyszerű Termék osztály:

@Entity public class Product {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; @NotNull (message = "A termék neve kötelező.") @Basic (választható = hamis) privát karakterlánc neve; magán Dupla ár; privát karakterlánc pictureUrl; // az összes argumentum szerzője // szokásos getterek és beállítók}

Bár a felhasználónak nem lesz lehetősége termékeket hozzáadni az alkalmazáson keresztül, támogatni fogjuk egy termék mentését az adatbázisba a terméklista előretöltése érdekében.

Egy egyszerű szolgáltatás elegendő lesz az igényeinkhez:

@Service @Transactional public class ProductServiceImpl implementálja a ProductService {// productRepository konstruktor injekciót @Orride public Iterable getAllProducts () {return productRepository.findAll (); } @Orride public Product getProduct (long id) {return productRepository .findById (id) .orElseThrow (() -> new ResourceNotFoundException ("A termék nem található")); } @Orride public Product save (Product product) {return productRepository.save (product); }}

Egy egyszerű vezérlő kezeli a terméklista lekérésére vonatkozó kéréseket:

@RestController @RequestMapping ("/ api / products") public class ProductController {// productService constructor injection @GetMapping (value = {"", "/"}) public @NotNull Iterable getProducts () {return productService.getAllProducts (); }}

Most csak arra van szükségünk, hogy a terméklistát a felhasználó elé tegyük - az, hogy néhány terméket ténylegesen feltegyünk az adatbázisba. Ezért felhasználjuk CommandLineRunner osztály, hogy a Bab fő alkalmazási osztályunkban.

Így az alkalmazás indításakor termékeket illesztünk be az adatbázisba:

@Bean CommandLineRunner futó (ProductService productService) {return args -> {productService.save (...); // további termékek}

Ha most elindítjuk az alkalmazást, akkor a terméklistát a (z) oldalon keresztül tudjuk letölteni // localhost: 8080 / api / products. Továbbá, ha elmegyünk // localhost: 8080 / h2-console és jelentkezzen be, meglátjuk, hogy van egy megnevezett tábla TERMÉK az imént hozzáadott termékekkel.

2.6. Rendelések

Az API oldalon engedélyeznünk kell a POST kéréseket a végfelhasználó által végrehajtott megrendelések mentéséhez.

Először hozzuk létre a modellt:

@Entity @Table (name = "megrendelések") public class Rendelés {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; @JsonFormat (pattern = "dd / MM / yyyy") private LocalDate dateCreated; privát húr státusz; @JsonManagedReference @OneToMany (mappedBy = "pk.order") @Valid private List orderProducts = new ArrayList (); @Transient public Double getTotalOrderPrice () {double summa = 0D; List orderProducts = getOrderProducts (); for (OrderProduct op: orderProducts) {összeg + = op.getTotalPrice (); } visszatérési összeg; } @Transient public int getNumberOfProducts () {return this.orderProducts.size (); } // szokásos mérőeszközök és beállítók}

Itt néhány dolgot meg kell jegyeznünk. Természetesen az egyik figyelemre méltó dolog az ne felejtse el megváltoztatni a táblázat alapértelmezett nevét. Mivel neveztük az osztályt Rendelés, alapértelmezés szerint a megnevezett tábla RENDELÉS létre kell hozni. De mivel ez egy fenntartott SQL szó, hozzátettük @Táblázat (név = „megrendelések”) elkerülni a konfliktusokat.

Továbbá kettőnk van @ Átmeneti módszerek, amelyek a rendelés teljes összegét és a benne lévő termékek számát adják vissza. Mindkettő kiszámított adatot képvisel, ezért nincs szükség az adatbázisban történő tárolásra.

Végül van egy @Egy a sokhoz a megrendelés részleteit képviselő reláció. Ehhez szükségünk van egy másik entitásosztályra:

@Entity public class OrderProduct {@EmbeddedId @JsonIgnore private OrderProductPK pk; @ Oszlop (nullable = false) privát egész szám; // alapértelmezett konstruktor public OrderProduct (rendelési rendelés, terméktermék, egész szám) {pk = new OrderProductPK (); pk.setOrder (rendelés); pk.setProduct (termék); ez.mennyiség = mennyiség; } @Transient public Product getProduct () {return this.pk.getProduct (); } @Transient public Double getTotalPrice () {return getProduct (). GetPrice () * getQuantity (); } // szokásos getterek és beállítók // hashcode () és egyenlő () módszerek}

Van egy összetett elsődleges kulcsunkitt:

A @Embeddable public class OrderProductPK végrehajtja a Serializable {@JsonBackReference @ManyToOne (opcionális = false, fetch = FetchType.LAZY) @JoinColumn (name = "order_id") privát rendelési rendelést; @ManyToOne (opcionális = false, fetch = FetchType.LAZY) @JoinColumn (name = "product_id") magántermék; // szokásos getterek és beállítók // hashcode () és egyenlő () módszerek}

Ezek az órák nem túl bonyolultak, de ezt meg kell jegyeznünk a OrderProduct osztályba tesszük @JsonIgnore az elsődleges kulcson. Ez azért van, mert nem akarunk sorosítani Rendelés az elsődleges kulcs része, mivel felesleges lenne.

Csak nekünk kell Termék hogy megjelenjen a felhasználó számára, tehát ezért van tranziens getProduct () módszer.

A következőkre egy egyszerű szolgáltatás-megvalósításra van szükségünk:

@Service @Transactional public class A OrderServiceImpl végrehajtja a OrderService {// orderRepository konstruktor injekciót @Orride public Iterable getAllOrders () {return this.orderRepository.findAll (); } @Orride public order create (Order order) {order.setDateCreated (LocalDate.now ()); return this.orderRepository.save (rendelés); } @Orride public void update (Order order) {this.orderRepository.save (order); }}

És egy vezérlő feltérképezve / api / megrendelések kezelni Rendelés kéréseket.

A legfontosabb az teremt() módszer:

@PostMapping public ResponseEntity create (@RequestBody OrderForm űrlap) {List formDtos = form.getProductOrders (); validateProductsExistence (formDtos); // rendelési logika létrehozása // a rendelés feltöltése a order.setOrderProducts (orderProducts) termékekkel; this.orderService.update (rendelés); Karakterlánc uri = ServletUriComponentsBuilder .fromCurrentServletMapping () .path ("/ megrendelések / {id}") .buildAndExpand (order.getId ()) .toString (); HttpHeaders fejlécek = new HttpHeaders (); fejlécek.add ("Hely", uri); return new ResponseEntity (rendelés, fejlécek, HttpStatus.CREATED); }

Először is, elfogadjuk a termékek listáját a megfelelő mennyiségekkel. Utána, ellenőrizzük, hogy létezik-e minden termék az adatbázisban és majd hozzon létre és mentse el az új megrendelést. Tartunk egy hivatkozást az újonnan létrehozott objektumra, hogy rendelés részleteit hozzá tudjuk adni hozzá.

Végül, létrehozunk egy „Hely” fejlécet.

A részletes megvalósítás a tárban található - a linket a cikk végén említjük.

3. Frontend

Most, hogy felépítettük a Spring Boot alkalmazást, ideje lépni a projekt szögletes része. Ehhez először a Node.js-t kell telepítenünk az NPM-mel, majd ezt követően egy Angular parancssori felületet, egy parancssori felületet az Angular számára.

Nagyon könnyű telepíteni mindkettőt, amint azt a hivatalos dokumentációban láthattuk.

3.1. A szögletes projekt beállítása

Mint említettük, használni fogjuk Szögletes CLI alkalmazásunk létrehozásához. Annak érdekében, hogy a dolgok egyszerűek legyenek, és mindez egy helyen legyen, az Angular alkalmazást bent tartjuk / src / main / frontend mappába.

A létrehozásához meg kell nyitnunk egy terminált (vagy parancssort) a / src / main mappát, és futtassa:

új kezelőfelület

Ezzel létrehozza az Angular alkalmazáshoz szükséges összes fájlt és mappát. A fájlban pakage.json, ellenőrizhetjük, hogy függőségeink mely verziói vannak telepítve. Ez az oktatóanyag az Angular v6.0.3 alapú, de a régebbi verzióknak kell elvégezniük a feladatot, legalább a 4.3-as és újabb verzióknak (HttpClient hogy itt használjuk, a szögletes 4.3-ban vezettük be.

Meg kell jegyeznünk az összes parancsunkat lefuttatjuk a / frontend mappába hacsak másként nem mondják.

Ez a beállítás elegendő az Angular alkalmazás futtatásával történő elindításához tálalás parancs. Alapértelmezés szerint fut // localhost: 4200 és ha most oda megyünk, látni fogjuk, hogy az alapszögletű alkalmazás betöltődik.

3.2. Bootstrap hozzáadása

Mielőtt folytatnánk a saját komponenseink létrehozását, először tegyük hozzá Bootstrap projektünkhöz, hogy szépen kinézhessük az oldalainkat.

Csak néhány dologra van szükségünk ennek eléréséhez. Először is meg kellfuttasson egy parancsot a telepítéséhez:

npm install --save bootstrap

és aztán mondani Angularnak, hogy valóban használja. Ehhez meg kell nyitnunk egy fájlt src / main / frontend / angular.json és add hozzá node_modules / bootstrap / dist / css / bootstrap.min.css alatt „Stílusok” ingatlan. És ez az.

3.3. Komponensek és modellek

Mielőtt elkezdenénk létrehozni az alkalmazásunk összetevőit, először nézzük meg, hogy fog kinézni alkalmazásunk:

Most létrehozunk egy alapösszetevőt, amelynek neve e-kereskedelem:

n g g e-kereskedelem

Ez létrehozza a komponensünket a / frontend / src / app mappába. Töltsük be az alkalmazás indításakortartalmazzaba,-be app.component.html:

Ezután létrehozunk további összetevőket ezen az alapkomponensen belül:

ng g c / e-kereskedelem / termékek ng g c / e-kereskedelem / megrendelések ng g c / e-kereskedelem / shopping-cart

Természetesen készíthettük volna ezeket a mappákat és fájlokat manuálisan, ha úgy tetszik, de ebben az esetben szükségünk lenne rá ne felejtse el regisztrálni ezeket az összetevőket a AppModule.

Szükségünk lesz néhány modellre az adataink egyszerű kezeléséhez:

export osztály Termék {id: szám; név: karakterlánc; ár: szám; pictureUrl: karakterlánc; // minden argumentum konstruktor}
exportosztály ProductOrder {termék: Termék; mennyiség: szám; // minden argumentum konstruktor}
exportosztály ProductOrders {productOrders: ProductOrder [] = []; }

Az utoljára említett modell megfelel a miénknek Megrendelőlap a háttérlapon.

3.4. Alapkomponens

A tetején e-kereskedelem komponensként egy jobb oldali Kezdőlap linket helyezünk el:

 Baeldung e-kereskedelem 
  • Főoldal (aktuális)

Más alkatrészeket is innen töltünk be:

Nem szabad megfeledkeznünk arról, hogy a komponensek tartalmát lássuk, mivel a navbar osztályban hozzá kell adnunk néhány CSS-t a app.component.css:

.container {padding-top: 65px; }

Nézzük meg a .ts fájl, mielőtt kommentálnánk a legfontosabb részeket:

@Component ({selector: 'app-ecommerce', templateUrl: './ecommerce.component.html', styleUrls: ['./ecommerce.component.css']}}) export osztály EcommerceComponent valósítja meg az OnInit {private collapsed = true; orderFinished = hamis; @ViewChild ('productsC') productsC: ProductsComponent; @ViewChild ('shoppingCartC') shoppingCartC: ShoppingCartComponent; @ViewChild ('megrendelésekC') megrendelésekC: RendelésekKomponens; toggleCollapsed (): void {this.collapsed =! this.collapsed; } finishOrder (orderFinished: logikai érték) {this.orderFinished = orderFinished; } reset () {this.orderFinished = hamis; this.productsC.reset (); this.shoppingCartC.reset (); ez.rendelésekC.fizetett = hamis; }}

Mint láthatjuk, a gombra kattintva itthon link visszaállítja a gyermek alkatrészeit. Hozzá kell férnünk a metódusokhoz és a mezőhöz a szülő gyermekkomponensein belül, ezért tartjuk meg a gyermekekre vonatkozó hivatkozásokat, és használjuk a Visszaállítás() módszer.

3.5. A szolgáltatás

Annak érdekében, hogy testvérek komponensei egymással való kommunikációhozés adatokat kérni / küldeni az API-ból / az API-ból, létre kell hoznunk egy szolgáltatást:

@Injectable () export osztály EcommerceService {private productsUrl = "/ api / products"; magánrendelésekUrl = "/ api / megrendelések"; privát productRendelés: ProductOrder; magánrendelések: ProductOrders = új ProductOrders (); private productOrderSubject = new Subject (); magánrendelésekSubject = new Subject (); private totalSubject = new Subject (); privát összesen: szám; ProductOrderChanged = this.productOrderSubject.asObservable (); OrdersChanged = this.ordersSubject.asObservable (); TotalChanged = this.totalSubject.asObservable (); konstruktor (privát http: HttpClient) {} getAllProducts () {return this.http.get (this.productsUrl); } saveOrder (rendelés: ProductOrders) {adja vissza ezt.http.post (this.ordersUrl, order); } // megosztott mezők lekérdezői és beállítói}

Viszonylag egyszerű dolgok vannak itt, amint észrevehettük. GET és POST kéréseket küldünk az API-val való kommunikációra. Emellett megfigyelhetővé tesszük azokat az adatokat, amelyeket meg kell osztanunk az összetevők között, hogy később feliratkozhassunk rá.

Mindazonáltal meg kell említenünk egy dolgot az API-val folytatott kommunikációval kapcsolatban. Ha most futtatnánk az alkalmazást, 404-et kapnánk, és nem kapnánk le adatokat. Ennek az az oka, hogy mivel relatív URL-eket használunk, az Angular alapértelmezés szerint megpróbál hívást kezdeményezni // localhost: 4200 / api / products és a háttéralkalmazásunk fut helyi gazda: 8080.

Kódolhatnánk az URL-eket helyi gazda: 8080természetesen, de ezt nem akarjuk megtenni. Helyette, amikor különböző tartományokkal dolgozunk, létre kell hoznunk egy nevű fájlt proxy-conf.json miénkben / frontend mappába:

{"/ api": {"target": "// localhost: 8080", "biztonságos": hamis}}

És akkor nekünk kell nyisd ki csomag.json és változtass szkriptek.kezdeni ingatlan illeszkedik:

"szkriptek": {... "start": "ng serve --proxy-config proxy-conf.json", ...}

És most csak kellene ne feledje, hogy elindítja az alkalmazást npm kezdés helyette tálalás.

3.6. Termékek

Miénkben TermékekKomponens, beadjuk a korábban elkészített szolgáltatást, és betöltjük a terméklistát az API-ból, és átalakítjuk a ProductOrders mivel minden termékhez egy mennyiség mezőt szeretnénk csatolni:

export osztály ProductsComponent megvalósítja az OnInit {productOrders: ProductOrder [] = []; termékek: Termék [] = []; selectedProductOrder: ProductOrder; privát vásárlásCartOrders: ProductOrders; al: Előfizetés; productSelected: logikai = hamis; konstruktor (privát ecommerceService: EcommerceService) {} ngOnInit () {this.productOrders = []; this.loadProducts (); this.loadOrders (); } loadProducts () {this.ecommerceService.getAllProducts () .subscribe ((products: any []) => {this.products = products; this.products.forEach (product => {this.productOrders.push (new ProductOrder ( termék, 0));})}, (hiba) => konzol.log (hiba)); } loadOrders () {this.sub = this.ecommerceService.OrdersChanged.subscribe (() => {this.shoppingCartOrders = this.ecommerceService.ProductOrders;}); }}

Arra is szükségünk van, hogy felvegyük a terméket a bevásárlókosárba, vagy eltávolítsuk azt belőle:

addToCart (rendelés: ProductOrder) {this.ecommerceService.SelectedProductOrder = rendelés; this.selectedProductOrder = this.ecommerceService.SelectedProductOrder; this.productSelected = true; } removeFromCart (productOrder: ProductOrder) {legyen index = this.getProductIndex (productOrder.product); if (index> -1) {this.shoppingCartOrders.productOrders.splice (this.getProductIndex (productOrder.product), 1); } this.ecommerceService.ProductOrders = this.shoppingCartOrders; this.shoppingCartOrders = this.ecommerceService.ProductOrders; this.productSelected = hamis; }

Végül létrehozunk egy Visszaállítás() módszer, amelyet a 3.4 szakaszban említettünk:

reset () {this.productOrders = []; this.loadProducts (); this.ecommerceService.ProductOrders.productOrders = []; this.loadOrders (); this.productSelected = hamis; }

HTML-fájlunk terméklistáját végigvezetjük, és megjelenítjük a felhasználó számára:

{{order.product.name}}

$ {{order.product.price}}

3.8. Rendelések

A lehető legegyszerűbben fogjuk tartani a dolgokat és a OrdersComponent szimulálja a fizetést úgy, hogy a tulajdonságot igazra állítja, és elmenti a sorrendet az adatbázisban. A rendelések mentését a következőn keresztül is ellenőrizhetjük h2-konzol vagy ütéssel // localhost: 8080 / api / megrendelések.

Szükségünk van a EcommerceService itt is annak érdekében, hogy lehívjuk a terméklistát a bevásárlókosárból és a megrendelésünk teljes összegét:

export osztály OrdersComponent megvalósítja az OnInit {megrendeléseket: ProductOrders; teljes szám; fizetett: logikai; al: Előfizetés; konstruktor (privát ecommerceService: EcommerceService) {this.orders = this.ecommerceService.ProductOrders; } ngOnInit () {this.fizetett = hamis; this.sub = this.ecommerceService.OrdersChanged.subscribe (() => {this.orders = this.ecommerceService.ProductOrders;}); this.loadTotal (); } pay () {this.fizetett = igaz; this.ecommerceService.saveOrder (this.rendelések) .subscribe (); }}

És végül meg kell jelenítenünk az információkat a felhasználó számára:

RENDELÉS

  • {{order.product.name}} - $ {{order.product.price}} x {{order.quantity}} db.

Teljes összeg: $ {{total}}

Fizetés Gratulálok! Sikeresen elvégezte a megrendelést.

4. A tavaszi csomagtartó és a szögletes alkalmazások egyesítése

Befejeztük mindkét alkalmazásunk fejlesztését, és valószínűleg könnyebb külön-külön fejleszteni, mint tettük. De a gyártás során sokkal kényelmesebb lenne egyetlen alkalmazás, ezért egyesítsük ezt a kettőt.

Amit itt akarunk tenni, az az készítse el az Angular alkalmazást, amely felhívja a Webpack-ot, hogy összegyűjtse az összes eszközt, és betolja őket az / resources / static a Spring Boot alkalmazás könyvtárát. Így egyszerűen futtathatjuk a Spring Boot alkalmazást, tesztelhetjük az alkalmazást, és mindezt csomagolhatjuk, és egy alkalmazásként telepíthetjük.

Ahhoz, hogy ezt lehetővé tegyük, meg kell tennünk nyisd ki 'csomag.json’Utána ismét adjon hozzá néhány új szkriptet szkriptek.épít:

"postbuild": "npm fut telepítés", "előre telepítés": "rimraf ../resources/static/ && mkdirp ../resources/static", "deploy": "copyfiles -f dist / ** ../resources/ statikus",

Néhány olyan csomagot használunk, amelyeket még nem telepítettünk, ezért telepítsük őket:

npm install --save-dev rimraf npm install --save-dev mkdirp npm install --save-dev copyfiles

A rimraf parancs meg fogja nézni a könyvtárat, és létrehoz egy új könyvtárat (valójában megtisztítva), míg másolatfájlok átmásolja a fájlokat a terjesztési mappából (ahová az Angular mindent elhelyez) a mi fájlunkba statikus mappába.

Most csak nekünk kell fuss npm futtatás parancsot, és ennek futtatnia kell ezeket a parancsokat, és a végső kimenet lesz a statikus mappában lévő csomagolt alkalmazásunk.

Ezután futtatjuk a Spring Boot alkalmazást a 8080-as porton, ott elérjük és használjuk az Angular alkalmazást.

5. Következtetés

Ebben a cikkben létrehoztunk egy egyszerű e-kereskedelmi alkalmazást. Létrehoztunk egy API-t a háttérrendszeren a Spring Boot használatával, majd ezt felhasználtuk a szögletes frontend alkalmazásunkban. Bemutattuk, hogyan lehet a szükséges összetevőket előállítani, egymással kommunikálni és adatokat lekérni / küldeni az API-ból / az API-ba.

Végül bemutattuk, hogyan lehet mindkét alkalmazást egyetlen, csomagolt webalkalmazásba egyesíteni a statikus mappában.

Mint mindig, a cikkben leírt teljes projekt megtalálható a GitHub projektben.