2

I am developing an e-commerce website using Spring-MVC and I am in the process of creating the cart. I am looking up the URL tradingcards/rest/cart/add/P1 and receiving the error "Request method 'GET' not supported" even though the method, "addItem()" that is mapped to that URL is a PUT method.

I know that this is a lot of code to look at but i would greatly appreciate any help that is offered

CartRestController.java

package com.tradingcards.tradingcards.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.tradingcards.tradingcards.domain.Cart;
import com.tradingcards.tradingcards.domain.CartItem;
import com.tradingcards.tradingcards.domain.Product;
import com.tradingcards.tradingcards.exception.CardNotFoundException;
import com.tradingcards.tradingcards.service.CartService;
import com.tradingcards.tradingcards.service.ProductService;

@Controller
@RequestMapping(value = "rest/cart")
public class CartRestController {

    @Autowired
    private CartService cartService;

    @Autowired
    private ProductService productService;

    @RequestMapping(method = RequestMethod.POST)
    public @ResponseBody Cart create(@RequestBody Cart cart) {
        return  cartService.create(cart);
    }

    @RequestMapping(value = "/{cartId}", method = RequestMethod.GET)
    public @ResponseBody Cart read(@PathVariable(value = "cartId") String cartId) {
        return cartService.read(cartId);
    }

    @RequestMapping(value = "/{cartId}", method = RequestMethod.PUT)
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    public void update(@PathVariable(value = "cartId") String cartId,   @RequestBody Cart cart) {
        cartService.update(cartId, cart);
    }

    @RequestMapping(value = "/{cartId}", method = RequestMethod.DELETE)
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    public void delete(@PathVariable(value = "cartId") String cartId) {
        cartService.delete(cartId);
    }

    @RequestMapping(value = "/add/{productID}", method = RequestMethod.PUT)
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    public void addItem(@PathVariable String productID, HttpServletRequest request) {

        String sessionId = request.getSession(true).getId();
        Cart cart = cartService.read(sessionId);
        if(cart== null) {
            cart = cartService.create(new Cart(sessionId));
        }

        Product product = productService.getProductById(productID);
        if(product == null) {
            throw new IllegalArgumentException(new CardNotFoundException(productID));
        }

        cart.addCartItem(new CartItem(product));

        cartService.update(sessionId, cart);
    }

    @RequestMapping(value = "/remove/{productID}", method = RequestMethod.PUT)
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    public void removeItem(@PathVariable String productID, HttpServletRequest request) {

        String sessionId = request.getSession(true).getId();
        Cart cart = cartService.read(sessionId);
        if(cart== null) {
            cart = cartService.create(new Cart(sessionId));
        }

        Product product = productService.getProductById(productID);
        if(product == null) {
            throw new IllegalArgumentException(new CardNotFoundException(productID));
        }

        cart.removeCartItem(new CartItem(product));

        cartService.update(sessionId, cart);
    }

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST,  reason="Illegal request, please verify your payload")
    public void handleClientErrors(Exception ex) { }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason="Internal server error")
    public void handleServerErrors(Exception ex) {  }
}

CartItem.java

    package com.tradingcards.tradingcards.domain;

import java.io.Serializable;
import java.math.BigDecimal;

public class CartItem implements Serializable{



    /**
     * 
     */
    private static final long serialVersionUID = 3285341151884777001L;
    private Product product;
    private int quantity;
    private BigDecimal totalPrice;

    public CartItem() {
        // TODO Auto-generated constructor stub
    }

    public CartItem(Product product) {
        super();
        this.product = product;
        this.quantity = 1;
        this.totalPrice = product.getUnitPrice();
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
        this.updateTotalPrice();
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
        this.updateTotalPrice();
    }

    public BigDecimal getTotalPrice() {
        return totalPrice;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public void updateTotalPrice() {
        totalPrice = this.product.getUnitPrice().multiply(new BigDecimal(this.quantity));
    }

    @Override
    public int hashCode() {
        final int prime = 311;
        int result = 1;
        result = prime * result + ((product == null) ? 0 : product.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CartItem other = (CartItem) obj;
        if (product == null) {
            if (other.product != null)
                return false;
        } else if (!product.equals(other.product))
            return false;
        return true;
    }
}

Cart.java

    package com.tradingcards.tradingcards.domain;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class Cart implements Serializable{

    private static final long serialVersionUID = 3286257236940240478L;

    private String cartId;
    private Map<String,CartItem> cartItems;
    private BigDecimal grandTotal;

    public Cart() {
        cartItems = new HashMap<String, CartItem>();
        grandTotal = new BigDecimal(0);
    }

    public Cart(String cartId) {
        this();
        this.cartId = cartId;
    }

    public String getCartId() {
        return cartId;
    }

    public void setCartId(String cartId) {
        this.cartId = cartId;
    }

    public Map<String, CartItem> getCartItems() {
        return cartItems;
    }

    public void setCartItems(Map<String, CartItem> cartItems) {
        this.cartItems = cartItems;
    }

    public BigDecimal getGrandTotal() {
        return grandTotal;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public void addCartItem(CartItem item) {
        String productID = item.getProduct().getProductID();

        if(cartItems.containsKey(productID)) {
            CartItem existingCartItem = cartItems.get(productID);
            existingCartItem.setQuantity(existingCartItem.getQuantity()+ item.getQuantity());
            cartItems.put(productID, existingCartItem);
        } else {
            cartItems.put(productID, item);
        }
        updateGrandTotal();
    }

    public void removeCartItem(CartItem item) {
        String productID = item.getProduct().getProductID();
        cartItems.remove(productID);
        updateGrandTotal();
    }

    public void updateGrandTotal() {
        grandTotal= new BigDecimal(0);
        for(CartItem item : cartItems.values()){
            grandTotal = grandTotal.add(item.getTotalPrice());
        }
    }

    @Override
    public int hashCode() {
        final int prime = 71;
        int result = 1;
        result = prime * result + ((cartId == null) ? 0 : cartId.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Cart other = (Cart) obj;
        if (cartId == null) {
            if (other.cartId != null)
                return false;
        } else if (!cartId.equals(other.cartId))
            return false;
        return true;
    }
}

CartRepository.java

    package com.tradingcards.tradingcards.domain.repository;

import com.tradingcards.tradingcards.domain.Cart;

public interface CartRepository {
    Cart create(Cart cart);

    Cart read(String cartId);

    void update(String cartId, Cart cart);

    void delete(String cartID);
}

InMemoryCartRepository.java

package com.tradingcards.tradingcards.domain.repository.impl;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.tradingcards.tradingcards.domain.Cart;
import com.tradingcards.tradingcards.domain.repository.CartRepository;

@Repository
public class InMemoryCartRepository implements CartRepository {

private Map<String, Cart> listOfCarts;


    public InMemoryCartRepository() {
        listOfCarts = new HashMap<String,Cart>();

    }


    public Cart create(Cart cart) {
        if(listOfCarts.keySet().contains(cart.getCartId())) {
            throw new IllegalArgumentException(String.format("Can not create a cart. A cart with the give id (%) aldrady exist",cart.getCartId()));
        }

        listOfCarts.put(cart.getCartId(), cart);
        return cart;
    }


    public Cart read(String cartId) {
        return listOfCarts.get(cartId);
    }

    public void update(String cartId, Cart cart) {
        if(!listOfCarts.keySet().contains(cartId)) {
            throw new IllegalArgumentException(String.format("Can not update cart. The cart with the give id (%) does not does not exist",cartId));
        }

        listOfCarts.put(cartId, cart);
    }


    public void delete(String cartId) {
        if(!listOfCarts.keySet().contains(cartId)) {
            throw new IllegalArgumentException(String.format("Can not delete cart. The cart with the give id (%) does not does not exist",cartId));
        }

        listOfCarts.remove(cartId);
    }
}

CartService.java

package com.tradingcards.tradingcards.service;

import com.tradingcards.tradingcards.domain.Cart;

public interface CartService {

    Cart create(Cart cart);

    Cart read(String cartId);

    void update(String cartId, Cart cart);

    void delete(String cartId);

    Cart validate(String cartId);
}

CartServiceImpl

package com.tradingcards.tradingcards.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.tradingcards.tradingcards.domain.Cart;
import com.tradingcards.tradingcards.domain.repository.CartRepository;
import com.tradingcards.tradingcards.exception.InvalidCartException;
import com.tradingcards.tradingcards.service.CartService;

@Service
public class CartServiceImpl  implements CartService{

    @Autowired
    private CartRepository cartRepository;

    public Cart create(Cart cart) {
        return cartRepository.create(cart);
    }

    public Cart read(String cartId) {
        return cartRepository.read(cartId);
    }

    public void update(String cartId, Cart cart) {
        cartRepository.update(cartId, cart);
    }

    public void delete(String cartId) {
        cartRepository.delete(cartId);

    }

    public Cart validate(String cartId){
        Cart cart = cartRepository.read(cartId);
        if(cart==null || cart.getCartItems().size()==0){
            throw new InvalidCartException(cartId);
        }
        return cart;
    }
}

EDIT:

controllers.js

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

cartApp.controller('cartCtrl',  function ($scope, $http) {

    $scope.refreshCart = function(cartId) {
                                $http.get('/tradingcards/rest/cart/'+$scope.cartId).success(function(data) {
                                                $scope.cart = data;
                                            });
                            };

    $scope.clearCart = function() {
                                $http['delete']('/tradingcards/rest/cart/'+$scope.cartId)
                                     .success($scope.refreshCart($scope.cartId));

                          };

    $scope.initCartId = function(cartId) {
                            $scope.cartId=cartId;
                            $scope.refreshCart($scope.cartId);
                            };

      $scope.addToCart = function(productID) {
                                $http.put('/tradingcards/rest/cart/add/'+productID).success(function(data) {
                                                $scope.refreshCart($http.get('/tradingcards/rest/cart/get/cartId'));
                                                alert("Product Successfully added to the Cart!");
                                            });
                            };
      $scope.removeFromCart = function(productID) {
                                    $http.put('/tradingcards/rest/cart/remove/'+productID).success(function(data) {
                                                $scope.refreshCart($http.get('/tradingcards/rest/cart/get/cartId'));
                                                });
                                };
      });
4
  • Does the client specify it is making a PUT request? Commented Apr 15, 2016 at 23:22
  • @ochi yes the client does specify it is making a PUT request. I have updated the question to include my javascript file Commented Apr 16, 2016 at 0:36
  • hmm, you seem to be missing the payload on the PUT request - see if this helps stackoverflow.com/a/16783540/600486 Commented Apr 16, 2016 at 1:48
  • @ochi i believe that it is a back-end problem not client side. Commented Apr 16, 2016 at 10:18

1 Answer 1

0

I added this in a comment, but I am concerned (like the other commenter) about this call in your client after your put completes:

$http.get('/webstore/rest/cart/get/cartId')

I don't see a valid mapping for this call in the controller:

@RequestMapping(method = RequestMethod.POST)
@RequestMapping(value = "/{cartId}", method = RequestMethod.GET)
@RequestMapping(value = "/{cartId}", method = RequestMethod.PUT)
@RequestMapping(value = "/{cartId}", method = RequestMethod.DELETE)
@RequestMapping(value = "/add/{productID}", method = RequestMethod.PUT)
@RequestMapping(value = "/remove/{productID}", method = RequestMethod.PUT)

I would try commenting out this call and seeing what happens.

Did you mean to call /webstore/rest/cart/cartId? (i.e. without the /get)

Sign up to request clarification or add additional context in comments.

1 Comment

Oh I see now what you mean i will try changing it to that EDIT: that made no difference. I believe that the problem is occurring before it reaches that point.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.