user3844782
user3844782

Reputation:

Spring controller - send html as response

I have a loaded jsp page with products and addtocart link against it. I am trying to show the cart in a div in the same page. I want to send html as response. This is what i have done. It just returns the string <div>output</div>. Can someone show me how i should do it.

Controller

    @RequestMapping(value="/addtocart{id}",  produces = "text/plain;charset=UTF-8")
    @ResponseBody
    public String addToCart(@PathVariable("id") int id, @ModelAttribute("cart") Cart cart,Model model)
    {
        Product product = productService.getProductById(id);
        if (product != null) {
            CartLine line = new CartLine();
            line.setProduct(product);
            line.setQuantity(1);
            productService.updateProduct(product);
        }
        return "<div>output</div>"; 
    }

JSP

<td><a id="demo4" href="addtocart${product.id}">Add To Cart</a> </td>

$('#demo4').click(function() { 

                $.ajax({    
                url : '/addtocart{id}',
                dataType: 'json',
                contentType: "text/html",
                type : 'GET',
                data :{id:id},
                success : function(response) {
                    $('#output').html(response);
                   }
                 }); 
        }); 

<div id="output" style="display:none">
           <h2>Cart Content(s):</h2>
</div>

Upvotes: 4

Views: 20255

Answers (2)

Master Slave
Master Slave

Reputation: 28519

I also favor the approach with using the view, and separate page even on ajax call. Nevertheless what you're asking is possible, simply change your produces = "text/plain;charset=UTF-8" to produces

produces = "text/html;charset=UTF-8"

There are many other aspects that appear wrong, not related to Spring MVC, so even with the produces corrected you still have to do few corrections to get what you're expecting.

  • I think that you're not sending an ajax call at all. You're most likely doing a complete browser redirect. When first read, I was confused that "text/plain" vs "text/html" makes a difference in an ajax response, but now I believe that you're actually redirecting via browser. Change this <a id="demo4" href="addtocart${product.id}">Add To Cart</a> into something like this <a id="demo4" href="#">Add To Cart</a> and add return false to the end of your function. This will execute the function, and the return will make sure that the link is not followed

  • When you do this you'll notice a few issues with your ajax call as well; firstly, url : '/addtocart{id}' should be url : '/addtocart${product.id}

  • Capture your response in complete function not in success, and get the output as response.responseText, the response will return fine, but the browser will attempt to parse it as json and fail.

  • Your div will remain invisible, you should add some js to toggle that

  • One Spring MVC gotcha, your Cart bean seems to have a property called id as well. Because of this, your id path variable should be renamed, otherwise it'll be ignored

This would be something that, if not completly, than much closer to working

<a id="demo4" href="#">Add To Cart</a>

<div id="output"></div>
<script>

    $('#demo4').click(function() {

        $.ajax({
            url : '/addtocart${product.id}',
            dataType: 'json',
            contentType: "text/html",
            type : 'GET',
            data :{id:4},
            complete: function(response) {
                $('#output').html(response.responseText);
            }
        });
        return false;
    });
</script>

Renaming PathVariable

@RequestMapping(value="/addtocart{productId}",  produces = "text/plain;charset=UTF-8")
public String addToCart(@PathVariable("productId") int productId, @ModelAttribute("cart") Cart cart,Model model)

Upvotes: 4

Jonas
Jonas

Reputation: 1345

You can do it with AJAX and still return a separate page for your Card, as Slava suggested.

JSP page cart.jsp:

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- custom html for your cart representation, just an example -->
<div>
  <h1>${cart.headline}</h1>
  <p>${cart.otherProperty}</p>
</div>

Controller:

@RequestMapping(value="/addtocart{id}")
public String addToCart(@PathVariable("id") int id, @ModelAttribute("cart") Cart cart, Model model) {
    doSomethingWithCart(cart);

    model.addAttribute("cart", cart); // add cart to model after doing some custom operations
    return "cart"; // resolved to cart.jsp by your view resolver
}

This way you are using AJAX but still you are returning dynamic html content ( adjusted to one specific cart).

Upvotes: 1

Related Questions