java存储H5上传的图片
来源:互联网 发布:c语言比较字符串长度 编辑:程序博客网 时间:2024/06/09 21:25
最近的业务需要配合前端提供一个上传图片的接口,前端是一个Html5的页面,使用的上传方式和原有上传方式不太一样,因此特别记录一下。
第一种,页面使用表单提交,后台使用commons-fileupload.jar来接收。
其实这种方法就是传统的表单提交方式,前端页面如下:
<form id="form" action="http://localhost:8080/emission/SaveImage" method="post" enctype="multipart/form-data"> <input class="m_camera" type="file" accept="image/*" name="file_img" capture="camera" id="cameraInput" > <input type="hidden" value="123455788" name="orderid" /> <input type="hidden" value="" name="hidden" id="j_thumb" /> <!-- input type="submit" value="submit" name="sbt" id="sbt" --></form>
JS中获得图片压缩一下,然后放到表单中传过来,其实这个东西本来是个很简单的业务,但由于其中的两行JS代码的误会,导致这个东西搞了很久,这两行代码时这样的
var r = i.toDataURL("image/jpeg", .8);document.getElementById("j_thumb").value = r.substr(22)
看起来是给”j_thumb“这个input赋值,然后提交到页面,实际上并不是这样的。当我在后台使用commons-fileupload插件解析request时,在 ”j_thumb“这个对象中,并没有看到对应的文件,直到最后把整个request输出出来,才发现原来这个东西是在file_img这个对象中传过来的,可能是因为浏览器自动处理吧,把图片放到了这个type为file的标签中。得到这个对象后就简单很多了。直接读取一下解析后的文件流,这里没有尝试判断是否文本域的方法,如何使用判断文本域的方法来处理图片,请参见前文:微软云+Servlet实现图片上传接口 所需jar包commons-fileupload也可以在前文中找到。
以下是后台接收图片的代码:
Data.writeLog(Global.errPath1, "访问到SaveImage+test\r\n"); DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(8192); factory.setRepository(tempPath); ServletFileUpload upload = new ServletFileUpload(factory); upload.setSizeMax(1000000 * 20); String orderid = ""; String suffix = ""; try { /* 解析request 取得表单域迭代器 */ FileItemIterator fii = upload.getItemIterator(request); /* 遍历迭代器 ,这里也可以使用while循环*/ for (final FileItemIterator itemIterator = fii; itemIterator.hasNext();) { final FileItemStream item = itemIterator.next(); /*直接根据对象name进行筛选*/ if ("orderid".equals(item.getFieldName())) { /*读取request的输入流*/ BufferedReader responseReader = new BufferedReader( new InputStreamReader(item.openStream(), "UTF-8")); String readLine; StringBuffer responseSb = new StringBuffer(); while ((readLine = responseReader.readLine()) != null) { responseSb.append(readLine); } /*获得表单文字域*/ orderid = responseSb.toString(); } if ("file_img".equals(item.getFieldName())) { /*截取name获得文件后缀名*/ String fileName = item.getName(); int index = fileName.indexOf("."); suffix = fileName.substring(index, fileName.length()); /*从request流中获得输入流*/ BufferedInputStream inputStream = new BufferedInputStream(item.openStream()); /*定义输出流*/ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); /*复制输入流到输出流*/ Streams.copy(inputStream, outputStream, true); /*生成文件图片*/ File picFile = new File( "D:\\feng\\perl-work\\zzq\\emission\\imageUpload\\" + directory + "\\" + saveName + suffix); if (picFile.getParentFile() != null && !picFile.getParentFile().exists()) { picFile.getParentFile().mkdirs(); } if (!picFile.exists()) { picFile.createNewFile(); } /*写入文件并关闭流*/ OutputStream fileOutputStream = new FileOutputStream(picFile); outputStream.writeTo(fileOutputStream); inputStream.close(); outputStream.close(); fileOutputStream.close(); } } } catch (Exception e) { message.put("code", "-1"); message.put("message", "接收文件失败" + e.getMessage()); message.put("id", request.getParameter("orderid")); writer.println(new JSONObject(message).toString()); request.setAttribute("orderId", orderid); }
这种范式的一个问题就是对app不太友好,因为表单提交就意味着url跳转,只能在服务器端的网页上使用这种上传图片的方法。
第二种,使用ajax异步调用图片存储接口
ajax也是现在很流行图片上传方法,即将图片处理成二进制文本,然后作为字符串传输给后台。前台代码如下:
function saveImage(txt) { var id = ""; alert(txt) $.ajax({ url: "http://localhost:8080/emission/SaveImage2", type: "post", data: { orderId: 39, file_img: txt }, success: function(response) { alert(response); var dataobj = eval("(" + response + ")") } })}
txt即为处理过的二进制文本图片。
后端接收代码如下:
String orderid = request.getParameter("orderId"); String image = request.getParameter("file_img"); /*进行base64解码*/ byte[] images = Base64.decodeBase64(image); File picFile = new File( "D:\\feng\\perl-work\\zzq\\emission\\imageUpload\\" + directory + "\\" + saveName + ".png"); if (picFile.getParentFile() != null && !picFile.getParentFile().exists()) { picFile.getParentFile().mkdirs(); } if (!picFile.exists()) { picFile.createNewFile(); } /*将bytes写入文件*/ FileOutputStream fos = new FileOutputStream(picFile); fos.write(images); fos.close();
由于前台有一个简单的压缩算法,使用了canvas对象的toDataURL方法,会将图片进行base64编码,因此后台接收的时候需要将对应的字符串进行解码。
小结:其实压缩图片上传是个很常见的业务,但是这其中的细节确实值得了解。最开始我们使用接口的形式,但是由于前后端不在一个服务器上,js调用的时候出现了跨域的问题。当我们使用jsonp传递参数试图解决这个问题的时候,由于图片压缩完是一个很长的字符串,因此可能超出了jsonp的限制,传输失败。这时候我们转用表单提交图片。由于对H5方法不熟悉,并且JS代码中压缩完的图片赋值给了一个hidden标签,对后台解析造成了很大的影响。事后推测,应该是浏览器对enctype=”multipart/form-data”形式的表单有自动的封装定义,即使将文件形式字符传给了hidden域,最终完成传递工作的还是type=“file”类型的input,而发现这个问题足足用了两天的时间,可以说是一个比较深刻的教训了。
- java存储H5上传的图片
- 基于H5的图片上传解析
- H5+ 图片压缩上传
- H5图片上传插件
- H5 FileReader 上传图片
- H5 图片压缩上传
- h5上传图片
- H5图片上传预览
- H5图片上传
- H5图片上传
- h5多图片上传
- 七牛云存储java上传图片
- 七牛云存储java上传图片
- H5图片压缩与上传
- webView支持H5上传图片
- H5页面上传图片控件
- H5 图片压缩上传解决方案
- H5图片压缩与上传
- dubbo协议参考
- 反转单向链表 (java 语言实现)
- [034]八大排序算法详解——基数排序
- 求数列的和
- Linux 错误代码含义/Linux Error Code
- java存储H5上传的图片
- phantomjs#0基础
- HBase连接池 -- HTablePool被Deprecated以及可能原因是什么
- 设置webview突出显示的内容
- Android 6.0权限的问题
- UChar* m_puhWidth的输出
- android在线边缓存边播放mp4
- Android界面编辑经验之谈
- Maven OSChina 镜像