shop--10.商品--商品添加(前端)及问题的解决
productoperation.html
其中包括商品信息的添加和商品信息的修改,这个和店铺信息注册和修改用的是一样的
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>商品操作</title> <meta name="viewport" content="initial-scale=1, maximum-scale=1"> <link rel="shortcut icon" href="/favicon.ico"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="stylesheet" href="//g.alicdn.com/msui/sm/0.6.2/css/sm.min.css"> <link rel="stylesheet" href="//g.alicdn.com/msui/sm/0.6.2/css/sm-extend.min.css"> </head> <body> <header class="bar bar-nav"> <h1 class="title">商品操作</h1> </header> <div class="content"> <div class="list-block"> <ul> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-name"></i> </div> <div class="item-inner"> <div class="item-title label">商品名称</div> <div class="item-input"> <input type="text" id="product-name" placeholder="商品名称"> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-email"></i> </div> <div class="item-inner"> <div class="item-title label">目录</div> <div class="item-input"> <select id="product-category"> </select> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-email"></i> </div> <div class="item-inner"> <div class="item-title label">优先级</div> <div class="item-input"> <input type="number" id="priority" placeholder="数字越大越排前面"> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-email"></i> </div> <div class="item-inner"> <div class="item-title label">原价</div> <div class="item-input"> <input type="number" id="normal-price" placeholder="可选"> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-email"></i> </div> <div class="item-inner"> <div class="item-title label">现价</div> <div class="item-input"> <input type="number" id="promotion-price" placeholder="可选"> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-email"></i> </div> <div class="item-inner"> <div class="item-title label">缩略图</div> <div class="item-input"> <input type="file" id="small-img"> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-email"></i> </div> <div class="item-inner detail-img-div"> <div class="item-title label">详情图片</div> <div class="item-input" id="detail-img"> <input type="file" class="detail-img"> <!-- <input type="file" class="detail-img" id="detail-img-1"> <input type="file" class="detail-img" id="detail-img-2"> --> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-email"></i> </div> <div class="item-inner"> <div class="item-title label">商品描述</div> <div class="item-input"> <textarea id="product-desc" placeholder="商品描述"></textarea> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-media"> <i class="icon icon-form-email"></i> </div> <div class="item-inner"> <label for="j_captcha" class="item-title label">验证码</label> <input id="j_captcha" name="j_captcha" type="text" class="form-control in" placeholder="验证码" /> <div class="item-input"> <img id="captcha_img" alt="点击更换" title="点击更换" onclick="changeVerifyCode(this)" src="../Kaptcha" /> </div> </div> </div> </li> </ul> </div> <div class="content-block"> <!-- 预留两个按钮 TODO --> <div class="row"> <div class="col-50"> <a href="#" class="button button-big button-fill button-danger" id="back">返回商品管理</a> </div> <div class="col-50"> <a href="#" class="button button-big button-fill" id="submit">提交</a> </div> </div> </div> </div> <script type='text/javascript' src='//g.alicdn.com/sj/lib/zepto/zepto.min.js' charset='utf-8'></script> <script type='text/javascript' src='//g.alicdn.com/msui/sm/0.6.2/js/sm.min.js' charset='utf-8'></script> <script type='text/javascript' src='//g.alicdn.com/msui/sm/0.6.2/js/sm-extend.min.js' charset='utf-8'></script> <!-- 引入自定义的JS --> <script type='text/javascript' src='../resources/js/common/common.js' charset='utf-8'></script> <script type='text/javascript' src='../resources/js/shop/productoperation.js' charset='utf-8'></script> </body> </html>
productoperation.js
商品添加和商品编辑使用的是同一个页面,所以需要根据请求的url来判断是编辑还是新增。
/** * 因为商品的添加和编辑复用同一个页面,所以需要根据url中的商品Id来判断 */ $(function(){ //通过url是否含有productId来判断是添加商品还是编辑 var productId = getQueryString('productId'); // 标示符 productId非空则为true即编辑,否则为添加商品 var isEdit = productId ? true : false ; // 商品添加URL var addProductURL = '/o2o/shopadmin/addproduct'; // 商品编辑URL TODO var editProductURL = ''; // 获取商品初始化信息的URL 根据页面原型只需要获取productCategory即可,后台调用之前写好的路由方法即可 var initProductURL = '/o2o/shopadmin/getproductcategorylist'; // 通过标示符,确定调用的方法 if(isEdit){ // 为true,则根据productId调用获取product信息的方法 TODO getProductInfoById(productId); }else{ // 为false,则初始化新增product页面 getProductInitInfo(); } /** * 始化新增product页面 * * 根据页面原型和数据模型,需要加载该shop对应的productCategory信息(shop信息从服务端session中获取) */ function getProductInitInfo(){ $.getJSON(initProductURL, function(data){ if(data.success){ // 设置product_category var productCategoryTempHtml = ''; data.productCategoryList.map(function(item, index) { // productCategoryTempHtml += '<option data-id="' // + item.productCategoryId + '">' + item.productCategoryName // + '</option>'; productCategoryTempHtml += '<option data-value="' + item.productCategoryId + '">' + item.productCategoryName + '</option>'; }); $('#product-category').html(productCategoryTempHtml); }else{ $.toast(data.errMsg) } }); }; /** * 点击控件的最后一个且图片数量小于6个的时候,生成一个选择框 */ $('.detail-img-div').on('change', '.detail-img:last-child', function() { if ($('.detail-img').length < 6) { $('#detail-img').append('<input type="file" class="detail-img">'); } }); /** * 提交按钮的响应时间,分别对商品添加和商品编辑做不同的相应 */ $('#submit').click( function(){ // 创建商品Json对象,并从表单对象中获取对应的属性值 var product = {}; // 如果是编辑操作,需要传入productId if(isEdit){ product.productId = productId; } product.productName = $('#product-name').val(); product.productDesc = $('#product-desc').val(); // 获取商品的特定目录值 product.productCategory = { productCategoryId : $('#product-category').find('option').not( function() { return !this.selected; }).data('value') }; product.priority = $('#priority').val(); product.normalPrice = $('#normal-price').val(); product.promotionPrice = $('#promotion-price').val(); // 生成表单对象用于接收参数并传递给后台 var formData = new FormData(); // 缩略图 (只有一张),获取缩略图的文件流 var thumbnail = $('#small-img')[0].files[0]; formData.append('thumbnail',thumbnail); // 图片详情 $('.detail-img').map( function(index, item) { // 判断该控件是否已经选择了文件 if ($('.detail-img')[index].files.length > 0) { // 将第i个文件流赋值给key为productImgi的表单键值对里 formData.append('productImg' + index, $('.detail-img')[index].files[0]); } }); // 将product 转换为json ,添加到forData formData.append('productStr', JSON.stringify(product)); // 获取表单中的验证码 var verifyCodeActual = $('#j_captcha').val(); if (!verifyCodeActual) { $.toast('请输入验证码!'); return; } formData.append("verifyCodeActual", verifyCodeActual); // 使用ajax异步提交 $.ajax({ url: isEdit?editProductURL:addProductURL, type: 'POST' , data : formData, contentType : false, processData : false, cache : false, success: function(){ console.log(data) if (data.success) { $.toast('提交成功!'); $('#captcha_img').click(); } else { $.toast('提交失败!'); $('#captcha_img').click(); } }, error:function(err){ console.log(err.status); console.log('异常'); } }); }); });
问题
在调试的时候发现String index out of range: -1超出索引
debug 发现是ImageUtil里的获取后缀名方法出错了
但是在测试Service时候是可以插入的 那么问题肯定出现在Controller层了,看看哪里使用到了ImageUtil方法
try { //若请求中存在文件流,则取出相关的文件(包括缩略图和详情图) if(commonsMultipartResolver.isMultipart(request)) { // 将HttpServletRequest转型为MultipartHttpServletRequest,可以很方便地得到文件名和文件内容 multipartHttpServletRequest = (MultipartHttpServletRequest) request; //1.接收商品缩略图 取出缩略图并构建ImageHolder对象 CommonsMultipartFile thumbnailFile = (CommonsMultipartFile) multipartHttpServletRequest.getFile("thumbnail"); //2.转化为ImageHolder,使用service层的参数类型要求 thumbnail = new ImageHolder(thumbnailFile.getOriginalFilename(), thumbnailFile.getInputStream()); //3.取出详情图列表并构建List<ImageHolder>列表对象,最多支持六张图上传 for(int i = 0; i < IMAGEMAXCOUNT; i++){ CommonsMultipartFile File = (CommonsMultipartFile) multipartHttpServletRequest.getFile("productImg" + i); if(File != null){ //若取出的第i个详情图片文件流不为空,则将其加入详情图列表 ImageHolder productImg = new ImageHolder(File.getName(), File.getInputStream()); productImgList.add(productImg); } else { //若取出的第i个详情图片文件流为空,则终止循环 break; } } }
原来是
getName
: 获取表单中文件组件的名字getOriginalFilename
: 获取上传文件的原名
这里出错了 将getName() 改成 getOriginalFilename()即可
同时将之前的改过来