how2j.cn

相关下载
文件名 文件大小
tmall_ssh.rar 19m
使用站长秘制下载工具

6分29秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)

步骤 1 : 先运行,看到效果,再学习   
步骤 2 : 模仿和排错   
步骤 3 : 效果截图   
步骤 4 : 页面   
步骤 5 : 为空判断   
步骤 6 : CategoryService   
步骤 7 : CategoryServiceImpl   
步骤 8 : ImageUtil   
步骤 9 : CategoryAction   
步骤 10 : 中文问题   

步骤 1 :

先运行,看到效果,再学习

老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。

注: struts允许的文件默认只能允许2M 的大小,请勿上传大小超过2 M的图片。 如果希望调整上限,请通过如下教程进行:上传文件最大值
步骤 2 :

模仿和排错

在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。

推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。
这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来
这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
步骤 3 :

效果截图

如图所示,新增加的分类,就是有图片的了。
效果截图
步骤 4 :

页面

增加分类的页面是做在listCategory.jsp上的
需要注意几点:
1. form的action="admin_category_add",会导致访问CategoryAction的add()方法
2. method="post" 用于保证中文的正确提交
3. 必须有enctype="multipart/form-data",这样才能上传文件
页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@include file="../include/admin/adminHeader.jsp"%> <%@include file="../include/admin/adminNavigator.jsp"%> <script> $(function(){ $("#addForm").submit(function(){ if(!checkEmpty("name","分类名称")) return false; if(!checkEmpty("categoryPic","分类上传图片")) return false; return true; }); }); </script> <title>分类管理</title> <div class="workingArea"> <h1 class="label label-info" >分类管理</h1> <br> <br> <div class="listDataTableDiv"> <table class="table table-striped table-bordered table-hover table-condensed"> <thead> <tr class="success"> <th>ID</th> <th>图片</th> <th>分类名称</th> <th>属性管理</th> <th>产品管理</th> <th>编辑</th> <th>删除</th> </tr> </thead> <tbody> <c:forEach items="${categorys}" var="c"> <tr> <td>${c.id}</td> <td><img height="40px" src="img/category/${c.id}.jpg"></td> <td>${c.name}</td> <td><a href="admin_property_list?category.id=${c.id}"><span class="glyphicon glyphicon-th-list"></span></a></td> <td><a href="admin_product_list?category.id=${c.id}"><span class="glyphicon glyphicon-shopping-cart"></span></a></td> <td><a href="admin_category_edit?category.id=${c.id}"><span class="glyphicon glyphicon-edit"></span></a></td> <td><a deleteLink="true" href="admin_category_delete?category.id=${c.id}"><span class=" glyphicon glyphicon-trash"></span></a></td> </tr> </c:forEach> </tbody> </table> </div> <div class="pageDiv"> <%@include file="../include/admin/adminPage.jsp" %> </div> <div class="panel panel-warning addDiv"> <div class="panel-heading">新增分类</div> <div class="panel-body"> <form method="post" id="addForm" action="admin_category_add" enctype="multipart/form-data"> <table class="addTable"> <tr> <td>分类名称</td> <td><input id="name" name="category.name" type="text" class="form-control"></td> </tr> <tr> <td>分类圖片</td> <td> <input id="categoryPic" type="file" name="img" /> </td> </tr> <tr class="submitTR"> <td colspan="2" align="center"> <button type="submit" class="btn btn-success">提 交</button> </td> </tr> </table> </form> </div> </div> </div> <%@include file="../include/admin/adminFooter.jsp"%>
步骤 5 :

为空判断

对分类名称和分类图片做了为空判断,当为空的时候,不能提交

其中用到的函数checkEmpty,在adminHeader.jsp 中定义
为空判断
<script> $(function(){ $("#addForm").submit(function(){ if(!checkEmpty("name","分类名称")) return false; if(!checkEmpty("categoryPic","分类图片")) return false; return true; }); }); </script>
<script>
$(function(){
	
	$("#addForm").submit(function(){
		if(!checkEmpty("name","分类名称"))
			return false;
		if(!checkEmpty("categoryPic","分类图片"))
			return false;
		return true;
	});
});

</script>
步骤 6 :

CategoryService

修改CategoryService,在原来的基础上增加save(Category category)方法
package com.how2java.tmall.service; import java.util.List; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.util.Page; public interface CategoryService{ public List list(); public void save(Category category); public int total(); public List<Category> listByPage(Page page); }
package com.how2java.tmall.service;
import java.util.List;
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.util.Page;
public interface CategoryService{
	
	public List list();

	public void save(Category category);
	
	public int total();

	public List<Category> listByPage(Page page);
}
步骤 7 :

CategoryServiceImpl

修改CategoryServiceImpl,增加save(Category category)方法的实现。
package com.how2java.tmall.service.impl; import java.util.List; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Order; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.how2java.tmall.dao.impl.DAOImpl; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.service.CategoryService; import com.how2java.tmall.util.Page; @Service public class CategoryServiceImpl implements CategoryService { @Autowired DAOImpl dao; @Override public List list() { DetachedCriteria dc = DetachedCriteria.forClass(Category.class); dc.addOrder(Order.desc("id")); return dao.findByCriteria(dc); } @Override public int total() { String hql = "select count(*) from Category "; List<Long> l= dao.find(hql); if(l.isEmpty()) return 0; Long result= l.get(0); return result.intValue(); } @Override public List<Category> listByPage(Page page) { DetachedCriteria dc = DetachedCriteria.forClass(Category.class); dc.addOrder(Order.desc("id")); return dao.findByCriteria(dc,page.getStart(),page.getCount()); } @Override public void save(Category category) { dao.save(category); } }
步骤 8 :

ImageUtil

新增加一个ImageUtil类,提供了三个方法,在增加分类这个业务里用到了change2jpg()方法,其作用是把上传的文件,无论是bmp,jpg,png,gif都转换为真正格式的JPG文件,以确保浏览器可以正常地显示。

1. change2jpg
确保图片文件的二进制格式是jpg。
仅仅通过ImageIO.write(img, "jpg", file);不足以保证转换出来的jpg文件显示正常。这段转换代码,可以确保转换后jpg的图片显示正常,而不会出现暗红色( 有一定几率出现)。 我也是度娘上抄的,哈哈哈~ 不过找了很多代码哦,才找到这一段能真正生效,而且不会发生错误的。

2. 后两种resizeImage用于改变图片大小,在上传产品图片的时候会用到。 这里不展开,到时候再讲
package com.how2java.tmall.util; import java.awt.Image; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; import java.awt.image.DirectColorModel; import java.awt.image.PixelGrabber; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class ImageUtil { public static BufferedImage change2jpg(File f) { try { java.awt.Image i = Toolkit.getDefaultToolkit().createImage(f.getAbsolutePath()); PixelGrabber pg = new PixelGrabber(i, 0, 0, -1, -1, true); pg.grabPixels(); int width = pg.getWidth(), height = pg.getHeight(); final int[] RGB_MASKS = { 0xFF0000, 0xFF00, 0xFF }; final ColorModel RGB_OPAQUE = new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]); DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight()); WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null); BufferedImage img = new BufferedImage(RGB_OPAQUE, raster, false, null); return img; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } public static void resizeImage(File srcFile, int width,int height, File destFile) { try { Image i = ImageIO.read(srcFile); i = resizeImage(i, width, height); ImageIO.write((RenderedImage) i, "jpg", destFile); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Image resizeImage(Image srcImage, int width, int height) { try { BufferedImage buffImg = null; buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); buffImg.getGraphics().drawImage(srcImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null); return buffImg; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
步骤 9 :

CategoryAction

修改CategoryAction以支持增加分类的操作,做了如下改动
1. 新增属性Category category,以接受浏览器传递过来的分类名称
2. 新增属性File image,以接受浏览器提交的图片文件
3. 新增加Result:listCategoryPage, 用于客户端跳转到页面admin_category_list.
4. 新增加方法add,以映射浏览器的访问地址:/admin_category_add
4.1 把category对象保存到数据库
4.2 根据category对象保存到数据库之后所获取的id, 计算其对应的图片文件的名称: id.jpg
4.3 然后把 Struts 接受到的浏览器上传的临时文件,复制到 id.jpg。
4.4 借助ImageUtil把这个文件的格式转换为真正的JPG格式。
4.5 通过listCategoryPage,客户端跳转到admin_category_list 路径

关于4.3的临时文件上传有不理解的地方,请参考:Struts 文件上传教程
package com.how2java.tmall.action; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.List; import javax.imageio.ImageIO; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.springframework.beans.factory.annotation.Autowired; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.service.CategoryService; import com.how2java.tmall.util.ImageUtil; import com.how2java.tmall.util.Page; @Namespace("/") @ParentPackage("basicstruts") @Results( { /*分类管理*/ @Result(name="listCategory", location="/admin/listCategory.jsp"), @Result(name="listCategoryPage", type = "redirect", location="/admin_category_list"), }) public class CategoryAction { @Autowired CategoryService categoryService; List<Category> categorys; Category category; File img; Page page; @Action("admin_category_list") public String list() { if(page==null) page = new Page(); int total = categoryService.total(); page.setTotal(total); categorys = categoryService.listByPage(page); return "listCategory"; } @Action("admin_category_add") public String add() { categoryService.save(category); File imageFolder= new File(ServletActionContext.getServletContext().getRealPath("img/category")); File file = new File(imageFolder,category.getId()+".jpg"); try { FileUtils.copyFile(img, file); BufferedImage img = ImageUtil.change2jpg(file); ImageIO.write(img, "jpg", file); } catch (IOException e) { e.printStackTrace(); } return "listCategoryPage"; } public List<Category> getCategorys() { return categorys; } public void setCategorys(List<Category> categorys) { this.categorys = categorys; } public Page getPage() { return page; } public void setPage(Page page) { this.page = page; } public Category getCategory() { return category; } public void setCategory(Category category) { this.category = category; } public File getImg() { return img; } public void setImg(File img) { this.img = img; } }
步骤 10 :

中文问题

中文问题,由web.xml中的过滤器和struts.xml中的编码设置来设置
web.xml:

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>


struts.xml:

<constant name="struts.i18n.encoding" value="UTF-8"></constant>


其他的配合动作
1. 在jsp中要加上

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>

其中contentType="text/html; charset=UTF-8"的作用是告诉浏览器提交数据的时候,使用UTF-8编码

2. 在form里method="post" 才能正确提交中文
参考: 使用Filter处理中文问题Struts中处理中文问题
<web-app> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.i18n.encoding" value="UTF-8"></constant> <constant name="struts.objectFactory" value="spring"/> <package name="basicstruts" extends="struts-default"> </package> </struts>


HOW2J公众号,关注后实时获知布最新的教程和优惠活动,谢谢。


关于 实践项目-天猫整站SSH-增加 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 620943819
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: http://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图