这个是垃圾识别系统功能的一部分,方法比较笨拙,实现了前端传图片利用js转化成base64编码,并在前端界面现实预览,传到后端转成ByteArrayInputSteam,再调用百度识物的api,返回图片中的内容。特此记录踩过的坑和学习到的东西。
1、blob地址 浏览器缓存 不等于 服务器缓存
在实现上传图片预览的时候用到了涉及到了blob。Binary Large Object的缩写,直译为二进制大对象,一般用于隐藏视频播放器的真实地址。个人理解是图片能以blob地址的形式储存在浏览器缓存中,但是本地服务器并无法使用,后端没法通过blob地址找到对应的服务器资源(加密的体现),所以本来想避免巨大的base64字符串的在前后端的笨拙传送,但是此路不通QuQ。
(或许也通,但是我没有学会对应的方法……)
2、base64太大传不过去的问题
虽然知道这个方法比较蠢,但是确实可以解决问题。必然的会有巨大的base64文件报400错误,header太大卡住了。修改server xml里面的maxHttpHeaderSize ="xxxx" 属性,一般是1024的倍数(普通手机拍的照片加四个0还是够用的)添加但是明显感觉到网页传输的速度慢了一些,应该还可以优化。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxHttpHeaderSize ="10240000" />
3.js用到的 readerfile()其中的readAsDataURL
方法,它会读取指定的Blob 或File对象。读取操作完成的时候,readyState 会变成已完成DONE
,并触发 loadend事件,同时 result 属性将包含一个data:
URL格式的字符串(base64编码)以表示所读取文件的内容。
function bindPic() {
console.log(2);
$("#picSelect").change(function () {
var obj=$("#picSelect")[0].files[0];
var fr = new FileReader();
fr.onload=function () {
$("#picPreview").attr('src',this.result);
console.log(this.result);
$("#pic").val(this.result.replace(/^data:image\/[a-z]+;base64,/, ""));
};
fr.readAsDataURL(obj);
//$("#s").val(args);/*将服务端的图片url赋值给form表单的隐藏input标签*/
}
})
})
}
4.Base64解码的时候出现了很多的问题,最后发现是版本的问题。
import Decoder.BASE63decoder一直报错500,是这个包不支持较高的版本(忘记具体的是哪里的问题了),所以换了种方法。改成加载这个包,对应的构造实体的方法也有点不太一样,改过来就行
import org.apache.commons.codec.binary.Base64;
public class GarServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String b64 = request.getParameter("pic");
String pic = b64;
//System.out.println(pic);
byte[] bytes=pic.getBytes();
//file = new byte[in.available()];
//in.read(file);
Base64 base64=new Base64();
bytes=base64.decode(bytes);
//System.out.println(Arrays.toString(bytes));
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
System.out.println(inputStream);
//System.out.println(BDRequest.BaiDuRequest(bytes));
}
}
(垃圾小项目 健壮性 安全性基本没有 还有两周答辩希望把它完善好QuQ)