[TOC]
## 步骤 1 : 先运行,看到效果,再学习
先将完整的 spring 项目(向老师要相关资料),配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
## 步骤 2 : 模仿和排错
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较**正确答案** ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,**学习有效果,排错有效率**,可以较为明显地提升学习速度,跨过学习路上的各个槛。
## 步骤 3 : 效果
如图所示,"测试分类A" 的名称被修改为了 "测试分类B"
![](https://box.kancloud.cn/9130dff75f1e43f480ae40ce634d71d9_112x71.png)
## 步骤 4 : 编辑页面提交数据
编辑页面提交数据到admin_category_update
~~~
<form method="post" id="editForm" action="admin_category_update"
enctype="multipart/form-data">
~~~
1. method="post" 用于提交中文
2. enctype="multipart/form-data" 用于提交二进制文件
![](https://box.kancloud.cn/e6da79947f7e275c5990e9e35115a7ef_508x256.png)
## 步骤 5 : CategoryMapper.xml
增加修改的sql语句
~~~
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dodoke.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from t_category order by id desc
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select>
<select id="total" resultType="int">
select count(*) from t_category
</select>
<insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category">
insert into t_category(name) values(#{name})
</insert>
<delete id="delete">
delete from t_category where id=#{id}
</delete>
<select id="get" resultType="Category">
select * from t_category where id=#{id}
</select>
<update id="update" parameterType="Category">
update t_category set name=#{name} where id=#{id}
</update>
</mapper>
~~~
## 步骤 6 : CategoryMapper
增加update方法
~~~
package com.dodoke.tmall.mapper;
import java.util.List;
import com.dodoke.tmall.pojo.Category;
import com.dodoke.tmall.util.Page;
public interface CategoryMapper {
List<Category> list(Page page);
public int total();
void add(Category category);
void delete(int id);
Category get(int id);
void update(Category category);
}
~~~
## 步骤 7 : CategoryService
增加update方法
~~~
package com.dodoke.tmall.service;
import java.util.List;
import com.dodoke.tmall.pojo.Category;
import com.dodoke.tmall.util.Page;
public interface CategoryService {
List<Category> list(Page page);
int total();
void add(Category category);
void delete(int id);
Category get(int id);
void update(Category category);
}
~~~
## 步骤 8 : CategoryServiceImpl
增加update方法
~~~
package com.dodoke.tmall.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dodoke.tmall.mapper.CategoryMapper;
import com.dodoke.tmall.pojo.Category;
import com.dodoke.tmall.service.CategoryService;
import com.dodoke.tmall.util.Page;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List<Category> list(Page page) {
return categoryMapper.list(page);
}
@Override
public int total() {
return categoryMapper.total();
}
@Override
public void add(Category category) {
categoryMapper.add(category);
}
@Override
public void delete(int id) {
categoryMapper.delete(id);
}
@Override
public Category get(int id) {
return categoryMapper.get(id);
}
@Override
public void update(Category category) {
categoryMapper.update(category);
}
}
~~~
## 步骤 9 : CategoryController
新增update方法
1. update 方法映射路径admin_category_update的访问
* 参数 Category c接受页面提交的分类名称
* 参数 session 用于在后续获取当前应用的路径
* UploadedImageFile 用于接受上传的图片
2. 通过categoryService更新c对象
3. 首先判断是否有上传图片,如果有上传,那么通过session获取ControllerContext,再通过getRealPath定位存放分类图片的路径。
如果严格按照本教程的做法,使用idea中的tomcat部署的话,那么图片就会存放在:E:\project\tmall_ssm\target\tmall_ssm\img\category 这里
4. 根据分类id创建文件名
5. 通过UploadedImageFile 把浏览器传递过来的图片保存在上述指定的位置
6. 通过ImageUtil.change2jpg(file); 确保图片格式一定是jpg,而不仅仅是后缀名是jpg.
7. 客户端跳转到admin_category_list
~~~
package com.dodoke.tmall.controller;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import com.dodoke.tmall.pojo.Category;
import com.dodoke.tmall.service.CategoryService;
import com.dodoke.tmall.util.ImageUtil;
import com.dodoke.tmall.util.Page;
import com.dodoke.tmall.util.UploadedImageFile;
@RequestMapping("")
@Controller
public class CategoryController {
@Autowired
CategoryService categoryService;
@RequestMapping("admin_category_list")
public String list(Model model,Page page) {
List<Category> cs = categoryService.list(page);
int total = categoryService.total();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page",page);
return "admin/listCategory";
}
/**
* 新增分类
* @param c 分类对象
* @param session 用于在后续获取当前应用的路径
* @param uploadedImageFile 用于接受上传的图片
* @return 页面路径
* @throws IOException
*/
@RequestMapping("admin_category_add")
public String add(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
// 新增分类
categoryService.add(c);
// 通过session获取ControllerContext,再通过getRealPath定位存放分类图片的路径。
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
// 根据分类id创建文件名
File file = new File(imageFolder,c.getId() + ".jpg");
// 如果/img/category目录不存在,则创建该目录,否则后续保存浏览器传过来图片,会提示无法保存
if(!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
System.out.println(file);
// 通过UploadedImageFile 把浏览器传递过来的图片保存在上述指定的位置
uploadedImageFile.getImage().transferTo(file);
// 通过ImageUtil.change2jpg(file); 确保图片格式一定是jpg,而不仅仅是后缀名是jpg.
BufferedImage img = ImageUtil.change2jpg(file);
// 写入图片
ImageIO.write(img, "jpg", file);
// 客户端跳转到admin_category_list
return "redirect:/admin_category_list";
}
/**
* 删除分类
* @param id 分类id
* @param session 用于在后续获取当前应用的路径
* @return 页面路径
* @throws IOException
*/
@RequestMapping("admin_category_delete")
public String delete(int id,HttpSession session) throws IOException {
categoryService.delete(id);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,id+".jpg");
file.delete();
return "redirect:/admin_category_list";
}
/**
* 根据id,查询分类信息
* @param id 分类id
* @param model 模型
* @return 页面路径
* @throws IOException
*/
@RequestMapping("admin_category_edit")
public String edit(int id,Model model) throws IOException {
Category c= categoryService.get(id);
model.addAttribute("c", c);
return "admin/editCategory";
}
/**
* 更新分类
* @param c 接受页面提交的分类名称
* @param session 用于在后续获取当前应用的路径
* @param uploadedImageFile 用于接受上传的图片
* @return 页面路径
* @throws IOException
*/
@RequestMapping("admin_category_update")
public String update(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
// 更新分类
categoryService.update(c);
MultipartFile image = uploadedImageFile.getImage();
// 判断是否有图片上传
if(null!=image &&!image.isEmpty()){
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
// 根据分类id创建文件
File file = new File(imageFolder,c.getId()+".jpg");
// 把浏览器传递过来的图片保存在上述指定的位置
image.transferTo(file);
// 确保图片格式一定是jpg,而不仅仅是后缀名是jpg.
BufferedImage img = ImageUtil.change2jpg(file);
// 覆盖图片
ImageIO.write(img, "jpg", file);
}
// 客户端跳转到admin_category_list
return "redirect:/admin_category_list";
}
}
~~~
## 步骤 10 : 测试效果
如图所示,点击编辑按钮之后,出现分类编辑页面,更改信息,保存,访问分类信息页面。
比如将**测试分类A**更改为**测试分类B**
![](https://box.kancloud.cn/3c441e698fc6d76e376969f93c3db623_515x253.png)
![](https://box.kancloud.cn/9130dff75f1e43f480ae40ce634d71d9_112x71.png)
## 问题
1. 在有图片时选择编辑,更改了图片成功后,网页上的图片没有及时变更,这是怎么一回事?
> 有缓存,用F5多刷新几下,就能看到最新上传的分类图片了
>
2. 编辑信息,又上传一张图片,但是图片的名字始终是id+jpg。那么不会冲突吗
> 新上传的,把原来上传的图片替换了呀,所以并没有保留原图片的需求,也就谈不上冲突嘛
- 项目简介
- 功能一览
- 前台
- 后台
- 开发流程
- 需求分析-展示
- 首页
- 产品页
- 分类页
- 搜索结果页
- 购物车查看页
- 结算页
- 确认支付页
- 支付成功页
- 我的订单页
- 确认收货页
- 确认收货成功页
- 评价页
- 需求分析-交互
- 分类页排序
- 立即购买
- 加入购物车
- 调整订单项数量
- 删除订单项
- 生成订单
- 订单页功能
- 确认付款
- 确认收货
- 提交评价信息
- 登录
- 注册
- 退出
- 搜索
- 前台需求列表
- 需求分析后台
- 分类管理
- 属性管理
- 产品管理
- 产品图片管理
- 产品属性设置
- 用户管理
- 订单管理
- 后台需求列表
- 表结构设计
- 数据建模
- 表与表之间的关系
- 后台-分类管理
- 可运行的项目
- 静态资源
- JSP包含关系
- 查询
- 分页
- 增加
- 删除
- 编辑
- 修改
- 做一遍
- 重构
- 分页方式
- 分类逆向工程
- 所有逆向工程
- 后台其他页面
- 属性管理实现
- 产品管理实现
- 产品图片管理实现
- 产品属性值设置
- 用户管理实现
- 订单管理实现
- 前端
- 前台-首页
- 可运行的项目
- 静态资源
- ForeController
- home方法
- home.jsp
- homePage.jsp
- 前台-无需登录
- 注册
- 登录
- 退出
- 产品页
- 模态登录
- 分类页
- 搜索
- 前台-需要登录
- 购物流程
- 立即购买
- 结算页面
- 加入购物车
- 查看购物车页面
- 登录状态拦截器
- 其他拦截器
- 购物车页面操作
- 订单状态图
- 生成订单
- 我的订单页
- 我的订单页操作
- 评价产品
- 总结