前言:近期在给学院的站点做一个加入附件的功能,首先到了某某邮箱看了一下。简单有用。可是是flash做的,无法拷贝。就仅仅好上网找插件了。经过筛选。最终找到plupload这款插件(其实有的编辑器自带加入附件功能)。官网仅仅有PHP版本号。后来各种百度谷歌。找到的资料都用点小问题,拼搏一天最终实现了功能,以下就把遇到的问题和重点部分写出来。希望遇到相同问题的同学能够參考。

首先你须要下载plupload插件,下载地址:http://www.plupload.com/download/

JSP页面配置例如以下:

  1. <!-- 配置界面上的css -->
  2. <link rel="stylesheet" type="text/css" href="<%=basePath%>plupload/js/jquery.plupload.queue/css/jquery.plupload.queue.css">
  3. <script type="text/javascript" src="<%=basePath%>js/jquery-1.9.1.min.js"></script>
  4. <script type="text/javascript" src="<%=basePath%>plupload/js/plupload.full.min.js"></script>
  5. <script type="text/javascript" src="<%=basePath%>plupload/js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
  6. <!-- 国际化中文支持 -->
  7. <script type="text/javascript" src="<%=basePath%>plupload/js/i18n/zh_CN.js"></script>
  8. <script type="text/javascript">
  9. // Initialize the widget when the DOM is ready
  10. $(function() {
  11. // Setup html5 version
  12. function plupload(){
  13. $("#uploader").pluploadQueue({
  14. // General settings
  15. runtimes : 'flash,html5,gears,browserplus,silverlight,html4',
  16. url : "<%=basePath%>upload",
  17. //unique_names: true,
  18. chunk_size : '1mb',
  19. //rename : true,
  20. dragdrop: true,
  21. filters : {
  22. // Maximum file size
  23. max_file_size : '10mb',
  24. // Specify what files to browse for
  25. mime_types: [
  26. {title : "Image files", extensions : "jpg,gif,png"},
  27. {title : "Zip files", extensions : "zip"}
  28. ]
  29. },
  30. // Resize images on clientside if we can
  31. resize: {
  32. width : 200,
  33. height : 200,
  34. quality : 90,
  35. crop: true
  36. // crop to exact dimensions
  37. },             // Flash settings
  38. flash_swf_url : '<%=basePath%>plupload/js/Moxie.swf',
  39. // Silverlight settings
  40. silverlight_xap_url : '<%=basePath%>plupload/js/Moxie.xap' ,
  41. // 參数
  42. multipart_params: {'user': 'Rocky', 'time': '2012-06-12'}
  43. });
  44. }
  45. plupload();
  46. $('#Reload').click(function(){
  47. plupload();
  48. });
  49. });
  50. </script>
  51. <div style="width:750px; margin:0px auto;">
  52. <div id="uploader">
  53. <p>您的浏览器未安装 Flash, Silverlight, Gears, BrowserPlus 或者支持 HTML5 .</p>
  54. </div>
  55. <input value="继续上传" id="Reload" type="button">
  56. </div>

* 1024;

  • /**上传失败响应的成功状态码*/
  • public static final String RESP_SUCCESS = "{\"jsonrpc\" : \"2.0\", \"result\" : \"success\", \"id\" : \"id\"}";
  • /**上传失败响应的失败状态码*/
  • public static final String RESP_ERROR = "{\"jsonrpc\" : \"2.0\", \"error\" : {\"code\": 101, \"message\": \"Failed to open input stream.\"}, \"id\" : \"id\"}";
  • /**
  • * 用于Plupload插件的文件上传,自己主动生成唯一的文件保存名
  • * @param plupload - 存放上传所需參数的bean
  • * @param dir - 保存目标文件文件夹
  • * @throws IllegalStateException
  • * @throws IOException
  • */
  • public static void upload(Plupload plupload, File dir) throws IllegalStateException, IOException {
  • //生成唯一的文件名称
  • String filename = "" + System.currentTimeMillis() + plupload.getName();
  • upload(plupload, dir, filename);
  • }
  • /**
  • * 用于Plupload插件的文件上传
  • * @param plupload - 存放上传所需參数的bean
  • * @param dir - 保存目标文件文件夹
  • * @param filename - 保存的文件名称
  • * @throws IllegalStateException
  • * @throws IOException
  • */
  • public static void upload(Plupload plupload, File dir, String filename) throws IllegalStateException, IOException {
  • int chunks = plupload.getChunks();  //获取总的碎片数
  • int chunk = plupload.getChunk();    //获取当前碎片(从0開始计数)
  • System.out.println(plupload.getMultipartFile() + "----------");
  • MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) plupload.getRequest();
  • MultiValueMap<String, MultipartFile> map = multipartRequest.getMultiFileMap();
  • if(map != null) {
  • if (!dir.exists()) dir.mkdirs();    //假设目标文件夹不存在则创建新的文件夹
  • //其实迭代器中仅仅存在一个值,所以仅仅须要返回一个值就可以
  • Iterator<String> iter = map.keySet().iterator();
  • while(iter.hasNext()) {
  • String str = (String) iter.next();
  • List<MultipartFile> fileList =  map.get(str);
  • for(MultipartFile multipartFile : fileList) {
  • //由于仅仅存在一个值,所以最后返回的既是第一个也是最后一个值
  • plupload.setMultipartFile(multipartFile);
  • //创建新目标文件
  • File targetFile = new File(dir.getPath()+ "/" + filename);
  • //当chunks>1则说明当前传的文件为一块碎片,须要合并
  • if (chunks > 1) {
  • //须要创建暂时文件名称,最后再更改名称
  • File tempFile = new File(dir.getPath()+ "/" + multipartFile.getName());
  • //假设chunk==0,则代表第一块碎片,不须要合并
  • saveUploadFile(multipartFile.getInputStream(), tempFile, chunk == 0 ?

    false : true);

  • //上传并合并完毕,则将暂时名称更改为指定名称
  • if (chunks - chunk == 1) {
  • tempFile.renameTo(targetFile);
  • }
  • } else {
  • //否则直接将文件内容拷贝至新文件
  • multipartFile.transferTo(targetFile);
  • }
  • }
  • }
  • }
  • }
  • /**
  • * 保存上传文件,兼合并功能
  • */
  • private static void saveUploadFile(InputStream input, File targetFile, boolean append) throws IOException {
  • OutputStream out = null;
  • try {
  • if (targetFile.exists() && append) {
  • out = new BufferedOutputStream(new FileOutputStream(targetFile, true), BUF_SIZE);
  • } else {
  • out = new BufferedOutputStream(new FileOutputStream(targetFile), BUF_SIZE);
  • }
  • byte[] buffer = new byte[BUF_SIZE];
  • int len = 0;
  • //写入文件
  • while ((len = input.read(buffer)) > 0) {
  • out.write(buffer, 0, len);
  • }
  • } catch (IOException e) {
  • throw e;
  • } finally {
  • //关闭输入输出流
  • if (null != input) {
  • try {
  • input.close();
  • } catch (IOException e) {
  • e.printStackTrace();
  • }
  • }
  • if (null != out) {
  • try {
  • out.close();
  • } catch (IOException e) {
  • e.printStackTrace();
  • }
  • }
  • }
  • }
  • /**
  • * 推断是否所有上传完毕
  • * 碎片需合并后才返回真
  • */
  • public static boolean isUploadFinish(Plupload plupload) {
  • return (plupload.getChunks() - plupload.getChunk() == 1);
  • }
  • }
    1. import javax.servlet.http.HttpServletRequest;
    2. import org.springframework.web.multipart.MultipartFile;
    3. /**
    4. * Plupload是一个上传插件。
    5. * 这是一个bean类,主要存储Plupload插件上传时须要的參数。
    6. * 属性名不可任意修改.
    7. * 这里主要使用MultipartFile文件上传方法
    8. */
    9. public class Plupload {
    10. /**文件暂时名(打文件被分解时)或原名*/
    11. private String name;
    12. /**总的块数*/
    13. private int chunks = -1;
    14. /**当前块数(从0開始计数)*/
    15. private int chunk = -1;
    16. /**HttpServletRequest对象,不能直接传入进来,须要手动传入*/
    17. private HttpServletRequest request;
    18. /**保存文件上传信息,不能直接传入进来。须要手动传入*/
    19. private MultipartFile multipartFile;
    20. public String getName() {
    21. return name;
    22. }
    23. public void setName(String name) {
    24. this.name = name;
    25. }
    26. public int getChunks() {
    27. return chunks;
    28. }
    29. public void setChunks(int chunks) {
    30. this.chunks = chunks;
    31. }
    32. public int getChunk() {
    33. return chunk;
    34. }
    35. public void setChunk(int chunk) {
    36. this.chunk = chunk;
    37. }
    38. public HttpServletRequest getRequest() {
    39. return request;
    40. }
    41. public void setRequest(HttpServletRequest request) {
    42. this.request = request;
    43. }
    44. public MultipartFile getMultipartFile() {
    45. return multipartFile;
    46. }
    47. public void setMultipartFile(MultipartFile multipartFile) {
    48. this.multipartFile = multipartFile;
    49. }
    50. }

    最后就是測试类了,这部分不是重点。比較粗糙

    1. import java.io.File;
    2. import java.io.IOException;
    3. import javax.servlet.http.HttpServletRequest;
    4. import javax.servlet.http.HttpServletResponse;
    5. import org.springframework.stereotype.Controller;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import org.springframework.web.bind.annotation.RequestMethod;
    8. @Controller
    9. public class uploadAction {
    10. public static final String FileDir = "uploadfile/";
    11. /**上传界面*/
    12. @RequestMapping("/uploadui")
    13. public String uploadUI() {
    14. return "login.upload";
    15. }
    16. /**上传处理方法*/
    17. @RequestMapping(value="/upload", method = RequestMethod.POST)
    18. public String upload(Plupload plupload,HttpServletRequest request, HttpServletResponse response) {
    19. //System.out.println(plupload.getChunk() + "===" + plupload.getName() + "---" + plupload.getChunks());
    20. plupload.setRequest(request);
    21. //文件存储路径
    22. File dir = new File(plupload.getRequest().getSession().getServletContext().getRealPath("/") + FileDir);
    23. System.out.println(dir.getPath());
    24. try {
    25. //上传文件
    26. PluploadUtil.upload(plupload, dir);
    27. //推断文件是否上传成功(被分成块的文件是否所有上传完毕)
    28. if (PluploadUtil.isUploadFinish(plupload)) {
    29. System.out.println(plupload.getName() + "----");
    30. }
    31. } catch (IllegalStateException e) {
    32. // TODO Auto-generated catch block
    33. e.printStackTrace();
    34. } catch (IOException e) {
    35. // TODO Auto-generated catch block
    36. e.printStackTrace();
    37. }
    38. return "login.upload";
    39. }
    40. }

    好了,到此重点部分的工作算是完毕了,须要提醒一下的就是,在前台JS部分有一个rename參数,假设设置成true,后台就获取不到文件的真实名称了。后台获取真实名称也不在是MultipartFile的getOriginalFilename()方法了,由于被分块的文件名称称会改变,而须要使用Plupload.getName()获取。

    附上上传成功界面图(这里把设置的文件是没有限制):

    至于后面的怎样将状态码以JOSN形式返回与前台进行交互和文件大小一次性上传大小的限制。就在往后用到了在详述吧。

    以上观点均为个人意见,欢迎指正与批评。