base64轉圖片問題javax.imageio.IIOException: Invalid JPEG file structure: two SOI markers

報錯信息:
javax.imageio.IIOException: Invalid JPEG file structure: two SOI markers
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1231)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1034)
	at javax.imageio.ImageIO.read(ImageIO.java:1448)
	at javax.imageio.ImageIO.read(ImageIO.java:1308)
	at com.hlxd.base.BaseController.uploadCaseMainPicImgByBase64(BaseController.java:272)
	at com.hlxd.controller.ws.AppDesignerControllerImpl.updateMyInfo(AppDesignerControllerImpl.java:188)

	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.j
ava:104)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.
java:749)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java
:689)

	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at com.hlxd.base.CorsFilter.doFilter(CorsFilter.java:37)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)

	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)

	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)  

檢查發現前端傳過來的base64字符串在傳輸過程中被改變了

這是後端接收到的字符串:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4 JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCAB8AHwDASIAAhEBAxEB/8QAGgABAAMBAQEAAAAAAAAAAAAAAAQFBgMBAv/EADwQAAEDAwMCAwYCBQ0AAAAAAAEAAgMEBREGEiETMUFRYRQVMnGBsSKRI0KhssEHJCUzNTZDYnOCo9Hw/8QAGwEBAAMBAQEBAAAAAAAAAAAAAAMEBQECBgf/xAAqEQACAgEDAwIFBQAAAAAAAAAAAQIDERIhMQQiQVFhExQjgZEyM3HB4f/aAAwDAQACEQMRAD8A3aIi/NDaCIiAIiIAiIgCIiAIiIAiIgCIiAIiIAiIgCIiAIiIAiIgCIiAIiIAiIgCKjsuo5LxHPI2gcxsAyQ2QOLj5DIC723Udvuc3s8b3xT8/opW4PCmlRZHOVwWJ9NbBtOPHPsWqIo09xpKWpjp55hHJL8AcMA/XsolFvZEMYuTwiSiz9w1O jvgtjKNsrnlrWvMu3l30Kuqqc01FLUFuTHGX7c98DOMqSVU44yueCWdFkNOpfq4OyKj0/qKS yTD2NsLYQNzuruJJz4Y9FeAg9jlebK5VvTI821Tqk4TW4RU9/v4sYgJp t1i79fbjGPT1VhQ1RraOOoML4eoAQ15GcfQrrrkoqbWzDpnGtWNbMkIqG4apit9493upXy8AbmHncfDH5eKvWOL2NcWlpIzg9wk65QSclyJ0zrScls D1EBBzgg aKMjCIiHDD6RutLa7fUvqzI1jpB IRucO3mBhdaiG21l1ZeqN9U4NcHmOKleRI4f5sYChCAxaCdIRjrVG4fmB/BR33cwaYpbfTvLZXvc95aeQA7j9v2W5oUpucec4Z9TKl2WSsre7lpfpjG5qbJfLhVVBguFunh3OJjkETg0DyPH7U1db46 hizUw07435DpnbQQRyPspWnYbhFbWOuFQZHvaCGubywep8VBuek4rje21jpNsDxmVg7kjtj5/wDu6pKVcb8p4wZMZVw6lyzpx6bmZfIyXU1D0ajrhjoWdXHxEYBK2Fyp7oLZUmSvgcwROJaKYjIx571nbhROZrSnjpqciON0RAY3hoGFZ 857jXT2d9a2CR26Pa l7j0If5KzZ3aZLhblzqe/wCHKHCSfGdvwVmi4auYVwpaplOcMDi6Lfn4u3IwtBZbHV2md73XQ1EUhLnxuixl3nnPdRbfpastkNRHS3VrPaAA53s/Ixnsd3qpmnaN9FA Nt0bXQtcWhoZgxuHcZyfyUN9ilqcJLH8f4QdZfG2U51yWHjbHt64KnUtNJeNSUdujcAGR7nEjIaCefsFzvNVeqe701JT1jXujZ1D049jGjn4uTxgKdfKOSit10uXULamZzA1zCQWMDgAAfuvjTtILnp97qmWR0k78SvLiXPaDw3PkvcJxValylsSQsUaY2PDjHbGPL3bKyy26uvVzlvT3xxbX7mOewvBPbgZHZWVpvVdeZ3Q09UGFrcuc6kGB/yKv0vX3OoqJbfDVsZFGwuaJIt MEDA5HmoelzVNFfJS1DYXRw7iXR7s9 3IwppxbUs42xj2LN9Tm7NWO3GPZP7GntOn6y2Vrqj3sZmSOLpY3RfGfPvwVfLK6Jr66sZUMqJ rFFjG/lwJ9fJapZnU6lZiTyzG62NkbnGx5aCIirlMy2q2U1v01FQMeAQWtY0nlwHcqBpDTzKnbc6nDo2u/RM8yPEqXeNLzy26aqfM tuBwc9gBnkNHyVbbblqG1UbaSC1vdG0kgvp3k88 C14ZlS41y3yfRVyb6Rwpn3N7 PwbiWrjhqoKZ2d8 7bj0GSo1XTPaXzvu09PF3IzGGt/NqzNHU6hrr/S1U9A5gj/CQY3Ma1p I8 K1MlooZ5utPAJn5z lcXgfIE4CpygqZLL/sy7alRJJvO3jcyN11G6B/St1zqp355keGBv0/Dkru60XGh/py4VDjO0jqdFrS5rMYzyMZHH0zyq/UkNZU380sVFjotDYmRNzlncFamkiv1bHi4OpqWMjBjYzc5w8uSR91dnJQhFxws8mna400wcMLPPrgprldppGiC019dXSPH4ixrdrQfkzOfsrTTdjFAPasVdO94w GWRrmu9eB/0VVXGw3OyVDquyySGE8ljOS36frBWWmbrd7pudUshEEZ2uftIcT5eS8W/s/Tax59SG K XzS1p8 v3RK1b/dqr/2fvBQ9JVUFPYYmSyta SRwY3xcc AUjWEVVLYpG0/LdwMrQMkt9PrhcdLad93QCrqm/wA6kHAP G0 HzUMHBdN3PyQwda6BqT31cfYpdF/27U/6Lv3go2maiGCG5daVke Ahu5wGTzwtbaNN01nqJamOWSSWRpad2MAZysxpCiZcPeFNLnZJEASPDlWviwmpy8bF/5iu1XTXHaWH8n/wDV13zZ/FbBQLTZqWzQOiptx3nLnPOSVPWb1E1OxyXBjdZdG6 U48MIiKAqBMIiHQiIgPNoyXYGcd16iIAgGOwwiIAiIgC IoIoGbIY2Rt8mNAC 0TLGXjAREQ4EREAREQBERAEREAREQBERAEREAREQBERAEREAREQBERAEREAREQBERAEREAREQH/2Q==

這是前端瀏覽器下看到的字符串:

data:image/jpeg;base64,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

仔細檢查發現


字符串中的加號“+”被替換成了空格“ ”

找到了問題,自然有了解決方案:重新替換過來即可。由於base64字符串都不會有空格,所以替換回去不會有問題。

      /**
	 * 上傳案例主圖
	 * @param imgStr
	 * @return
	 * @author heh
	 * @date Oct 12, 2017
	 * @modifytime 2017-12-14
	 */
	protected String uploadCaseMainPicImgByBase64(String imgStr){
		if(imgStr.length() > 50) {
			imgStr = imgStr.substring(imgStr.indexOf("base64,")+7).replace(" ", "+");
			String imgs = "";
			try {
				if(null==imgStr){
					return imgs;
				}
				String base64str = imgStr;
				BASE64Decoder decoder = new BASE64Decoder();    
				//Base64解碼  
				byte[] b = decoder.decodeBuffer(base64str);    
				for(int j=0;j<b.length;++j) {
					if(b[j]<0){//調整異常數據    
						b[j]+=256;
					}    
				}    
				//生成jpeg圖片
				Map paramMap = SysCache.getSysCaches("commonParamPro");
				String _path = (String) paramMap.get("imgUpload.path");
				Long timestamp = System.currentTimeMillis();
				String imgName = timestamp + ".jpg";
				String imgFilePath = _path + "/" + imgName;//新生成的圖片 
				OutputStream out = new FileOutputStream(imgFilePath);   
				out.write(b);    
				out.flush();    
				out.close();
				imgs = "/img/upload/" + imgName;
				// 生成app專用圖片
				String imgFilePath_app = _path + "/" + timestamp + "_app.jpg";
				File f = new File(imgFilePath);
				BufferedImage bufferedImage = ImageIO.read(f);
				Integer width = bufferedImage.getWidth();
				Integer height = bufferedImage.getHeight();
				if(width > 2000){
					Float tmp = 2000/Float.valueOf(width);
					Float newHeight = Float.valueOf(height)*tmp;
					height = newHeight.intValue();
					width = 2000;
				}
				Thumbnails.of(f).forceSize(width/2, height/2).outputFormat("jpg").toFile(imgFilePath_app);
			}     
			catch (Exception e) {
				e.printStackTrace();
			}
			return imgs;
		}else {
			return imgStr;
		}
	}

問題是解決了,但是具體原因還沒有發現,爲什麼會在傳輸的過程中數據丟失。

網上找了一下解決方案,有這樣做的(因爲隔了N天才想起來寫博客,所以原文鏈接找不到了,只留下截圖,若原作者看到請指出來源,認爲侵權的請聯繫我刪除


但是用這個方法仍然沒有解決數據丟失的問題,這個事情告一段落吧,希望有知道原因的大神分享一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章