upload_json.jsp文件,关键在于struts2对于struts2过滤访问的jsp时,会改变reqeust的类型,由HttpServletRequest变成MultiPartRequestWrapper,所以在kindeditor原始的jsp接收上传的request的数据时,取得不了上传的数据内容。

修改之后的upload_json.jsp文件源码:


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

  2. <%@ page import="java.util.*,java.io.*"%>

  3. <%@ page import="java.text.SimpleDateFormat"%>

  4. <%@ page import="org.apache.commons.fileupload.*"%>

  5. <%@ page import="org.apache.commons.fileupload.disk.*"%>

  6. <%@ page import="org.apache.commons.fileupload.servlet.*"%>

  7. <%@ page import="org.json.simple.*"%>

  8. <%@ page

  9. import="org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper"%>

  10. <%

  11. //文件保存目录路径 //D:\Tomcat6.0\webapps\zswz\attached/

  12. String savePath = request.getSession().getServletContext()

  13. .getRealPath("/")

  14. + "photo/upload/";

  15. //文件保存目录URL /zswz/attached/

  16. String saveUrl = request.getContextPath() + "/photo/upload/";

  17. //定义允许上传的文件扩展名

  18. //定义允许上传的文件扩展名

  19. HashMap<String, String>extMap = new HashMap<String, String>();

  20. extMap.put("p_w_picpath", "gif,jpg,jpeg,png,bmp");

  21. extMap.put("flash", "swf,flv");

  22. extMap.put("media",

  23. "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");

  24. extMap.put("file",

  25. "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2"); //允许最大上传文件大小 struts.xml struts.multipart.maxSize=3G

  26. long maxSize = 3000000000l;

  27. response.setContentType("text/html; charset=UTF-8");

  28. if (!ServletFileUpload.isMultipartContent(request)) {

  29. out.println(getError("请选择文件。"));

  30. return;

  31. }

  32. //检查目录

  33. File uploadDir = new File(savePath);

  34. if (!uploadDir.isDirectory()) {

  35. out.println(getError("上传目录不存在。"));

  36. return;

  37. }

  38. //System.out.println("检查目录写权限");

  39. //检查目录写权限

  40. if (!uploadDir.canWrite()) {

  41. out.println(getError("上传目录没有写权限。"));

  42. return;

  43. }

  44. String dirName = request.getParameter("dir");

  45. //p_w_picpath

  46. if (dirName == null) {

  47. dirName = "p_w_picpath";

  48. }

  49. if (!extMap.containsKey(dirName)) {

  50. out.println(getError("目录名不正确。"));

  51. return;

  52. }

  53. //创建文件夹

  54. savePath += dirName + "/";//D:\Tomcat6.0\webapps\zswz\attached/p_w_picpath/

  55. saveUrl += dirName + "/";///zswz/attached/p_w_picpath/

  56. File saveDirFile = new File(savePath);

  57. if (!saveDirFile.exists()) {

  58. saveDirFile.mkdirs();

  59. }

  60. SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

  61. String ymd = sdf.format(new Date());

  62. savePath += ymd + "/";//D:\Tomcat6.0\webapps\zswz\attached/p_w_picpath/20111129/

  63. saveUrl += ymd + "/";///zswz/attached/p_w_picpath/20111129/

  64. File dirFile = new File(savePath);

  65. if (!dirFile.exists()) {

  66. dirFile.mkdirs();

  67. }

  68. if (!dirFile.isDirectory()) {

  69. out.println(getError("上传目录不存在 。"));

  70. return;

  71. }

  72. //检查目录写入权限

  73. if (!dirFile.canWrite()) {

  74. out.println(getError("上传目录没有写入权限。"));

  75. return;

  76. }

  77. //Struts2 请求 包装过滤器,此处使用struts2的包装过滤器

  78. MultiPartRequestWrapper wrapper = (MultiPartRequestWrapper) request;

  79. //获得上传的文件名

  80. String fileName = wrapper.getFileNames("imgFile")[0];

  81. //imgFile

  82. //获得文件过滤器

  83. File file = wrapper.getFiles("imgFile")[0];

  84. //检查扩展名

  85. String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1)

  86. .toLowerCase();

  87. if (!Arrays.<String> asList(extMap.get(dirName).split(","))

  88. .contains(fileExt)) {

  89. out.println(getError("上传文件扩展名是不允许的扩展名。\n只允许"

  90. + extMap.get(dirName) + "格式。"));

  91. return;

  92. }

  93. //检查文件大小

  94. if (file.length() > maxSize)

  95. {

  96. out.println(getError("上传文件大小超过限制。"));

  97. return;

  98. }

  99. //重构上传图片的名称

  100. SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

  101. String newImgName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;byte[] buffer = new byte[1024];

  102. //获取文件输出流

  103. FileOutputStream fos = new FileOutputStream(savePath +"/" + newImgName);

  104. //获取内存中当前文件输入流

  105. InputStream in = new FileInputStream(file);

  106. try {

  107. int num = 0;

  108. while ((num = in.read(buffer)) > 0)

  109. {

  110. fos.write(buffer, 0, num); }}

  111. catch (Exception e) {

  112. e.printStackTrace(System.err);}

  113. finally {

  114. in.close();

  115. fos.close();}

  116. //发送给 KE

  117. JSONObject obj = new JSONObject();

  118. obj.put("error", 0);

  119. obj.put("url", saveUrl +"/" + newImgName);

  120. ///zswz/attached/p_w_picpath/20111129/ p_w_picpath 20111129195421_593.jpg

  121. out.println(obj.toJSONString());

  122. //System.out.println("检查目录写权限2");

  123. %>

  124. <%!

  125. private String getError (String message )

  126. {

  127. JSONObject obj = new JSONObject();

  128. obj.put("error", 1);

  129. obj.put("message", message);

  130. return obj.toJSONString();

  131. }%>

在Common- FileUpload中,它把从客户端提交过来的表单封装成一个个FileItem对象,这也是它实现文件上传功能 的核心类。另一个很重要的类就是FileUploadBase,他的功能就是解析请求(request),如进行上传文 件大小验证,请求类型验证(文件上传的enctype要设置成multipart/form-data)等。我们经常用到它 的子类ServletFileUpload。在FileUploadBase解析 request的过程中会将文件保存到内存,如果文件大 小大于我们设置的缓存的大小,它将把文件的其他内容保存到一个临时目录,当我们对FileItem 对象实 现正真上传时会从内存区或临时目录将文件保存到正真的上传目录。
在kindeditor上传图片调试过程中,发现
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
List items = upload.parseRequest(request);
Iterator itr = items.iterator();
while (itr.hasNext()) {
发现代码4,items为空,取不到需要上传的文件,故没有执行while循环,也就没有返回值,kindeditor报服务器错误。
为什么取不到值,
是因为:struts2过滤访问的jsp时,会改变reqeust的类型,由HttpServletRequest变成MultiPartRequestWrapper,所以parseRequest就返回了null。
既然在过滤的时候改变reqeust的类型,那就可以修改web.xml不过滤jsp。但是如果在jsp中用到了struts2的标签就会报500的错误,这个方案在我的应用中不适用。
最终解决方案是,写个Servlet来代替upload_json.jsp的功能。upload_json.jsp里面的代码大部分都可以复制到Servlet中, upload_json.jsp中的out.prinln返回值用 resp.getWriter().println()代替就行。


转自:http://linxucn.blog.51cto.com/1360306/803634