ajaxfileupload+Jqgrid实现异步文件上传

1.环境搭建

引入ajaxfileupload.js文件(ajaxfileupload.js是基于jQuery编写的插件,故此也需要引入jQuery文件)

    <script type="text/javascript" src="${pageContext.request.contextPath}/statics/jqgrid/js/ajaxfileupload.js"></script>

引入jqgrid相关文件

    <!--引入样式文件-->
    <link rel="stylesheet" href="${pageContext.request.contextPath}/statics/boot/css/bootstrap.css" type="text/css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/statics/jqgrid/css/trirand/ui.jqgrid-bootstrap.css" type="text/css">
    <!--引入js功能文件-->
    <script src="${pageContext.request.contextPath}/statics/boot/js/jquery-2.2.1.min.js" type="text/javascript"></script>
    <script src="${pageContext.request.contextPath}/statics/boot/js/bootstrap.min.js" type="text/javascript"></script>
    <script src="${pageContext.request.contextPath}/statics/jqgrid/js/trirand/i18n/grid.locale-cn.js" type="text/javascript"></script>
    <script src="${pageContext.request.contextPath}/statics/jqgrid/js/trirand/jquery.jqGrid.min.js" type="text/javascript"></script>

2.页面代码编写

下例为上传封面cover

	<table id="banner-table"></table>
	<div id="banner-pager"></div>
	
	<script>
        $(function () {
            //展示供应商信息
            $("#banner-table").jqGrid({
                // 整合使用bootstrap样式的属性
                styleUI:'Bootstrap',
                url:'${pageContext.request.contextPath}/banner/findBannerByPage',
                editurl:'${pageContext.request.contextPath}/banner/operBanner',
                caption : "轮播图详细信息",   //设置表格名
                datatype:'json',
                colNames:['名称','封面','描述','创建日期','状态','最后修改时间'],
                // 开启表格编辑模式
                cellEdit:true,
                colModel:[
                    // {name:'id',align:'center'},
                    {name:'title',align:'center',editable:true},
                    {
                        name:'cover',
                        formatter:function(value,options,row){
                            return '<img src="${pageContext.request.contextPath}/view/banner/image/'+row.cover+'"  width="150px" height="60px"/>';
                        },
                     	// index:'cover', 相当于索引id,唯一标识(没有用到)
                        align:'center',
                        editable:true,
                        //editoptions: {enctype: "multipart/form-data"},
                        //代表编辑后表单有文件类型数据传输,(没有用到)
                        edittype:'file', //设置后,编辑时此选项为文件类型

                    },
                    {name:'description',align:'center',editable:true},
                    {
                        name:'createDate',
                        align:'center',
                        //日期格式化
                        formatter:"date",    
                        formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d'}
                    },
                    {name:'status',align:'center',editable:true},
                    {
                        name:'lastUpdateDate',
                        align:'center',
                        //日期格式化
                        formatter:"date",
                        formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d'}
                    },
                ],

                //数据表格是否自适应父容器的大小宽度
                autowidth:true,
                //显示行号
                rownumbers:true,
                //在第一列前加入复选框
                multiselect:true,
                //设置高度
                height:400,
                //添加分页
                //使用分页工具栏
                pager:'#banner-pager',
                rowList:[5,10,15],
                rowNum:10,
                page:1,
                //显示总记录数
                viewrecords:true,
            }).navGrid('#banner-pager',{edit : true,add : true,del : true,search:false},
                //.navGrid("工具栏id",{显示内容},{修改操作},{添加操作}),{删除操作}
				//注意注意!!!!!!!!!!!顺序一定不能错

                //=====控制修改操作====================================
                {
                    //修改后关闭编辑框
                    closeAfterEdit:true,
                },


                //=====控制添加操作======================================
                {
                    //添加后关闭编辑框
                    closeAfterAdd: true,
                    //提交后:
                    //执行完添加操作后这里返回了一个Map<String,Object>
                    //里面存有刚添加数据的ID和状态码  {data:id;code:200/404/500...}
                    afterSubmit:function (response) {
                        var id = response.responseJSON.data;   //返回的id
                        var code = response.responseJSON.code; //返回的状态码

                        if(code==200) {
                            $.ajaxFileUpload({
                                fileElementId: "cover",    //需要上传的文件域的ID,即<input type="file">的ID。
                                url: "${pageContext.request.contextPath}/banner/upload",     //后台方法的路径
                                type: 'post',              //当要提交自定义参数时,这个参数要设置成post
                                data: {id: id},              //发送请求时传递的参数(数据)
                                //dataType: 'json',          //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。不要加它了,太恶心了!!
                                //   secureuri: false,        //是否启用安全提交,默认为false。
                                //   async : true,            //是否是异步
                                success:function() {
                                    alert("成功!");
                                    $("#banner-table").trigger("reloadGrid");
                                }
                            })
                            return "true";
                            //注意注意!!!!!!!这个一定不能少,随便返回一个字符串即可
                            //ajaxFileUpload需要一个返回值,否则上述设置的修改后关闭编辑框不会生效
                        }
                    }
                }
            );
        })
    </script>

3.后台代码编写

@RequestMapping("banner")
@RestController
public class BannerController extends BaseApiService{

    @Autowired
    private BannerService bannerService;

    @RequestMapping("findBannerByPage")
    /**
     * page:查询页数
     * rows:每页显示条数
     * searchField: 查询条件
     * searchString: 查询内容
     * 加入分页工具栏后,远程响应json数据格式为:
     * {"rows":[当前页结果(list)],"page":"当前页","total":"总页数","records":"总条数"}
     */
    public Map<String,Object> findBannerByPage(Integer page, Integer rows,
                                               String searchField, String searchString){
        //创建结果集
        List<Banner> bannerList = null;
        Integer records = 0;
        HashMap<String, Object> map = new HashMap<>();
        Integer total = 0;


        //判断是否为模糊查询
        if(searchField==null){
            //查询集合
            bannerList = bannerService.findAllByPage(page, rows);
            //查询总条数
            records = bannerService.getCount();
            //计算总页数
            total = records%rows==0?records/rows:records/rows+1;
        }else {
            //查询集合
            bannerList = bannerService.findAllByPageBySearch(page, rows,searchField,searchString);
            //查询总条数
            records = bannerService.getCountBySearch(searchField,searchString);
            //计算总页数
            total = records%rows==0?records/rows:records/rows+1;
        }
        //封装的一个map集合
        return setPageMap(bannerList,page,total,records);
    }

    @RequestMapping("operBanner")
    public Map<String,Object> operBanner(Banner banner,MultipartFile cover,String id,String oper) {
        //添加
        if("add".equals(oper)){
            String i = bannerService.add(banner);
            return setResultSuccessData(i);
        }

        //修改
        if("edit".equals(oper)){

            String i = bannerService.update(banner);
            return setResultSuccessData(i);
        }

        //删除
        if("del".equals(oper)){
            String[] ids = id.split(",");
            for (String i : ids) {
                bannerService.delete(i);
            }
        }

        return null;

    }

    @RequestMapping("upload")
    public void upload(MultipartFile cover, String id, HttpSession session) throws IOException {

        System.out.println("id===="+id);
        System.out.println("cover===="+cover.getOriginalFilename());
        if ("".equals(cover.getOriginalFilename())) throw new RuntimeException("文件为空");
        //获取文件上传路径
        String realPath = session.getServletContext().getRealPath("/view/banner/image");
        //文件上传
        cover.transferTo(new File(realPath,cover.getOriginalFilename()));

        //修改数据库图片中的路径
        Banner banner = new Banner();
        banner.setId(id).setCover(cover.getOriginalFilename());
        bannerService.update(banner);

        //return "success";
    }

}

4.流程介绍

如上例,主要实现使用jqgrid添加一条数据时,该数据为图片类型,展示时要求展示图片。
方案:

a).先将普通字段数据入库,添加完成后返回一个Map<String,Object>类型集合,存入数据data=刚添加数据的id,(code=200/500/404…状态码)。

b).前台在控制添加数据(后面介绍)后加入事件,afterSubmit代表调教数据之后触发。然后使用ajaxFileUpload发送ajax请求上传文件。

	afterSubmit:function (response) {
	var id = response.responseJSON.data;   //返回的id
	var code = response.responseJSON.code; //返回的状态码
	...
	}
	$.ajaxFileUpload({
	   fileElementId: "cover",    //需要上传的文件域的ID,即<input type="file">的ID。
	   url: "${pageContext.request.contextPath}/banner/upload",     //后台方法的路径
	   type: 'post',              //当要提交自定义参数时,这个参数要设置成post
	   data: {id: id},              //发送请求时传递的参数(数据)
	   dataType: 'json',          //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
	   //   secureuri: false,        //是否启用安全提交,默认为false。
	   //   async : true,            //是否是异步
	   success:function() {
	       //alert("成功!");
	       $("#banner-table").trigger("reloadGrid");
	   }
	})

c).在控制上传文件的controller里进行文件上传然后修改数据库中该条数据的图片路径。

	   if ("".equals(cover.getOriginalFilename())) throw new RuntimeException("文件为空");
       //获取文件上传路径
       String realPath = session.getServletContext().getRealPath("/view/banner/image");
       //文件上传
       cover.transferTo(new File(realPath,cover.getOriginalFilename()));

       //修改数据库图片中的路径
       Banner banner = new Banner();
       banner.setId(id).setCover(cover.getOriginalFilename());
       bannerService.update(banner);

       return "success";

注意事项:

  • 如果文件框内没有文件上传该字段为“”,而并非nul。
  • 在修改时如果修改图片则正常,但如果没有修改图片则会把数据库中原图片路径置空
    原因:没有文件上传该字段为“”,会直接传入实体类中以至于修改数据库。
    解决方法:如果使用通用mapper,则在service中更新数据之前判断是否为空串,如果是则置为null;如果没有使用通用mapper,则获取原始数据重新赋值即可。
	if ("".equals(banner.getCover())) banner.setCover(null);

5.注意事项

a). jqgrid中对工具栏id、工具栏展示功能设置、修改、添加、删除操作的顺序有严格要求,不可缺少或错位

	.navGrid('#banner-pager',{edit : true,add : true,del : true,search:false},{},{},{})
  //.navGrid("工具栏id",{显示内容},{修改操作},{添加操作}),{删除操作}

b). 执行ajaxfileupload请求时,需要有个返回值(任意字符串),否则修改、添加后关闭模态框(closeAfterAdd: true/closeAfterEdit: true)不会生效。

c). 修改或添加操作后刷新表格:此时是执行完文件上传之后,success函数中进行操作。一定注意,如果ajaxfileupload中加入了dataType,请一定要和后台controller中upload方法的返回值类型对应,若不对应则success中方法不会执行,默认请求失败,但不影响文件上传,但需要上传后手动刷新。
综上,还是不要加了!!!!!!!

	//服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
	dataType: 'json',          
	success:function() {
		//alert("成功!");
		$("#表格id").trigger("reloadGrid");
	}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值