SSM项目(五) 功能实现 -- 10 . 商品类别下拉选项 -- 监听器实现、11. 上传文件 --ajax异步上传并回显 -- springMVC组件、12 . 新增商品功能、13. 更新商品

文章目录

10 . 商品类别下拉选项实现 – 监听器实现(自动查询并存入全局对象中)

10.1 业务逻辑层 – 实现获取所有类别数据

创建ProductTypeService接口,定义获取所有类别数据方法getAll

package com.yanyu.service;
package ...

public interface ProductTypeService {
    List<ProductType> getAll();
}

创建ProductTypeServiceImpl实现接口的所有类别数据方法getAll

package com.yanyu.service.impl;

import ...

@Service("ProductTypeServiceImpl")
public class ProductTypeServiceImpl implements ProductTypeService {
    //数据访问层对象
    @Autowired
    ProductTypeMapper productTypeMapper;

    @Override
    public List<ProductType> getAll() {
        return productTypeMapper.selectByExample(new ProductTypeExample());
    }

}

10.2 通过监听器自动查询并存入全局对象中

spring容器的注册是通过监听器,与该对象是同一个监听器,无法确定谁先创建,所以无法使用spring的自动装配,需手动从Spring容器取出ProductTypeServiceImpl对象

package com.yanyu.listener;

import ...

@WebListener
public class ProductTypeListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //手动从Spring容器取出ProductTypeServiceImpl对象
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext_*.xml");
        ProductTypeService productTypeService = (ProductTypeService) context.getBean("ProductTypeServiceImpl");
        List<ProductType> typeList = productTypeService.getAll();

        //放入全局作用域中
        sce.getServletContext().setAttribute("typeList",typeList);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }
}

10.3 前端下拉框显示类别

<tr>
	<td class="one">类别</td>
	<td>
		<select name="typeId">
		    <!--typeList后端传输的商品类别数据-->
			<c:forEach items="${typeList}" var="type">
				<option value="${type.typeId}">${type.typeName}</option>
			</c:forEach>
		</select>
	</td>
</tr>

11. 上传文件 --ajax异步上传并回显 – springMVC组件

11.1 前端上传图片

文件选择

<tr>
	<td class="three">图片介绍</td>
	<!--ajax接收返回的图片位置并加载到imgDiv中-->
    <td> <br><div id="imgDiv" style="display:block; width: 40px; height: 50px;"></div><br><br><br><br>
    <!--选择文件,触发点击事件将文件传给Ajax异步上传-->
    <input type="file" id="pimage" name="pimage" onchange="fileChange()" >
        <span id="imgName" ></span><br>

    </td>

Ajax异步提交事件 – 采用ajaxfileupload.js文件(封装ajax异步上传的功能)

<!-- 引入ajaxfileupload.js-->
<script type="text/javascript" src="${pageContext.request.contextPath }/js/ajaxfileupload.js"></script>

<script type="text/javascript">
    function fileChange(){//注意:此处不能使用jQuery中的change事件,因此仅触发一次,因此使用标签的:onchange属性
        $.ajaxFileUpload({
            url: '/prod/ajaxImg.action',//用于文件上传的服务器端请求地址
            secureuri: false,//是否需要安全协议一般设置为false
            fileElementId: 'pimage',//文件上传控件的id属性  <input type="file" id="pimage" name="pimage" />
            dataType: 'json',//返回值类型 一般设置为json
            success: function(obj) //服务器成功响应处理函数
            {
                $("#imgDiv").empty();  //清空原有数据
                //创建img 标签对象
                var imgObj = $("<img>");
                //给img标签对象追加属性
                imgObj.attr("src","/image_big/"+obj.imgurl);
                imgObj.attr("width","100px");
                imgObj.attr("height","100px");
                //将图片img标签追加到imgDiv末尾
                $("#imgDiv").append(imgObj);
            },
            error: function (e)//服务器响应失败处理函数
            {
                alert(e.message);
            }
        });
    }
</script>

11.2 在ProductInfoAction中添加异步Ajax文件上传处理

Ajax文件上传处理并返回含图片位置的json对象用于回显图片

//异步Ajax文件上传处理
@ResponseBody
@RequestMapping("/ajaxImg")
//pimage与前台上传的name值一样
public Object ajaxImg(MultipartFile pimage,HttpServletRequest request){
    //生成文件名和后缀,通过FileNameUtil工具类将前台上传的文件名通过UUID重新生成,防止重复
    String uuidFileName = FileNameUtil.getUUIDFileName()+FileNameUtil.getFileType(pimage.getOriginalFilename());
    //存取路径  -- 完整的项目本地路径
    String path = request.getServletContext().getRealPath("/image_big");
    //存储  File.separator -> \
    try {
        pimage.transferTo(new File(path+File.separator+uuidFileName));
    } catch (IOException e) {
        e.printStackTrace();
    }

    //返回josn对象,包含图片路径,
    String s = "{\"imgurl\":\""+uuidFileName+"\"}";
    return s;
}

FileNameUtil工具类 – 用于UUID文件名防止重复

package com.yanyu.utils;

import java.util.UUID;

public class FileNameUtil {
	//根据UUID生成文件名
	public static String getUUIDFileName() {
		UUID uuid = UUID.randomUUID();
		return uuid.toString().replace("-", "");
	}
	//从请求头中提取文件名和类型
	public static String getRealFileName(String context) {
		// Content-Disposition: form-data; name="myfile"; filename="a_left.jpg"
		int index = context.lastIndexOf("=");
		String filename = context.substring(index + 2, context.length() - 1);
		return filename;
	}
	//根据给定的文件名和后缀截取文件名
	public static String getFileType(String fileName){
		//9527s.jpg
		int index = fileName.lastIndexOf(".");
		return fileName.substring(index);
	}
}

12 . 新增商品功能

12.1 业务逻辑层 – 实现新增商品

ProductInfoService接口添加save方法

    //新增商品
    int save(ProductInfo info);

ProductInfoServiceImpl实现类实现save

    @Override
    public int save(ProductInfo info) {

        return productInfoMapper.insert(info);
    }

12.2 界面控制层 – ProductInfoAtion中,添加save完成添加,返回初始页

    @RequestMapping("/save")
    public String save(ProductInfo info,HttpServletRequest request){
        //文件由ajaxImg方法上传,将uuidFileName设置为全局变量,在此传递给数据库
        info.setpImage(uuidFileName);
        //前端提交的数据不包含时间,由后端添加
        info.setpDate(new Date());

        //num受影响行数
        int num=0;
        try {
            num = productInfoService.save(info);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(num>0){
            request.setAttribute("msg","增加成功!");
        }else{
            request.setAttribute("msg","增加失败!");
        }
        //转发到所有商品初始页
        return "forward:/prod/split.action";
    }

13. 更新商品

13.1 根据主键id查询商品,用于修改数据 - getById方法

业务逻辑层 – ProductInfoService接口添加getById方法

    //按主键id查询商品
    ProductInfo getById(int pid);

业务逻辑层 – ProductInfoServiceImpl实现类实现getById

    @Override
    public ProductInfo getById(int pid) {
        return productInfoMapper.selectByPrimaryKey(pid);
    }

界面控制层 – ProductInfoAtion中,添加one方法完成查询,返回修改页

    @RequestMapping("one")
    public String one(int pid, Model model){
        ProductInfo byId = productInfoService.getById(pid);
        model.addAttribute("prod",byId);
        //更新时可以修改图片,防止数据冲突,清除uuidFileName
        uuidFileName="";
        return "update";
    }

13.3 前端点击编辑,跳转one方法根据主键id查询所要修改的数据,回显

function one(pid) {
    location.href = "${pageContext.request.contextPath}/prod/one.action?pid=" + pid;
}

....

<button type="button" class="btn btn-info " onclick="one(${p.pId})">编辑 </button>

13.3 更新前端页面 – 主要代码

//取消时返回初始页
<script type="text/javascript">
	function myclose(ispage) {		window.location="${pageContext.request.contextPath}/admin/product/split.action";
		//window.close();
	}
</script>

<div id="table">
	<form action="${pageContext.request.contextPath}/prod/update.action" enctype="multipart/form-data" method="post" id="myform">
	    //修改根据id,所以要提交,但不修改用隐藏域
		<input type="hidden" value="${prod.pId}" name="pId">
		//用于判断是否重新上传图片
		<input type="hidden" value="${prod.pImage}" name="pImage">
		
		...
		商品名称
		商品介绍
		定价
		...

            //显示图片和异步上传
			<tr>
				<td class="one">图片介绍</td>
				<td> <br><div id="imgDiv" style="display:block; width: 40px; height: 50px;"><img src="/image_big/${prod.pImage}" width="100px" height="100px" ></div><br><br><br><br>
					<input type="file" id="pimage" name="pimage" onchange="fileChange()">
					<span id="imgName"></span><br>
				</td>
			</tr>
			...
			总数量
			...
			//取出全局中的数据,与修改商品的类别id对比,selected="selected"表示选中
			<tr>
				<td class="one">类别</td>
				<td>
					<select name="typeId">
						<c:forEach items="${typeList}" var="type">
							<option value="${type.typeId}"
									<c:if test="${type.typeId==prod.typeId}">
										selected="selected"
									</c:if>
							>${type.typeName}</option>

						</c:forEach>
					</select>
				</td>
			</tr>
				<td>
					<input type="submit" value="提交" class="btn btn-success">
				</td>
				<td>
					<input type="reset" value="取消" class="btn btn-default" onclick="myclose(1)">
				</td>
			</tr>
		</table>
	</form>
</div>

13.4 修改数据 - update方法

业务逻辑层 – ProductInfoService接口添加update方法

    //更新商品
    int update(ProductInfo info);

业务逻辑层 – ProductInfoServiceImpl实现类实现update

    @Override
    public int update(ProductInfo info) {
        return productInfoMapper.updateByPrimaryKey(info);
    }

界面控制层 – ProductInfoAtion中,添加update完成更新

    @RequestMapping("/update")
    public String update(ProductInfo info,HttpServletRequest request){
        //判断是否有重新上传的图片,若有则修改图片地址,没有不变
        if(!uuidFileName.equals("")) {
            info.setpImage(uuidFileName);
        }
        //num受影响行数
        int num=0;
        try {
            num = productInfoService.update(info);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(num>0){
            request.setAttribute("msg","更新成功!");
        }else{
            request.setAttribute("msg","更新失败!");
        }
        //转发到所有商品初始页
        return "forward:/prod/split.action";
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值