본문 바로가기

Study/Spring

[Spring] Store - Cart View (장바구니) / AngularJS - RestAPI

Angular를 사용해 CartView 구현 

 

AngularJs란? - Front-end Framework

  • AngularJs : javascript framework (MVC지원)
  • AngularJs extends HTML wwith ng-directives
  • Angluar : typescript

 

 

Work Flow

 

 

 

 

 

 

 

 

RestAPI 구현 

CartRestController.java 생성

 

package kr.ac.hansung.cse.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import kr.ac.hansung.cse.model.Cart;
import kr.ac.hansung.cse.model.CartItem;
import kr.ac.hansung.cse.model.Product;
import kr.ac.hansung.cse.model.User;
import kr.ac.hansung.cse.service.CartItemService;
import kr.ac.hansung.cse.service.CartService;
import kr.ac.hansung.cse.service.ProductService;
import kr.ac.hansung.cse.service.UserService;

@RestController // @Controller + @ResponseBody
@RequestMapping("/api/cart")
public class CartRestController {

	@Autowired
	private CartService cartService;
	
	@Autowired
	private CartItemService cartItemService;
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private ProductService productService;
	
	@RequestMapping(value = "/{cartId}", method=RequestMethod.GET)
	public ResponseEntity<Cart> getCartById(@PathVariable(value = "cartId") int cartId){
		Cart cart = cartService.getCartById(cartId);
		return new ResponseEntity<Cart>(cart, HttpStatus.OK);
	}
	
	@RequestMapping(value="/{cartId}", method=RequestMethod.DELETE)
	public ResponseEntity<Void>clearCart(@PathVariable(value = "cartId") int cartId){
		Cart cart = cartService.getCartById(cartId);
		cartItemService.removeAllCartItems(cart);
	
		return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
	}
	
	@RequestMapping(value="/add/{productId}", method = RequestMethod.PUT)
	public ResponseEntity<Void> addItem(@PathVariable(value="productId")int productId){
	
		Product product = productService.getProductById(productId);
	
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		String username = authentication.getName();
		
		User user = userService.getUserByUsername(username);
		Cart cart = user.getCart();
		
		List<CartItem> cartItems = cart.getCartItems();
		
		//check if cartitem for a given product already exists
		for(int i=0; i<cartItems.size(); i++) {
			if(product.getId() == cartItems.get(i).getProduct().getId()) {
				CartItem cartItem = cartItems.get(i);
				cartItem.setQuantity(cartItem.getQuantity()+1);
				cartItem.setTotalPrice(product.getPrice() * cartItem.getQuantity());
				cartItemService.addCartItem(cartItem);
				
				return new ResponseEntity<>(HttpStatus.OK);
			}
		}
		
		// create new cartItem
		CartItem cartItem = new CartItem();
		cartItem.setQuantity(1);
		cartItem.setTotalPrice(product.getPrice() * cartItem.getQuantity());
		cartItem.setProduct(product);
		cartItem.setCart(cart);
		
		// bidirectional
		cart.getCartItems().add(cartItem);
		
		cartItemService.addCartItem(cartItem);
		
		return new ResponseEntity<>(HttpStatus.OK);
	
	}
	
	@RequestMapping(value="/cartItem/{productId}", method = RequestMethod.DELETE)
	public ResponseEntity<Void> removeItem(@PathVariable(value="productId") int productId){
		
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		String username = authentication.getName();
		
		User user = userService.getUserByUsername(username);
		Cart cart = user.getCart();
		
		CartItem cartItem = cartItemService.getCartItemByProductId(cart.getId(),productId);
		cartItemService.removeCartItem(cartItem);
		
		return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
	}
	
	
	
}
  • @RequestMapping("/api/cart") 에서 path에 api를 넣음으로써 REST Service임을 명시.

 

//현재 인증된(로그인된) 사용자의 정보를 가져온다.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = authentication.getName();
		
User user = userService.getUserByUsername(username);

 

위의 코드를 사용하기 위해 

1. servlet-context.xml에 추가

<argument-resolvers>
	<beans:bean
		class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver">
	</beans:bean>
</argument-resolvers>

 

- servlet-context.xml 전체코드 

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing 
		infrastructure -->

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven>
		<argument-resolvers>
			<beans:bean
				class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver">
			</beans:bean>
		</argument-resolvers>
	</annotation-driven>

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<context:component-scan
		base-package="kr.ac.hansung.cse.controller" />


	<beans:bean id="tilesViewResolver"
		class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
	</beans:bean>
	<beans:bean id="tilesConfigurer"
		class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
		<beans:property name="definitions">
			<beans:list>
				<beans:value>/WEB-INF/tiles-def/tiles.xml</beans:value>
			</beans:list>
		</beans:property>
	</beans:bean>
	
	<beans:bean
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
		id="multipartResolver">
	<beans:property name="maxUploadSize" value="10240000"></beans:property>
	</beans:bean>
	
</beans:beans>

 

 

Anguler 세팅

 

1. controller.js생성

 

var cartApp = angular.module('cartApp', []);

cartApp.controller("cartCtrl", function($scope, $http) {
	
	$scope.initCartId = function(cartId){
		$scope.cartId = cartId;
		$scope.refreshCart();
	};
	
	$scope.refreshCart = function(){
		$http.get('/eStore/api/cart/' + $scope.cartId).then(
				function successCallback(response) {
					$scope.cart = response.data;
				});	
	};
	
	$scope.clearCart = function(){
		$http({
			method : 'DELETE',
			url : '/eStore/api/cart/' + $scope.cartId
		}). then(function successCallback(){
			$scope.refreshCart();
		},  function errorCallback(response){
			console.log(response.data);
		});
	};
	
	$scope.addToCart = function(productId){
		$http.put('/eStoer/api/cart/add/' + productId). then(
				function successCallback(){
					alert("Product successfully added to the cart!");
				}, function errorCallback(){
					alert("Adding to the cart failed!");
				});
	};
	
	$scope.removeFromCart = function(productId){
		$http({
			method : 'DELETE',
			url : '/eStore/api/cart/cartitem/' + productId
		}).then(function successCallback(){
			$scope.refreshCart();
		}, function errorCallback(response){
			console.log(response.data);
		});
	};
	
	$scope.calGrandTotal = function(){
		var grandTotal = 0;
		
		for(var i = 0 ; i < $scope.cart.cartItems.length; i++){
			grandTotal += $scope.cart.cartItems[i].totalPrice;
		}
		return grandTotal;
	};
	
});

 

CartRestController의 각 함수들을 호출

 

 

2. layout.jsp에 Angular JS 추가

 

https://angularjs.org/

 

AngularJS — Superheroic JavaScript MVW Framework

document.createElement('tabs'); document.createElement('pane'); document.createElement('ng-pluralize'); <!-- Prompt IE 6 users to install Chrome Frame. Remove this if you support IE 6. chromium.org/developers/how-tos/chrome-frame-getting-started --> Yo

angularjs.org

 

공식홈페이지 > DownLoad AngularJs > CDN 복사 후 

layout.jsp에 <script src = https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js></script> 를 추가한다.

 

- layout.jsp 전체코드 

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
	content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="/docs/4.0/assets/img/favicons/favicon.ico">

<title><tiles:insertAttribute name="title"/></title>

<link rel="canonical"
	href="https://getbootstrap.com/docs/4.0/examples/carousel/">

<!-- Bootstrap core CSS -->
<link href="<c:url value="/resources/css/bootstrap.min.css"/>"
	rel="stylesheet">

<!-- Custom styles for this template -->
<link href="<c:url value="/resources/css/carousel2.css"/>"
	rel="stylesheet">
<link href="<c:url value="/resources/css/main.css"/>" rel="stylesheet">
<!-- font-awesome -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">

<!-- AngularJS -->
<script src = https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js></script>
</head>
<body>

	<div>
		<tiles:insertAttribute name="menu"/>
		<tiles:insertAttribute name="body"/>
		<tiles:insertAttribute name="footer"/>
	</div>

	<!-- Bootstrap core JavaScript
    ================================================== -->
	<!-- Placed at the end of the document so the pages load faster -->
	<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
		integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
		crossorigin="anonymous"></script>
	<script
		src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js"
		integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
		crossorigin="anonymous"></script>
	<script src="<c:url value="/resources/js/bootstrap.min.js"/>"></script>
</body>
</html>