Json数据未被接收的问题

写了一个购买的功能模块,但是前台接收不到数据?
后台代码如下
@ResponseBody
@RequestMapping(value = "/buy",method= RequestMethod.POST,produces = MediaType.JSON)
public JsonResult api_buy(HttpSession httpSession,
@RequestParam("id") Long product_id)
{
System.out.println("Class BuyApiController Method api_buy");
System.out.println("[product_id]:" + product_id);

    //session
    System.out.println("[session.id]:" + httpSession.getId());
    UserVO userVO = (UserVO) httpSession.getAttribute("user");

    JsonResult jsonResult = new JsonResult();
    if(product_id == null)
    {
        //请求参数有错误 http status code is 400
        jsonResult.setCode("400");
        jsonResult.setMessage("购买失败");
        jsonResult.setResult(false);
    }
    else
    {
        if(userVO == null)
        {
            //401 Unauthorized当前请求需要验证
            jsonResult.setCode("401");
            jsonResult.setMessage("购买失败");
            jsonResult.setResult(false);
        }
        else if(userVO.getUsertype() == 0)
        {
            //buy
            try {
                this.transactionServiceImpl.buy(userVO, product_id);

                jsonResult.setCode("200");
                jsonResult.setMessage("购买成功");
                jsonResult.setResult(true);
            }
            catch (Exception e)
            {
                System.out.println("[Exception]:" + e.toString());
                jsonResult.setCode("400");
                jsonResult.setMessage("购买失败");
                jsonResult.setResult(false);
            }
        }
        else if(userVO.getUsertype() == 1)
        {
            //403 Forbidden,当卖家点击进入购买时,则发生没有权限,导致操作拒绝
            jsonResult.setCode("403");
            jsonResult.setMessage("购买失败");
            jsonResult.setResult(false);
        }
        else
        {
            //403 Forbidden未知身份发生购买,拒绝
            jsonResult.setCode("403");
            jsonResult.setMessage("购买失败");
            jsonResult.setResult(false);
        }
    }

    return jsonResult;

    前端ftl代码:
    <div class="g-doc" id="settleAccount">
<div class="m-tab m-tab-fw m-tab-simple f-cb" >
    <h2>已添加到购物车的内容</h2>
</div>
<table id="newTable" class="m-table m-table-row n-table g-b3">
</table>
<div id="act-btn"><button class="u-btn u-btn-primary" id="back">退出</button>
<button class="u-btn u-btn-primary" id="Account">购买</button></div>


<#include "/include/footer.ftl">

ModelAndView modelAndView = new ModelAndView("settleAccount");
//当用户不为空时,返回用户信息
if(userVO != null)
modelAndView.addObject("user", userVO);
return modelAndView;

这一段可以改为直接返回JSON字符串
JSONObject obj = new JSONObject();
if(userVO != null)
obj.put("user", userVo);
return obj.toString();

不想改的话可以参照如下
http://blog.163.com/rains_xy/blog/static/1103309902012818105937299/

当然你可以用chrome查看你这个登录成功请求返回的结果
chrome调式工具Network可以查看你这个请求返回的数据格式

JS代码
(function(w,d,u){
var settleAccount = util.get('settleAccount');
if(!settleAccount){
return;
}
var name = 'products';
var products = util.getCookie(name);
var $ = function(id){
return document.getElementById(id);
}

    var str = "<tr>" + 
              "<th>" + '内容名称'  + "</th>"+ 
              "<th>" + '数量' + "</th>" +
              "<th>" + '价格' + "</th>" +
              "</tr>";

    for(var i = 0; i < products.length; i++){
        str = str + 
        "<tr>" + 
        "<td>" + products[i].title  + "</td>"+
        "<td>" + 
        "<span class=\"lessNum\">"+ "-" + "</span>" +
        "<span class=\"totalNum\" id=\"allNum\">" + products[i].num + "</span>" +
        "<span id=\"thisId\">" + products[i].id + "</span>" +
        "<span class=\"moreNum\">"+ "+" + "</span>" + "</td>" +
        "<td>" + products[i].price + "</td>" +
        "</tr>";
    }

    $("newTable").innerHTML = str;

    window.onload = function(){
        $('newTable').onclick = function(e){
            var e = arguments[0] || window.event;
            target = e.srcElement ? e.srcElement : e.target;
            if(target.nodeName == "SPAN" && target.className == "moreNum"){
                var num = target.parentElement.children[1].textContent;
                var id = target.parentElement.children[2].textContent;
                num ++;
                target.parentElement.children[1].textContent = num;
                util.modifyOne(products,id,num);
            }else if(target.nodeName == "SPAN" && target.className == "lessNum"){
                var num = target.parentElement.children[1].textContent;
                var id = target.parentElement.children[2].textContent;
                num --;
                if(num < 0){
                    alert("该商品数量为0");
                }else{
                    target.parentElement.children[1].textContent = num;
                    util.modifyOne(products,id,num);
                }
            }
            return false;
        };
    };

    var loading = new Loading();
    var layer = new Layer();
    $('Account').onclick = function(e){
        var newProducts = products.map(function(arr){
            return {'id':arr.id,'number':arr.num};
        });
        console.log(newProducts);
        var ele = e.target;
            layer.reset({
                content:'确认购买吗?',
                onconfirm:function(){
                    layer.hide();
                    loading.show();

                    var xhr = new XMLHttpRequest();
                    var data = JSON.stringify(newProducts);
                    xhr.onreadystatechange = function(){
                         if(xhr.readyState == 4){
                                var status = xhr.status;
                                if(status >= 200 && status < 300 || status == 304){
                                    var json = JSON.parse(xhr.responseText);
                                    if(json && json.code == 200){
                                        loading.result('购买成功',function(){location.href = '/webapp/account';});
                                        util.deleteCookie(name);
                                    }else{
                                        alert(json.message);
                                    }
                                }else{
                                    loading.result(message||'购买失败');
                                }
                            }
                    };
                     xhr.open('post','/api/buy');
                     xhr.setRequestHeader('Content-Type','application/json');
                     xhr.send(data);
                }.bind(this)
            }).show();
            return;
    };
    $('back').onclick = function(){
        location.href = window.history.back();
    }
})(window,document);

看的好累,自己打断点调式下,定位是后台代码问题还是前端代码问题。说实话不是很麻烦的,你这样问 大家应该看的都好累吧,先定位问题所在,,再来问多高效啊