使用 Spring中MultipartHttpServletRequest实现文件上传
一、上传对表单的要求
1) 表单的提交方式 :"method=post"
2) 表单的类型 :enctype="multipart/form-data"
3) 上传表单的文件项:xx" /> //其中名字是必须要的
二.上传的一般步骤
1.将request转化为MultipartHttpServletRequest multipartRequest= (MultipartHttpServletRequest)(request);
原理是:使用spring的CommosMultipartResolver 配置MultipartResolver 用于文件上传,DispatcherServlet 将调用 MultipartResolver 的 isMultipart(request) 方法检查当前 Web 请求是否为 multipart类型。如果是,DispatcherServlet 将调用 MultipartResolver 的 resolveMultipart(request) 方法,对原始 request 进行装饰,并返回一个 MultipartHttpServletRequest 供后继处理流程使用(最初的 HttpServletRequest 被偷梁换柱成了 MultipartHttpServletRequest),否则,直接返回最初的 HttpServletRequest。
获取文件
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; //将request转化为MultipartHttpServletRequest
MultipartFile multipartFile = multipartRequest.getFile("upload");//获取文件
InputStream is = multipartFile.getInputStream();//获取图片的文件流
String uploadContentType = multipartFile.getOriginalFilename();//获取文件的格式
3.对图片进行处理(压缩图片),并输出到指定目录
4.在数据库中保存图片的路径名imgDir+imgName
jsp页面代码
<%@ page language="java" pageEncoding="UTF-8"%>
<%@include file="/include.jsp"%>
<%@page import="java.util.Date"%>
当前功能:期刊章节管理 > 新增电子院报章节<%-- 1 图文新闻 --%>带 *号为必填项 * 标题: 封面图片: 尺寸:520*320 px 文件大小:100KB以内,文件格式:jpg,jpeg,gif,bmp,png <%-- --%>图片预览 ![]()
* 内容:
java 后台代码
controller
@Autowired
private Executor threadPoolTaskExecutor;
/***后台添加电子院报章节内容* * */@RequestMapping(value = "/m/periodicals/addContentDo")public void addContentDo(@ModelAttribute PeriodicalsChapter periodicalsChapter,Model model,HttpServletRequest request,HttpServletResponse response){Map map = new HashMap();InputStream is = null;Gson gson = new Gson();try{MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; MultipartFile multipartFile = multipartRequest.getFile("upload");String uploadContentType = multipartFile.getOriginalFilename();if(multipartFile != null && multipartFile.getSize() != 0){String expandedName = CommonUtil.checkImg(uploadContentType);if(expandedName.equals("")){map.put("resultCode", 3);map.put("resultMsg", "文件格式不正确(必须为.jpg/.gif/.bmp/.png文件)!");String jsonStr = gson.toJson(map);AjaxUtil.ajaxHtml(jsonStr, response);return ;}String imgName = System.currentTimeMillis() + "_" + ((int) (Math.random() * 900) + 100) + "." + expandedName;is = multipartFile.getInputStream();threadPoolTaskExecutor.execute(new ImageCompressionTask(is, imgName, 520, 320));periodicalsChapter.setTopThumbUrl(CommonUtil.getFolder(imgName));}//压缩图片 periodicalsChapter.setCreateTime(new Date().getTime());//获取时间periodicalsChapter.setTitle(periodicalsChapter.getTitle());periodicalsChapter.setContent(periodicalsChapter.getContent());periodicalsChapter.setParentId(periodicalsChapter.getParentId());//保存if(periodicalsChapterService.addPeriodicalsChapter(periodicalsChapter)){ map.put("resultCode", 0);map.put("resultMsg", "发布成功");String jsonStr = gson.toJson(map);AjaxUtil.ajaxHtml(jsonStr, response);return ;}else{map.put("resultCode", 1);map.put("resultMsg", "发布失败");String jsonStr = gson.toJson(map);AjaxUtil.ajaxHtml(jsonStr, response);}}catch(Exception e){logger.error("保存异常",e);map.put("resultCode", 1);map.put("resultMsg", "发布失败");String jsonStr = gson.toJson(map);AjaxUtil.ajaxHtml(jsonStr, response);}} 1. CommonUti类的 checkImg的方法,检查文件的格式
package com.rmyy.web.common;import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;import javax.imageio.ImageIO;import org.apache.commons.fileupload.disk.DiskFileItem;
import org.springframework.ui.ModelMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;import com.rmyy.web.model.Channel;
import com.rmyy.web.util.DateUtil;
import com.rmyy.web.util.PropertyFileUtil;public class CommonUtil {public static String getFolder(String imgName) {// 图片上下文String imgContext = PropertyFileUtil.get("imgContext");String dateStr = DateUtil.getDate();String imgDir = imgContext + "/" + dateStr + "/";return imgDir+imgName;}public static String checkImg(String uploadContentType){String expandedName = "";if (uploadContentType.endsWith(".jpg") || uploadContentType.endsWith(".JPG")) {// IE6上传jpg图片的headimageContentType是image/pjpeg,而IE9以及火狐上传的jpg图片是image/jpegexpandedName = "jpg";} else if (uploadContentType.endsWith(".png") || uploadContentType.endsWith(".PNG")) {// IE6上传的png图片的headimageContentType是"image/x-png"expandedName = "png";} else if (uploadContentType.endsWith(".gif")) {expandedName = "gif";} else if (uploadContentType.endsWith(".bmp")) {expandedName = "bmp";}return expandedName;}// 校验文件尺寸跟大小public static String checkFileImg(MultipartFile file,String photoSizeStr,String photoWidthStr,String photoHeightStr) throws IOException {int photoSize = photoSizeStr!=null?Integer.parseInt(photoSizeStr):0;int photoWidth = photoWidthStr!=null?Integer.parseInt(photoWidthStr):0;int photoHeight = photoHeightStr!=null?Integer.parseInt(photoHeightStr):0;CommonsMultipartFile cf= (CommonsMultipartFile)file;String result = "";String tip = "请上传图片尺寸为"+photoWidth+"*"+photoHeight+"!";BufferedImage image =ImageIO.read(cf.getInputStream());//BufferedImage image = ImageIO.read(f);if (file.getSize() > photoSize * 1024) {result = "文件大小不得大于" + photoSize + "kb!";return result;}if (image.getWidth() < (photoWidth) || image.getWidth() > (photoWidth + 20)) {return tip;}if (image.getHeight() < (photoHeight) || image.getHeight() > (photoHeight + 20)) {return tip;}return null;}}
2.图片压缩
package com.rmyy.web.common.task;import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;import javax.imageio.ImageIO;import org.apache.log4j.Logger;import com.rmyy.web.common.CommonUtil;
import com.rmyy.web.util.DateUtil;
import com.rmyy.web.util.ImageUtils;
import com.rmyy.web.util.PropertyFileUtil;public class ImageCompressionTask implements Runnable{protected static Logger logger = Logger.getLogger(ImageCompressionTask.class);private InputStream is;private int width;private int height;private String fileName;/*** 初始化参数* @param file 图片* @param id ID* @param type 图片分类1为商家管理图片2为产品分类图片* @param fileName 图片名称* @param width 高* @param height 宽*/public ImageCompressionTask(InputStream is,String fileName,int width,int height){this.is = is;this.width = width;this.height = height;this.fileName = fileName;}public void run() {try{this.compressPic();}catch(Exception e){logger.error("生成压缩图失败! " ,e);} }/*** 图片压缩* @return*/private String compressPic() throws Exception {String rootPath = PropertyFileUtil.get("imgPath");String path = getFolder(rootPath); //根路径下的子目录String urlPath = path + fileName;BufferedImage buffImg;FileOutputStream output = null;try {String extentionName = "";if(fileName.lastIndexOf(".") != -1){extentionName = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();}extentionName = extentionName.toLowerCase(); //没有扩展名的urlbuffImg = ImageIO.read(is);if(buffImg == null){return null;}BufferedImage compressPic = ImageUtils.compressPicMin(buffImg, width, height);//图片等比缩放if(compressPic != null){ //图片已压缩output = new FileOutputStream(urlPath);ImageUtils.write(compressPic, extentionName, output);//图片输出}}finally {if(output != null){try {output.close();} catch (IOException e) {e.printStackTrace();}}if(is != null){is.close();}}return "";}//保存路径获取private String getFolder(String rootPath) {// 图片上下文String imgContext = PropertyFileUtil.get("imgContext");String dateStr = DateUtil.getDate();String imgDir = imgContext + "/" + dateStr + "/";String path = rootPath + imgDir;File dir = new File(path);if (!dir.exists()) {try {dir.mkdirs();} catch (Exception e) {return "";}}return path;}public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public static Logger getLogger() {return logger;}public static void setLogger(Logger logger) {ImageCompressionTask.logger = logger;}public static void main(String args[]){String abc = "abc";String ab2 = "abc";System.out.print(abc==ab2);}
}
3.图片等比缩放,先要设置宽和高
package com.rmyy.web.util;import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;import javax.imageio.ImageIO;import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** Description: 图片工具类** @author KangWei* @Date 11-2-23*/
public class ImageUtils {private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);/**1111* 将图片写入输出流** @param image* BufferedImage 对象* @param format* 输出格式* @param output* 输出流* @throws java.io.IOException* IO异常*/public static void write(BufferedImage image, String format,OutputStream output) throws IOException {ImageIO.write(image, format, output);}/**111* 图片等比缩放,先要设置宽和高** @param image* @param* @throws java.io.IOException*/public static BufferedImage compressPicMin(BufferedImage image,int outputWidth, int outputHeight) throws IOException {if (image == null) {return null;}if (image.getWidth(null) < outputWidth&& image.getHeight(null) < outputHeight) {return image;}int newWidth;int newHeight;// 为等比缩放计算输出的图片宽度及高度double rate1 = ((double) image.getWidth(null)) / (double) outputWidth;double rate2 = ((double) image.getHeight(null)) / (double) outputHeight;// 根据缩放比率大的进行缩放控制double rate = rate1 < rate2 ? rate1 : rate2;newWidth = (int) (((double) image.getWidth(null)) / rate);newHeight = (int) (((double) image.getHeight(null)) / rate);BufferedImage tag = new BufferedImage(newWidth, newHeight,BufferedImage.TYPE_INT_RGB);/** Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢*/tag.getGraphics().drawImage(image.getScaledInstance(newWidth, newHeight,Image.SCALE_SMOOTH), 0, 0, null);return tag;}}
4.系统性工具类
package com.rmyy.web.util;import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;import org.apache.log4j.Logger;/*** 系统属性工具类* * @author HenryYan*/
public class PropertyFileUtil {private static Properties config = null;private static Logger logger = Logger.getLogger(PropertyFileUtil.class);static {InputStream in = PropertyFileUtil.class.getClassLoader().getResourceAsStream("application.properties");config = new Properties();try {config.load(in);in.close();} catch (IOException e) {logger.error("加载系统参数配置异常========", e);}}/*** 根据key 得到value* @param key* @return*/public static String get(String key) {try {String value = config.getProperty(key);return value;} catch (Exception e) {logger.error("系统参数配置错误========", e);return null;}}
}