使用struts2及xheditor实现文件、图片上传(支持拖拽上传)
用JSP实现拖拽上传文件和文件夹

用JSP实现拖拽上传文件和文件夹JSP(JavaServer Pages)是一种动态网页技术,允许将Java代码嵌入到HTML页面中。
拖拽上传文件和文件夹是一种常见的网页交互功能,可以使用JSP来实现。
在实现拖拽上传文件和文件夹功能之前,首先需要了解一下拖拽上传的基本原理。
在HTML中,可以通过Drag and Drop API来获取拖拽的文件和文件夹。
然后,可以使用JavaScript将拖拽的文件和文件夹发送到服务器端,服务器端可以使用JSP来处理这些文件和文件夹。
以下是一个基本的实现拖拽上传文件的JSP页面的示例:```htmlpageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>拖拽上传文件</title><script>function handleDrop(event)event.preventDefault(; // 禁止浏览器打开文件var files = event.dataTransfer.files;//遍历上传的文件for (var i = 0; i < files.length; i++)var file = files[i];// 创建FormData对象,用于发送文件到服务器var formData = new FormData(;formData.append("file", file);// 创建一个XMLHttpRequest对象,发送文件到服务器var xhr = new XMLHttpRequest(;xhr.open("POST", "upload.jsp", true);xhr.onreadystatechange = functioif (xhr.readyState == 4 && xhr.status == 200)//上传成功console.log(xhr.responseText);}};xhr.send(formData);}}</script></head><body ondragover="event.preventDefault(;"ondrop="handleDrop(event);"><h1>拖拽上传文件</h1><p>将文件拖拽到此处上传</p></body></html>```当文件被拖拽到页面的时候,`handleDrop(`函数会被调用。
struts文件上传

然后在struts.xml文件中加一句话
<constant name="struts.custom.i18n.resources" value="fileuploadmessages"/>
该属源文件,则多个资源文件的文件名以英文逗号(,)隔开。
配置文件代码
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "/dtds/struts-2.3.dtd"> <struts> <constant name="struts.i18n.encoding" value="gbk"/> <package name="fileupload" extends="struts-default" namespace="/"> <action name="fileupload" class="org.myfileupload.action.FileUpLoadAction" > <param name="savePath">/upload</param> <result name="success">/success.jsp</result> </action> </package> </struts> 配置上传文件的保存路
Struts2文件上传

1
文件上传与下载(单文件与多文件上传)
目标
2
struts2并没有定义自己的文件解析器,而是采用 了其他的开源组件 支持三种文件上传组件
# struts.multipart.parser=cos # struts.multipart.parser=pell struts.multipart.parser=jakarta 其中jakarta是默认支持的方式
Struts2文件下载
文件下载实质是将服务器上的文件以流的形式传送给客 户端浏览器,并通知浏览器如何处理文件流. 通过response对象通知浏览器的处理方式为下载
response.setHeader("Content-disposition", "attachment; filename=" + utf8File);
<s:form action="fileupload.action" enctype="multipart/formdata" method="post"> <s:textfield label="照片描述" name="desc"></s:textfield> <s:file label="文件1" name="file1"></s:file> <s:submit value="上传"></s:submit> </s:form>
<form action="fileupload.action" enctype="multipart/form-data" method="post"> 头像:<input type="file" name="image"> 头像描述:<input type="text" name="desc"> <input type="submit" value="上传"/> </form>
struts2文件上传文件类型设置

struts2是根据contentType来限制的,并不是文件的扩展名比如我想仅上传image/png,image/gif,image/jpeg这三种文件类型第一种方法是通过javascript校验来限制,这个比较简单,获取input的value 然后截取扩展名进行判断即可第二种是根据struts2自带的fileupload拦截器中提供的allowedTypes来进行限制,步骤如下:1 配置fileupload拦截器struts2的defaultStack中已经含有fileupload拦截器,如果想加入allowedTypes 参数,需要从新写一个defaultstack ,拷贝过来修改一下即可:<interceptor-stack name="myDefaultStack"><interceptor-ref name="exception"/><interceptor-ref name="alias"/><interceptor-ref name="servletConfig"/><interceptor-ref name="i18n"/><interceptor-ref name="prepare"/><interceptor-ref name="chain"/><interceptor-ref name="debugging"/><interceptor-ref name="profiling"/><interceptor-ref name="scopedModelDriven"/><interceptor-ref name="modelDriven"/><interceptor-ref name="fileUpload"><param name="allowedTypes">image/png,image/gif,image/jpeg</param></interceptor-ref><interceptor-ref name="checkbox"/><interceptor-ref name="staticParams"/><interceptor-ref name="actionMappingParams"/><interceptor-ref name="params"><paramname="excludeParams">dojo\..*,^struts\..*</param></interceptor-ref><interceptor-ref name="conversionError"/><interceptor-ref name="validation"><paramname="excludeMethods">input,back,cancel,browse</param></interceptor-ref><interceptor-ref name="workflow"><paramname="excludeMethods">input,back,cancel,browse</param></interceptor-ref></interceptor-stack></interceptors><default-interceptor-refname="myDefaultStack"></default-interceptor-ref>仅修改代码中的<interceptor-ref name="fileUpload"><param name="allowedTypes">image/png,image/gif,image/jpeg</param></interceptor-ref>上面配置的是上传文件类型的限制,其实共有两个参数maximumSize (可选) - 这个拦截器允许的上传到action中的文件最大长度(以byte为单位). 注意这个参数和在webwork.properties中定义的属性没有关系,默认2MBallowedTypes (可选) - 以逗号分割的contentType类型列表(例如text/html),这些列表是这个拦截器允许的可以传到action中的contentType.如果没有指定就是允许任何上传类型.2 jsp页面定义如下(testFileUpload.jsp)<s:form action="testFileUpload" method="post"enctype="multipart/form-data"><s:file name="file"theme="simple"/><s:fielderror name="file"></s:fielderror><s:submit/></s:form>3 后台的action声明如下(我用的是struts2的注解进行action配置)public class TestFileUploadAction extends ActionSupport{private File file;private String fileContentType;private String fileFileName;@Action(value = "testFileUpload", results = {@Result(name = "input", location = "/testFileUpload.jsp"),@Result(name = "success", location ="/testFileUploadSuccess.jsp")})public String execute() {return SUCCESS;}get/set......}注意:如果jsp中file的name="xxx",那么后台action中的属性要做相应更改为private File xxx;private String xxxContentType;private String xxxFileName;同时注意大小写一定要一致4 定义错误文件类型的消息提示,这个需要用到struts2的资源文件,在struts.properties文件中加入struts.custom.i18n.resources=globalMessagesglobalMessages对应着资源文件名5 在源文件夹下定义资源文件globalMessages.properties,并在里面加入如下信息:struts.messages.error.content.type.not.allowed=upload file contenttype is invalidate这里稍作说明(拷贝一下struts2的帮助):如果你的action实现了ValidationAware接口(如果action继承了ActionSupport,那么就相当于实现了ValidationAware),这个拦截器就可以添加几种字段错误.这些错误信息是基于存储在struts-messages.properties文件中的一些i18n值,这个文件是所有i18n请求的默认文件.你可以在自己消息文件的复写以下key的消息文字struts.messages.error.uploading - 文件不能上传的通用错误信息rge - 上传文件长度过大的错误信息struts.messages.error.content.type.not.allowed - 当上传文件不符合指定的contentType以上配置完毕后,测试一下,对于非法的contentType,例如xxx.log这个文件的的contentType是pplication/octet-stream会给出提示:upload file contenttype is invalidate'.a' : 'application/octet-stream','.ai' : 'application/postscript','.aif' : 'audio/x-aiff','.aifc' : 'audio/x-aiff','.aiff' : 'audio/x-aiff','.au' : 'audio/basic','.avi' : 'video/x-msvideo','.bat' : 'text/plain','.bcpio' : 'application/x-bcpio','.bin' : 'application/octet-stream','.bmp' : 'image/x-ms-bmp','.c' : 'text/plain','.cdf' : 'application/x-cdf','.cdf' : 'application/x-netcdf','.cpio' : 'application/x-cpio','.csh' : 'application/x-csh','.css' : 'text/css','.dll' : 'application/octet-stream', '.doc' : 'application/msword', '.dot' : 'application/msword','.dvi' : 'application/x-dvi','.eml' : 'message/rfc822','.eps' : 'application/postscript', '.etx' : 'text/x-setext','.exe' : 'application/octet-stream', '.gif' : 'image/gif','.gtar' : 'application/x-gtar','.h' : 'text/plain','.hdf' : 'application/x-hdf','.htm' : 'text/html','.html' : 'text/html','.ief' : 'image/ief','.jpe' : 'image/jpeg','.jpeg' : 'image/jpeg','.jpg' : 'image/jpeg','.js' : 'application/x-javascript', '.ksh' : 'text/plain','.latex' : 'application/x-latex','.m1v' : 'video/mpeg','.man' : 'application/x-troff-man', '.me' : 'application/x-troff-me', '.mht' : 'message/rfc822','.mhtml' : 'message/rfc822','.mif' : 'application/x-mif','.mov' : 'video/quicktime','.movie' : 'video/x-sgi-movie','.mp2' : 'audio/mpeg','.mp3' : 'audio/mpeg','.mpa' : 'video/mpeg','.mpe' : 'video/mpeg','.mpeg' : 'video/mpeg','.mpg' : 'video/mpeg','.ms' : 'application/x-troff-ms', '.nc' : 'application/x-netcdf', '.nws' : 'message/rfc822','.o' : 'application/octet-stream','.obj' : 'application/octet-stream','.oda' : 'application/oda','.p12' : 'application/x-pkcs12','.p7c' : 'application/pkcs7-mime','.pbm' : 'image/x-portable-bitmap','.pdf' : 'application/pdf','.pfx' : 'application/x-pkcs12','.pgm' : 'image/x-portable-graymap', '.pl' : 'text/plain','.png' : 'image/png','.pnm' : 'image/x-portable-anymap', '.pot' : 'application/vnd.ms-powerpoint', '.ppa' : 'application/vnd.ms-powerpoint', '.ppm' : 'image/x-portable-pixmap','.pps' : 'application/vnd.ms-powerpoint', '.ppt' : 'application/vnd.ms-powerpoint', '.ps' : 'application/postscript','.pwz' : 'application/vnd.ms-powerpoint', '.py' : 'text/x-python','.pyc' : 'application/x-python-code','.pyo' : 'application/x-python-code','.qt' : 'video/quicktime','.ra' : 'audio/x-pn-realaudio','.ram' : 'application/x-pn-realaudio', '.ras' : 'image/x-cmu-raster','.rdf' : 'application/xml','.rgb' : 'image/x-rgb','.roff' : 'application/x-troff','.rtx' : 'text/richtext','.sgm' : 'text/x-sgml','.sgml' : 'text/x-sgml','.sh' : 'application/x-sh','.shar' : 'application/x-shar','.snd' : 'audio/basic','.so' : 'application/octet-stream','.src' : 'application/x-wais-source', '.sv4cpio': 'application/x-sv4cpio','.sv4crc' : 'application/x-sv4crc','.swf' : 'application/x-shockwave-flash', '.t' : 'application/x-troff','.tar' : 'application/x-tar','.tcl' : 'application/x-tcl','.tex' : 'application/x-tex','.texi' : 'application/x-texinfo','.texinfo': 'application/x-texinfo','.tif' : 'image/tiff','.tiff' : 'image/tiff','.tr' : 'application/x-troff','.tsv' : 'text/tab-separated-values', '.txt' : 'text/plain','.ustar' : 'application/x-ustar','.vcf' : 'text/x-vcard','.wav' : 'audio/x-wav','.wiz' : 'application/msword','.wsdl' : 'application/xml','.xbm' : 'image/x-xbitmap','.xlb' : 'application/vnd.ms-excel', '.xls' : 'application/excel','.xls' : 'application/vnd.ms-excel', '.xml' : 'text/xml','.xpdl' : 'application/xml','.xpm' : 'image/x-xpixmap','.xsl' : 'application/xml','.xwd' : 'image/x-xwindowdump', '.zip' : 'application/zip',。
使用数组实现struts2组图上传

在实际项目中,由于要上传的图片比较多,我们需要对图片名称做一些处理,以避免图片名称相同,造成后者覆盖前者的意外。
所以action中我们可以这样写:Java代码1.package bag;2.3.import java.io.File;4.import java.io.FileInputStream;5.import java.io.FileOutputStream;6.import java.util.Date;7.8.import org.apache.struts2.ServletActionContext;9.10.import com.opensymphony.xwork2.ActionSupport;11.12.public class ManyUploadAction extends ActionSupport {13. private static final int BUFFER_SIZE = 16 * 1024;14.15. // 使用File数组封装多个文件域对应的文件内容16. private File[] file;17.18. // 使用字符串数组封装多个文件域对应的文件名19. private String[] fileFileName;20.21. // 接受依赖注入的属性22. private String savePath;23.24. // 结果显示消息25. private String msg;26.27. // 只用这个方法也可以实现多图片上传功能28. public String execute() throws Exception {29.30. // 取得需要上传的文件数组31. File[] files = this.getFile();32. // 遍历每个需要上传的文件33. for (int i = 0; i < files.length; i++) {34. fileFileName[i] = i + new Date().getTime()35. + getExtention(fileFileName)[i];36. // 以服务器的文件保存地址和原文件名建立上传文件输出流37. FileOutputStream fos = new FileOutputStream(getSavePath() + "\\"38. + getFileFileName()[i]);39. System.out.println(getSavePath() + "\\" + getFileFileName()[i]);40. // 以每个需要上传的文件建立文件输入流41. FileInputStream fis = new FileInputStream(files[i]);42. // 将每个需要上传的文件写到服务器对应的文件中43. byte[] buffer = new byte[BUFFER_SIZE];44. int len = 0;45. while ((len = fis.read(buffer)) > 0) {46. fos.write(buffer, 0, len);47. }48. }49. this.msg = "上传成功!";50. return SUCCESS;51. }52.53. // 获得每个文件的扩展名54. public String[] getExtention(String[] fileNames) {55. String[] extentions = new String[fileNames.length];56. for (int i = 0; i < extentions.length; i++) {57. int pos = fileNames[i].lastIndexOf(".");58. extentions[i] = fileNames[i].substring(pos);59. }60. return extentions;61. }62.63. public File[] getFile() {64. return file;65. }66.67. public void setFile(File[] file) {68. this.file = file;69. }70.71. public String[] getFileFileName() {72. return fileFileName;73. }74.75. public void setFileFileName(String[] fileFileName) {76. this.fileFileName = fileFileName;77. }78.79. public String getSavePath() {80. return ServletActionContext.getRequest().getRealPath(savePath);81. }82.83. public void setSavePath(String savePath) {84. this.savePath = savePath;85. }86.87. public String getMsg() {88. return msg;89. }90.91. public void setMsg(String msg) {92. this.msg = msg;93. }94.95.}这时注意到 execute方法中的fileFileName[i] ,我们给它以毫秒时间进行命名,但意外的是这是一个数组,执行上传时,三张图片产生的毫秒时间是相同的,导致结果你只能看到最后一张图片,因为他们的图片名称处理后是一样的,后来者覆盖了前面的,结果只剩一张了,那么在实际操作中,我们就有必要对它们再做其他处理,比如:在这里我在名称前面加上了循环变量i,那么三个名称就区分开了,结果当然就是我们想要的了。
struts2中使用kindeditor上传图片(包括jmagic压缩图片)

@SuppressWarnings("serial")@ParentPackage("control-center")public class UploadContentImgAction extends BaseAction {private File up;private String upFileName;private String upContentType;private String fileDir = "uploads/articleContentImg";private String imgTitle;private String align;private int imgWidth;private int imgHeight;/*** kindeditor图片上传* @return* @throws Exception*/@Action("kindeditorImgUpload")public String kindeditorImgUpload() throws Exception {//只能传图片try {if(!validatePostfix(upFileName)) {return "error";}User user = (User)getSession().get("user");String fileRealDir = getServletContext().getRealPath(fileDir);File file = up;String fileRealName = createfilename(user.getUserId());String fileName = fileRealName + upFileName.substring(stIndexOf(".")).toLowerCase();File newFile = new File(fileRealDir, fileName);FileUtils.copyFile(file, newFile);//压缩图片ImageUtil.resize(newFile.getPath(), newFile.getPath(), 500);String id = "contentId";String url = "/" + fileDir + "/" + fileName;String border = "0";String result = "<script type='text/javascript'>parent.KE.plugin['image'].insert('" + id + "','" + url + "','" + imgTitle + "','" + imgHeight + "','" + imgHeight + "','" + border + "','" + align + "');</script>";getHttpServletResponse().getWriter().write(result);} catch (RuntimeException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}/*** 生成文件名: 当前时间+ 随机数+ 用户id*/private String createfilename(int userId) {StringBuilder result = new StringBuilder();// 得到本地的当前时间String now = DateUtil.getLongStrFromDate(new Date());// 在1000W 内随机生成一个数字int rand = new Random().nextInt(9999999);// 去掉- 去掉: 去掉空格后,返回result.append(now.replace("-", "").replace(":", "").replace(" ", "")).append("_").append(rand).append("_").append(userId);return result.toString();}/*** 验证后缀名应该从配置文件中获取*/public boolean validatePostfix(String filename) {// 定义可上传文件的类型List<String> fileTypes = new ArrayList<String>();// 图片fileTypes.add("jpg");fileTypes.add("jpeg");fileTypes.add("bmp");fileTypes.add("gif");fileTypes.add("png");// 得到文件尾数并进行小写转换String postfix = filename.substring(stIndexOf(".") + 1).toLowerCase();return fileTypes.contains(postfix) ? true : false;}public File getUp() {return up;}public void setUp(File up) {this.up = up;}public String getUpFileName() {return upFileName;}public void setUpFileName(String upFileName) { this.upFileName = upFileName;}public String getUpContentType() {return upContentType;}public void setUpContentType(String upContentType) { this.upContentType = upContentType;}public String getImgTitle() {return imgTitle;}public void setImgTitle(String imgTitle) {this.imgTitle = imgTitle;}public int getImgWidth() {return imgWidth;}public void setImgWidth(int imgWidth) {this.imgWidth = imgWidth;}public int getImgHeight() {return imgHeight;}public void setImgHeight(int imgHeight) {this.imgHeight = imgHeight;}public String getAlign() {return align;}public void setAlign(String align) {this.align = align;}}/*** @author**/public class ImageUtil {public final static int PHOTO_RATIO = 800; //缩放图片系数static{System.setProperty("jmagick.systemclassloader", "no");}/*** 图片水印** @param pressImg 水印图片* @param targetImg 目标图片* @param x 修正值默认在中间* @param y 修正值默认在中间* @param alpha 透明度*/public final static void pressImage(String pressImg, String targetImg,int x, int y, float alpha) {try {File img = new File(targetImg);Image src = ImageIO.read(img);int wideth = src.getWidth(null);int height = src.getHeight(null);BufferedImage image = new BufferedImage(wideth, height,BufferedImage.TYPE_INT_RGB);Graphics2D g = image.createGraphics();g.drawImage(src, 0, 0, wideth, height, null);// 水印文件Image src_biao = ImageIO.read(new File(pressImg));int wideth_biao = src_biao.getWidth(null);int height_biao = src_biao.getHeight(null);g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));g.drawImage(src_biao, (wideth - wideth_biao) / 2,(height - height_biao) / 2, wideth_biao, height_biao, null);// 水印文件结束g.dispose();ImageIO.write((BufferedImage) image, "jpg", img);} catch (Exception e) {e.printStackTrace();}}/*** 文字水印** @param pressText 水印文字* @param targetImg 目标图片* @param fontName 字体名称* @param fontStyle 字体样式* @param color 字体颜色* @param fontSize 字体大小* @param x 修正值* @param y 修正值* @param alpha 透明度*/public static void pressText(String pressText, String targetImg, String fontName, int fontStyle, Color color, int fontSize, int x,int y, float alpha) {try {File img = new File(targetImg);Image src = ImageIO.read(img);int width = src.getWidth(null);int height = src.getHeight(null);BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D g = image.createGraphics();g.drawImage(src, 0, 0, width, height, null);g.setColor(color);g.setFont(new Font(fontName, fontStyle, fontSize));g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_A TOP, alpha));g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (height - fontSize) / 2 + y);g.dispose();ImageIO.write((BufferedImage) image, "jpg", img);} catch (Exception e) {e.printStackTrace();}}/*** 缩放效果太差ps: Graphics下的还有AffineTransform下的* 缩放都是针对"图形"而不是"图像"的,所以处理后图片很不清晰* @param filePath 图片路径* @param height 高度* @param width 宽度* @param bb 比例不对时是否需要补白*/public static void resizeImgcale(String filePath, int height, int width, boolean bb) { try {double ratio = 0.0; // 缩放比例File f = new File(filePath);BufferedImage bi = ImageIO.read(f);Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);// 计算比例if ((bi.getHeight() > height) || (bi.getWidth() > width)) {if (bi.getHeight() > bi.getWidth()) {ratio = (new Integer(height)).doubleV alue() / bi.getHeight();} else {ratio = (new Integer(width)).doubleValue() / bi.getWidth();}AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);itemp = op.filter(bi, null);}if (bb) {BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D g = image.createGraphics();g.setColor(Color.white);g.fillRect(0, 0, width, height);if (width == itemp.getWidth(null))g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,itemp.getWidth(null), itemp.getHeight(null),Color.white, null);elseg.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,itemp.getWidth(null), itemp.getHeight(null),Color.white, null);g.dispose();itemp = image;}ImageIO.write((BufferedImage) itemp, "jpg", f);} catch (IOException e) {e.printStackTrace();}}/*** 计算字的长度** @param text* @return*/public static int getLength(String text) {int length = 0;for (int i = 0; i < text.length(); i++) {if (new String(text.charAt(i) + "").getBytes().length > 1) {length += 2;} else {length += 1;}}return length / 2;}/*** 压缩图片** @param imgsrc 源文件* @param imgdist 目标文件* @param widthdist 宽* @param heightdist 高*/public static void resizeImg(String imgsrc, String imgdist, int widthdist, int heightdist) { try {File srcfile = new File(imgsrc);if (!srcfile.exists()) {return;}Image src = javax.imageio.ImageIO.read(srcfile);BufferedImage tag = new BufferedImage(widthdist, heightdist, BufferedImage.TYPE_INT_RGB);/** SCALE_SMOOTH:尺寸平滑SCALE_AREA_A VERAGING:尺度区平均SCALE_FAST:尺度快速* SCALE_REPLICATE:尺度复制*/tag.getGraphics().drawImage(src.getScaledInstance(widthdist, heightdist, Image.SCALE_SMOOTH), 0, 0, null);FileOutputStream out = new FileOutputStream(imgdist);JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);encoder.encode(tag);out.close();} catch (IOException ex) {ex.printStackTrace();}}/*** 图片压缩* @param picFrom* @param picTo* @param widthdist* @param heightdist*/public static void resize(String picFrom, String picTo, int widthdist, int heightdist) { try {ImageInfo info = new ImageInfo(picFrom);MagickImage image = new MagickImage(new ImageInfo(picFrom));MagickImage scaled = image.scaleImage(widthdist, heightdist);// 小图片文件的大小.scaled.setFileName(picTo);scaled.writeImage(info);} catch (Exception ex) {ex.printStackTrace();}}public static void resize(String picFrom, String picTo, int ratio) throws Exception { BufferedImage bi = ImageIO.read(new File(picFrom));//原始图片属性int srcWidth = bi.getWidth();int srcHeight = bi.getHeight();//生成图片属性int newWidth = srcWidth;int newHeight = srcHeight;//如果超出最大宽或高就压缩if (srcWidth > ratio || newHeight > ratio) {//生成图片width, height计算if (srcWidth >= srcHeight) {if (srcWidth < ratio) {return;}newWidth = ratio;newHeight = (int)(ratio * srcHeight / srcWidth);} else {if (srcHeight < ratio) {return;}newHeight = ratio;newWidth = (int)(ratio * srcWidth / srcHeight);}}resize(picFrom, picTo, newWidth, newHeight);}public static void resize(String picFrom, String picTo) throws Exception {resize(picFrom, picTo, PHOTO_RATIO);}public static void main(String[] args) throws Exception {// resizeImg("d:/411766.jpg", "d:/411766_1.jpg", 800, 600);// resize("d:/test_4.jpg", "d:/test_4_2.jpg", 800);pressText("欢喜冤家", "d:/411766.jpg", "简体", Font.ITALIC, Color.black, 90, 40, 80, 0.5f);}}。
Struts2实现文件上传

Struts2实现文件上传文件上传,说白了就是个文件复制的过程,文件复制需要什么呢,只需要有源文件和目标地址即可,·用main方法实现的文件复制代码如下:package cn.oracle.upload;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;public class FileUploadDemo {public static void main(String[] args) throws Exception{File input=new File(args[0]); 参数args[0]是你运行Java程序的时候输入的参数,下面有详细解释:if(!input.exists()){System.out.println("源文件不存在!");System.exit(0);}File output=new File(args[1]);if(!output.getParentFile().exists()){output.mkdirs();}OutputStream outputFile=new FileOutputStream(output);InputStream inputFile=new FileInputStream(input);byte data[]=new byte[1024];int temp=0;while((temp=inputFile.read(data))!=-1){outputFile.write(data, 0, temp);}outputFile.close();inputFile.close();}}例如上图中的Java 运行的程序类名称后面就是参数第一个是d:\1.txt 是一个参数args[0],d:\2.txt是第二个参数args[1]C:\Users\congz_000>java FileUploadDemo d:\1.txt d:\2.txt上面的代码就实现了文件的复制,其实在struts2之中的实现原理是一样的,也就是两个File对象,两个字节流对象,然后调用相应的方法执行的复制而已;在struts2之中实现的复制需要一个表单,将此表单的内容提交到一个action之中,然后struts负责参数的接受处理,赋给相应的变量,编写一个文件复制的方法即可完成文件上传;·给项目添加struts2开发支持,我们用自动配置的方式,用myeclipse帮我们完成,不需要做过多的配置,一路next即可;·新建一个upload.jsp页面<%@page language="java"import="java.util.*"pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort( )+path+"/";%><!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>文件上传</title></head><body><form action="FileUpload!upload.action"method="post"enctype="multipart/form-data"><input type="file"name="photo"id="photo"> 这个name属性一定要和action之中的File 类对象的名称一致;<input type="submit"value="上传"></form></body></html>·一个用来表示上传成功的页面<%@page language="java"import="java.util.*"pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort( )+path+"/";%><!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>文件上传</title></head><body><h1>上传成功</h1></body></html>·一个用来表示上传失败的页面<%@page language="java"import="java.util.*"pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort( )+path+"/";%><!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>文件上传</title></head><body><h2>上传失败!</h2></body></html>·编写相应的上传需要的action FileUploadActionpackage cn.oracle.action;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.util.UUID;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;@SuppressWarnings("serial")public class FileUploadAction extends ActionSupport { private File photo;private String photoFileName;public void setPhotoFileName(String photoFileName) { this.photoFileName = photoFileName;}public void setPhoto(File photo) {this.photo = photo;}public String upload(){System.out.println("************");String filePath =ServletActionContext.getServletContext().getRealPath("/upload")+ File.separator+ UUID.randomUUID()+ "."+ this.photoFileName.substring(this.photoFileName.lastIndexOf(".") + 1);if(this.saveFile(this.photo, filePath)){return"success";}return"failure";}public boolean saveFile(File input, String outputFilePath) { File output = new File(outputFilePath);if (!output.getParentFile().exists()) {output.mkdirs();}InputStream inputFile = null;try {inputFile = new FileInputStream(input);} catch (FileNotFoundException e) {e.printStackTrace();}OutputStream outputFile = null;try {outputFile = new FileOutputStream(output);} catch (FileNotFoundException e) {e.printStackTrace();}byte[] data = new byte[1024];int temp = 0;try {while ((temp = inputFile.read(data)) != -1) {outputFile.write(data, 0, temp);}if (inputFile != null) {inputFile.close();}if (outputFile != null) {outputFile.close();}return true;} catch (Exception e) {e.printStackTrace();}return false;}}·配置Struts.xml文件<?xml version="1.0"encoding="UTF-8"?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN""/dtds/struts-2.1.dtd"><struts><package name="main"namespace="/"extends="struts-default"><action name="FileUpload"class="cn.oracle.action.FileUploadAction"> <result name="success">/success.jsp</result><result name="failure">/failure.jsp</result></action></package></struts>·我们还需要配置一个Struts.properties的资源文件,在src之中,设置上传的限制和编码;struts.i18n.encoding=UTF-8struts.multipart.saveDir=/tempstruts.multipart.maxSize=2097152000·我们把项目部署到tomcat或者weblogic之中,按照你的连接访问,整个上传到此就完成了,这是个最简单的上传,没有做任何的修饰,有些上传做的很华丽的,那些都是div+css的功劳,如果你想要那种特效的话,需要研究下css 这个很不错的;。
java struts2入门学习实例--使用struts2快速实现多个文件上传

一、错误提示信息配置昨天说到更改默认错误配置信息,我测试很多遍,一直都不对。
下面贴出来,待以后有好方法了再补充吧。
首先新建一个properties文件,这里命名为testupload.properties,内容为:rge=\u6587\u4EF6\u592A\u5927{0} "{1}" "{2}" {3}struts.messages.error.content.type.not.allowed=\u6587\u4EF6\u7C7B\u578B\u4E0D \u5141\u8BB8!{0} "{1}" "{2}" {3}struts.messages.error.file.extension.not.allowed=\u4E0D\u5141\u8BB8\u7684\u6269 \u5C55\u540D!{0} "{1}" "{2}" {3}这里将默认提示信息改为中文的。
upload.xml中内容如下:<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""/dtds/struts-2.3.dtd"><struts><!-- 对上传文件总大小进行设置--><constant name="struts.multipart.maxSize"value="20971520"></constant><!-- 错误信息提示--><constant name="struts.custom.i18n.resources"value="testupload"/><package name="upload"extends="struts-default"><action name="UploadAction"class="action.UploadAction"method="up loadMethod"><result name="success"type="dispatcher">/WEB-INF/upload_success.jsp</result><result name="input"type="dispatcher">upload.jsp</result><!-- 对系统的拦截器进行设置--><interceptor-ref name="fileUpload"><!-- 对单个上传文件的大小进行设置,5M --><param name="maximumSize">5242880</param><!-- 对允许的文件扩展名进行设置,这里以英文逗号隔开--><param name="allowedExtensions">.txt,.xml</param><!-- 对允许的文件类型进行设置,这里以英文逗号进行隔开--><param name="allowedTypes">text/plain,text/xml</param> </interceptor-ref><!-- 显示引用默认的拦截器--><interceptor-ref name="defaultStack"></interceptor-ref></action></package></struts>二、多个文件上传只需要更改upload.jsp中的部分内容即可:<%@ page language="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags"prefix="s"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http: ///TR/html4/loose.dtd"> <html><head><meta http-equiv="Content-Type"content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><s:form action="UploadAction"enctype="multipart/form-data"method="POS T"><s:textfield label="上传用户"name="username"/><s:file label="上传文件"name="upload"/><s:file label="上传文件"name="upload"/><s:file label="上传文件"name="upload"/><s:submit value="提交"/></s:form></body></html>结果如下所示:也可以将UploadAction.java中的file改为数组类型的,如下所示:package action;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import javax.servlet.ServletContext;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;/*** @ClassName: UploadAction* @Description: 文件上传* @author: amosli* @email:amosli@* @date Jan 14, 2014 1:50:28 AM*/public class UploadAction extends ActionSupport {private static final long serialVersionUID = -8920466592471253212L;private String username;// 用户名private String[] uploadContentType;// 上传文件的类型,(Fileupload拦截器传入的参数)private File[] upload;// 上传的文件,(Fileupload拦截器传入的参数)private String[] uploadFileName;// 上传文件的真实文件名,(Fileupload拦截器传入的参数)public void setUsername(String username) {ername =username;}public String[] getUploadContentType() {return uploadContentType;}public void setUploadContentType(String[] uploadContentType) { this.uploadContentType =uploadContentType;}public File[] getUpload() {return upload;}public void setUpload(File[] upload) {this.upload =upload;}public String[] getUploadFileName() {return uploadFileName;}public void setUploadFileName(String[] uploadFileName) {this.uploadFileName =uploadFileName;}public String getUsername() {return username;}public String uploadMethod() throws Exception {ServletContext context =ServletActionContext.getServletContext();String real_path = context.getRealPath("/WEB-INF/upload/");for(int i = 0; i < upload.length; i++) {InputStream inputStream = new FileInputStream(upload[i]);OutputStream outputStream = new FileOutputStream(real_path + " /" +uploadFileName);byte[] b = new byte[1024];int len = 0;while((len = inputStream.read(b)) > 0) {outputStream.write(b, 0, len);}// 关闭流inputStream.close();outputStream.close();// 删除tmp文件,最好是用tyrcatch finally进行删除// upload[i].delete();}return SUCCESS;}}这里没有立马删除是想做个演示,查看一下缓存文件空间生成了几个。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
xheditor +struts2 文件上传(一般情况和支持HTML5拖拽上传)1、准备工作Struts2.2.3导入相关jar包Xheditor1.1.4引入jquery和xheditor的js文件2、效果图a) 使用上传图片按钮进行上次b) 将图片进行拖入上传(支持html5的浏览器)3、相关代码a)单纯的使用普通方式上传:如下图:Struts2中Action中的方法:和传统的上传没什么区别,记得写getter和setterXheditor官方要求:返回内容必需是标准的json字符串,结构可以是如下:{"err":"","msg":"200906030521128703.gif"} 或者{"err":"","msg":{"url":"200906030521128703.jpg","localfile":"test.jpg","id":"1"}} 注:若选择结构2,则url变量是必有注意:1.上传成功时返回的json字符串是:{"err":"","msg":"200906030521128703.gif"}2.err是””,不能省略,3.方式1,msg返回值是上传成功文件的路径;4.方式2,则msg中的url是上传成功文件的路径5.url第一个字符是!表示立即上传,不需要点确定就插入到textarea中Jsp中:【特别应该注意的是:html5Upload:false;如果不设置成false,在支持html5的浏览器(eg:chrome)中,会默认使用html5上传的方式,导致未设置multipart/form-data上传失败,而在不支持html5,例如IE中正常。
】吐槽一下,xheditor的作者为何不默认上传使用传统方式,且html5Upload默认还是true,官方也没有明显的说明,因为这个问题测试了很久。
b)支持html5的拖拽上传官方说明:HTML5上传的整个POST数据流就是上传的文件完整数据,而本地文件名等信息储存于HTTP_CONTENT_DISPOSITION这个服务器变量中。
也就是说,如果是html5实现的文件上次,我们可以从request的header的Content-Disposition中获得相关数据,可以打开浏览器的网络监测查看。
Struts2中Action中的方法:Jsp中:无任何变化,把html5Upload =true即可注:本程序未对细节做过多的处理,重在实现上传,比如上传文件的限制,上传成功后的回调函数未做处理。
问后附上了完整的程序,本人邮箱623565791@欢迎交流。
4、完整代码下面是完整代码,如果您还有什么问题,可以参考:Struts2packagecom.zhy.xheditor.action;importjava.io.File;importjava.io.IOException;importjava.io.PrintWriter;importjavax.servlet.ServletInputStream;importjavax.servlet.http.HttpServletResponse;mons.io.FileUtils;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;@SuppressWarnings("serial")public class FileUpload extends ActionSupport{public File filedata;public String filedataFileName;public void ajaxFileUpload(){String dirPath = ServletActionContext.getRequest().getSession().getServletContext().getRealPath("");File dir = new File(dirPath + "/resources/upload");String contentDisposition = ServletActionContext.getRequest().getHeader("Content-Disposition");// 如果是HTML5上传文件,那么这里有相应头的if (contentDisposition != null){// HTML5拖拽上传文件Long fileSize = Long.valueOf(ServletActionContext.getRequest().getHeader("Content-Length"));// 上传的文件大小String fileName = contentDisposition.substring(contentDisposition.lastIndexOf("filename=\""));// 文件名称fileName = fileName.replaceAll("filename=\"", "");fileName = fileName.substring(0, fileName.length() - 1);System.out.println(fileName);ServletInputStreaminputStream = null;try{System.out.println("invoked!");inputStream = ServletActionContext.getRequest().getInputStream();if (inputStream != null){FileUtils.copyInputStreamToFile(inputStream, new File(dir,fileName));String msg = "{\"err\":\"\",\"msg\":{\"url\":\"!"+ ServletActionContext.getRequest().getContextPath() + "/resources/upload/"+ fileName+ "\",\"localfile\":\"test.jpg\",\"id\":\"1\"}} ";System.out.println("xheditor using html5 ..." + fileName);writer(msg);System.out.println("xheditor using html5 ..." + fileName);}} catch (IOException e){e.printStackTrace();}return;}try{System.out.println("xheditor using common ..." + filedataFileName);FileUtils.copyFile(filedata, new File(dir, filedataFileName));String msg = "{\"err\":\"\",\"msg\":{\"url\":\"!"+ ServletActionContext.getRequest().getContextPath()+ "/resources/upload/" + filedataFileName+ "\",\"localfile\":\"test.jpg\",\"id\":\"1\"}} ";writer(msg);} catch (IOException e){e.printStackTrace();}}private void writer(String msg){try{System.out.println("invoked!!..");HttpServletResponseresp = ServletActionContext.getResponse();resp.setCharacterEncoding("utf-8");resp.setContentType("text/plain");PrintWriter out = resp.getWriter();out.write(msg);out.flush();} catch (IOException e){e.printStackTrace();}}}Jsp:<%@page language="java"import="java.util.*"pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";%><!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma"content="no-cache"><meta http-equiv="cache-control"content="no-cache"><meta http-equiv="expires"content="0"><meta http-equiv="keywords"content="keyword1,keyword2,keyword3"> <meta http-equiv="description"content="This is my page"><script type="text/javascript"src="<%=request.getContextPath()%>/resources/jquery-1.7.2.js"></script><script type="text/javascript"src="<%=request.getContextPath()%>/resources/xheditor-1.1.14/xhed itor-1.1.14/xheditor-1.1.14-zh-cn.min.js"></script><script type="text/javascript">$(function(){$("#xheditor").xheditor({upLinkUrl:$("#contextPath").val()+"/upload!ajaxFileUpload",upLinkExt:"zip,rar,txt",upImgUrl:$("#contextPath").val()+"/upload!ajaxFileUpload",upImgExt:"jpg,jpeg,gif,png",upFlashUrl:$("#contextPath").val()+"/upload!ajaxFileUpload",upFlashExt:"swf",upMediaUrl:$("#contextPath").val()+"/upload!ajaxFileUpload",upMediaExt:"avi",html5Upload:true,width:800,height:600});});</script></head><body><textarea rows=""cols=""id="xheditor"></textarea> </body><input type="hidden"id="contextPath"value="<%=request.getContextPath()%>"/></html>Struts.xml<?xml version="1.0"encoding="UTF-8"?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "/dtds/struts-2.0.dtd"><struts><constant name="struts.enable.DynamicMethodInvocation"value="true"/> <constant name="struts.devMode"value="false"/><package name="default"namespace="/"extends="struts-default"><action name="upload"class="com.zhy.xheditor.action.FileUpload"> </action></package></struts>。