一、前端信息传递(JS)
1、定义对象 var shop = {}
2、给对象添加值 shop.shopName = $("#shopName").val();赋值
3、小技巧
a、获取select的选中项
shopCategoryId : $('#shop-category').find('option').not(function() {
return !this.selected;
}).data('id')
// 给店铺选定原先的所属的区域
$("#area option[data-id='" + shop.area.areaId + "']").attr(
"selected", "selected");
$("#duanRuleType option[value='" + node.ruleType + "']").attr("selected", "selected");
b、获取上传的图片文件流
var shopImg = $('#shop-img')[0].files[0];
c、生成表单对象,用于接收参数并传递给后台
var formData = new FormData();
d、添加图片流进表单对象里
formData.append('shopImg', shopImg);
e、将给shop赋值然后用 json对象转成字符流保存至表单对象key为shopStr的的键值对里
formData.append('shopStr', JSON.stringify(shop));
f、ajax用form表单的形式提交类型
data : formData
g、可以通过$(function(){})中定义预加载内容,比方说需要用的区域信息等,这样不需要其他触发条件
$(function() {
// 从URL里获取shopId参数的值
var shopId = getQueryString('shopId');
// 由于店铺注册和编辑使用的是同一个页面,
// 该标识符用来标明本次是添加还是编辑操作
var isEdit = shopId ? true : false;
// 用于店铺注册时候的店铺类别以及区域列表的初始化的URL
var initUrl = '/o2o/shopadmin/getshopinitinfo';
// 注册店铺的URL
var registerShopUrl = '/o2o/shopadmin/registershop';
// 编辑店铺前需要获取店铺信息,这里为获取当前店铺信息的URL
var shopInfoUrl = "/o2o/shopadmin/getshopbyid?shopId=" + shopId;
// 编辑店铺信息的URL
var editShopUrl = '/o2o/shopadmin/modifyshop';
// 判断是编辑操作还是注册操作
if (!isEdit) {
getShopInitInfo();
} else {
getShopInfo(shopId);
}
// 通过店铺Id获取店铺信息
function getShopInfo(shopId) {
$.getJSON(shopInfoUrl, function(data) {
if (data.success) {
// 若访问成功,则依据后台传递过来的店铺信息为表单元素赋值
var shop = data.shop;
$('#shop-name').val(shop.shopName);
$('#shop-addr').val(shop.shopAddr);
$('#shop-phone').val(shop.phone);
$('#shop-desc').val(shop.shopDesc);
// 给店铺类别选定原先的店铺类别值
var shopCategory = '<option data-id="'
+ shop.shopCategory.shopCategoryId + '" selected>'
+ shop.shopCategory.shopCategoryName + '</option>';
var tempAreaHtml = '';
// 初始化区域列表
data.areaList.map(function(item, index) {
tempAreaHtml += '<option data-id="' + item.areaId + '">'
+ item.areaName + '</option>';
});
$('#shop-category').html(shopCategory);
// 不允许选择店铺类别
$('#shop-category').attr('disabled', 'disabled');
$('#area').html(tempAreaHtml);
// 给店铺选定原先的所属的区域
$("#area option[data-id='" + shop.area.areaId + "']").attr(
"selected", "selected");
}
});
}
// 取得所有二级店铺类别以及区域信息,并分别赋值进类别列表以及区域列表
function getShopInitInfo() {
$.getJSON(initUrl, function(data) {
if (data.success) {
var tempHtml = '';
var tempAreaHtml = '';
data.shopCategoryList.map(function(item, index) {
tempHtml += '<option data-id="' + item.shopCategoryId
+ '">' + item.shopCategoryName + '</option>';
});
data.areaList.map(function(item, index) {
tempAreaHtml += '<option data-id="' + item.areaId + '">'
+ item.areaName + '</option>';
});
$('#shop-category').html(tempHtml);
$('#area').html(tempAreaHtml);
}
});
}
// 提交按钮的事件响应,分别对店铺注册和编辑操作做不同响应
$('#submit').click(function() {
// 创建shop对象
var shop = {};
if (isEdit) {
// 若属于编辑,则给shopId赋值
shop.shopId = shopId;
}
// 获取表单里的数据并填充进对应的店铺属性中
shop.shopName = $('#shop-name').val();
shop.shopAddr = $('#shop-addr').val();
shop.phone = $('#shop-phone').val();
shop.shopDesc = $('#shop-desc').val();
// 选择选定好的店铺类别
shop.shopCategory = {
shopCategoryId : $('#shop-category').find('option').not(function() {
return !this.selected;
}).data('id')
};
// 选择选定好的区域信息
shop.area = {
areaId : $('#area').find('option').not(function() {
return !this.selected;
}).data('id')
};
// 获取上传的图片文件流
var shopImg = $('#shop-img')[0].files[0];
// 生成表单对象,用于接收参数并传递给后台
var formData = new FormData();
// 添加图片流进表单对象里
formData.append('shopImg', shopImg);
// 将shop json对象转成字符流保存至表单对象key为shopStr的的键值对里
formData.append('shopStr', JSON.stringify(shop));
// 获取表单里输入的验证码
var verifyCodeActual = $('#j_captcha').val();
if (!verifyCodeActual) {
$.toast('请输入验证码!');
return;
}
formData.append('verifyCodeActual', verifyCodeActual);
// 将数据提交至后台处理相关操作
$.ajax({
url : (isEdit ? editShopUrl : registerShopUrl),
type : 'POST',
data : formData,
contentType : false,
processData : false,
cache : false,
success : function(data) {
if (data.success) {
$.toast('提交成功!');
if (!isEdit) {
// 若为注册操作,成功后返回店铺列表页
window.location.href = "/o2o/shopadmin/shoplist";
}
} else {
$.toast('提交失败!' + data.errMsg);
}
// 点击验证码图片的时候,注册码会改变
$('#captcha_img').click();
}
});
});
})
h、通过网址获取网址附带的参数值
/**
* 组织正则表达式,主要是定位name所在的位置,并截取name=value
* 如www.baidu.com:8080?a=1&b=2&c=3
* 若传入b,则获取b=2,并经过后续步骤拆解成2返回
*/
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) {
return decodeURIComponent(r[2]);
}
return '';
}
i、
二、后端数据接收
1、接收前端传来的数据转化成对应的数据工具类
package com.imooc.o2o.util;
import javax.servlet.http.HttpServletRequest;
public class HttpServletRequestUtil {
public static int getInt(HttpServletRequest request, String key) {
try {
return Integer.decode(request.getParameter(key));
} catch (Exception e) {
return -1;
}
}
public static long getLong(HttpServletRequest request, String key) {
try {
return Long.valueOf(request.getParameter(key));
} catch (Exception e) {
return -1;
}
}
public static Double getDouble(HttpServletRequest request, String key) {
try {
return Double.valueOf(request.getParameter(key));
} catch (Exception e) {
return -1d;
}
}
public static boolean getBoolean(HttpServletRequest request, String key) {
try {
return Boolean.valueOf(request.getParameter(key));
} catch (Exception e) {
return false;
}
}
public static String getString(HttpServletRequest request, String key) {
try {
String result = request.getParameter(key);
if (result != null) {
result = result.trim();
}
if ("".equals(result)) {
result = null;
}
return result;
} catch (Exception e) {
return null;
}
}
}
2、Controller中转化及赋值
①实体类转换成json ,json转换成实体类ObjectMapper
a、引入jackson-databind (maven), 可参考其在github中的说明文档
b、先new一个jackson-databind对应的方法类 ObjectMapper mapper = new ObjectMapper();
c、通过readValue将前端传来的值(shopStr),转换成对应的实体类(Shop.class) Shop shop = mapper.readValue(shopStr, Shop.class);
② 具体执行代码
@RequestMapping(value = "/registershop", method = RequestMethod.POST)
@ResponseBody
private Map<String, Object> registerShop(HttpServletRequest request) {
Map<String, Object> modelMap = new HashMap<String, Object>();
if (!CodeUtil.checkVerifyCode(request)) {
modelMap.put("success", false);
modelMap.put("errMsg", "输入了错误的验证码");
return modelMap;
}
// 1.接收并转化相应的参数,包括店铺信息以及图片信息
String shopStr = HttpServletRequestUtil.getString(request, "shopStr");
ObjectMapper mapper = new ObjectMapper();
Shop shop = null;
try {
shop = mapper.readValue(shopStr, Shop.class);
} catch (Exception e) {
modelMap.put("success", false);
modelMap.put("errMsg", e.getMessage());
return modelMap;
}
CommonsMultipartFile shopImg = null;
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
if (commonsMultipartResolver.isMultipart(request)) {
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
} else {
modelMap.put("success", false);
modelMap.put("errMsg", "上传图片不能为空");
return modelMap;
}
// 2.注册店铺
if (shop != null && shopImg != null) {
PersonInfo owner = (PersonInfo) request.getSession().getAttribute("user");
shop.setOwner(owner);
ShopExecution se;
try {
ImageHolder imageHolder = new ImageHolder(shopImg.getOriginalFilename(), shopImg.getInputStream());
se = shopService.addShop(shop, imageHolder);
if (se.getState() == ShopStateEnum.CHECK.getState()) {
modelMap.put("success", true);
// 该用户可以操作的店铺列表
@SuppressWarnings("unchecked")
List<Shop> shopList = (List<Shop>) request.getSession().getAttribute("shopList");
if (shopList == null || shopList.size() == 0) {
shopList = new ArrayList<Shop>();
}
shopList.add(se.getShop());
request.getSession().setAttribute("shopList", shopList);
} else {
modelMap.put("success", false);
modelMap.put("errMsg", se.getStateInfo());
}
} catch (ShopOperationException e) {
modelMap.put("success", false);
modelMap.put("errMsg", e.getMessage());
} catch (IOException e) {
modelMap.put("success", false);
modelMap.put("errMsg", e.getMessage());
}
return modelMap;
} else {
modelMap.put("success", false);
modelMap.put("errMsg", "请输入店铺信息");
return modelMap;
}
}
3、结果处理
①结果类型封装enum
package com.imooc.o2o.enums;
public enum ShopStateEnum {
CHECK(0, "审核中"), OFFLINE(-1, "非法店铺"), SUCCESS(1, "操作成功"), PASS(2, "通过认证"), INNER_ERROR(-1001,
"内部系统错误"), NULL_SHOPID(-1002, "ShopId为空"),NULL_SHOP(-1003, "shop信息为空");
private int state;
private String stateInfo;
private ShopStateEnum(int state, String stateInfo) {
this.state = state;
this.stateInfo = stateInfo;
}
/**
* 依据传入的state返回相应的enum值
*/
public static ShopStateEnum stateOf(int state) {
for (ShopStateEnum stateEnum : values()) {
if (stateEnum.getState() == state) {
return stateEnum;
}
}
return null;
}
public int getState() {
return state;
}
public String getStateInfo() {
return stateInfo;
}
}
②结果返回对象封装
package com.imooc.o2o.dto;
import java.util.List;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.enums.ShopStateEnum;
public class ShopExecution {
// 结果状态
private int state;
// 状态标识
private String stateInfo;
// 店铺数量
private int count;
// 操作的shop(增删改店铺的时候用到)
private Shop shop;
// shop列表(查询店铺列表的时候使用)
private List<Shop> shopList;
public ShopExecution() {
}
// 店铺操作失败的时候使用的构造器
public ShopExecution(ShopStateEnum stateEnum) {
this.state = stateEnum.getState();
this.stateInfo = stateEnum.getStateInfo();
}
// 店铺操作成功的时候使用的构造器
public ShopExecution(ShopStateEnum stateEnum, Shop shop) {
this.state = stateEnum.getState();
this.stateInfo = stateEnum.getStateInfo();
this.shop = shop;
}
// 店铺操作成功的时候使用的构造器
public ShopExecution(ShopStateEnum stateEnum, List<Shop> shopList) {
this.state = stateEnum.getState();
this.stateInfo = stateEnum.getStateInfo();
this.shopList = shopList;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getStateInfo() {
return stateInfo;
}
public void setStateInfo(String stateInfo) {
this.stateInfo = stateInfo;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public Shop getShop() {
return shop;
}
public void setShop(Shop shop) {
this.shop = shop;
}
public List<Shop> getShopList() {
return shopList;
}
public void setShopList(List<Shop> shopList) {
this.shopList = shopList;
}
}
③操作类使用封装的对象
@Override
@Transactional
public ShopExecution modifyShop(Shop shop, ImageHolder thumbnail) throws ShopOperationException {
if (shop == null || shop.getShopId() == null) {
return new ShopExecution(ShopStateEnum.NULL_SHOP);
} else {
// 1.判断是否需要处理图片
try {
if (thumbnail.getImage() != null && thumbnail.getImageName() != null
&& !"".equals(thumbnail.getImageName())) {
Shop tempShop = shopDao.queryByShopId(shop.getShopId());
if (tempShop.getShopImg() != null) {
ImageUtil.deleteFileOrPath(tempShop.getShopImg());
}
addShopImg(shop, thumbnail);
}
// 2.更新店铺信息
shop.setLastEditTime(new Date());
int effectedNum = shopDao.updateShop(shop);
if (effectedNum <= 0) {
return new ShopExecution(ShopStateEnum.INNER_ERROR);
} else {
shop = shopDao.queryByShopId(shop.getShopId());
return new ShopExecution(ShopStateEnum.SUCCESS, shop);
}
} catch (Exception e) {
throw new ShopOperationException("modifyShop error:" + e.getMessage());
}
}
}
三、当发现上传的内容并没有被接收的情况,需要检查一下spring-web.xml中配置是否配置了文件上传解析器
1、commons-fileupload对应的jar要引入
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
2、文件上传解析器
<!-- 文件上传解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<!-- 1024 * 1024 * 20 = 20M -->
<property name="maxUploadSize" value="20971520"></property>
<property name="maxInMemorySize" value="20971520"></property>
</bean>
三A、批量操作前后端
1、前端依据后端实体类名封装list数据
//点击提交时,获取class名为temp的所有数据封装成集合,再对集合进行遍历,将数据装载到对象中,再装在list集合中
$('#submit').click(function() {
var tempArr = $('.temp');
var productCategoryList = [];
tempArr.map(function(index, item) {
var tempObj = {};
tempObj.productCategoryName = $(item).find('.category').val();
tempObj.priority = $(item).find('.priority').val();
if (tempObj.productCategoryName && tempObj.priority) {
productCategoryList.push(tempObj);
}
});
2、后端接收前端传来的list集合
需使用@RequestBody修饰参数才可以接收到
@RequestMapping(value = "/addproductcategorys", method = RequestMethod.POST)
@ResponseBody
private Map<String, Object> addProductCategorys(@RequestBody List<ProductCategory> productCategoryList,
HttpServletRequest request) {
Map<String, Object> modelMap = new HashMap<String, Object>();
Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
for (ProductCategory pc : productCategoryList) {
pc.setShopId(currentShop.getShopId());
}
if (productCategoryList != null && productCategoryList.size() > 0) {
try {
ProductCategoryExecution pe = productCategoryService.batchAddProductCategory(productCategoryList);
if (pe.getState() == ProductCategoryStateEnum.SUCCESS.getState()) {
modelMap.put("success", true);
} else {
modelMap.put("success", false);
modelMap.put("errMsg", pe.getStateInfo());
}
} catch (ProductCategoryOperationException e) {
modelMap.put("success", false);
modelMap.put("errMsg", e.toString());
return modelMap;
}
} else {
modelMap.put("success", false);
modelMap.put("errMsg", "请至少输入一个商品类别");
}
return modelMap;
}