步骤 1 : 先运行,看到效果,再学习 步骤 2 : 模仿和排错 步骤 3 : 效果截图 步骤 4 : 页面 步骤 5 : 为空判断 步骤 6 : CategoryService 步骤 7 : CategoryServiceImpl 步骤 8 : ImageUtil 步骤 9 : CategoryAction 步骤 10 : 中文问题
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
注: struts允许的文件默认只能允许2M 的大小,请勿上传大小超过2 M的图片。 如果希望调整上限,请通过如下教程进行:上传文件最大值
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
如图所示,新增加的分类,就是有图片的了。
增加分类的页面是做在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"%>
<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>
修改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); }
修改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);
}
}
新增加一个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;
}
}
修改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;
}
}
中文问题,由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公众号,关注后实时获知布最新的教程和优惠活动,谢谢。
![]() |