springmvc+mybatis 处理图片(一):上传图片
一直觉得上传图片文件之类的很难,所以最后才处理图片,发现也并没有那么难,开始正文。
思路:将前台上传的file存到MutipartFile类型字段中,再将MulipartFile转换为pojo类中的byte[ ]数组,最后存入数据库longBlob类型字段中
1. 数据库设计,将图片newsPic字段类型设置为longblob或blob
2. 准备jar包:commons-fileupload和commons-io,我用的是commons-fileupload-1.3.1.jar和commons-io-2.4.jar,也可以在这里下载。
3. 在springmvc-config.xml中进行上传文件的配置
<!-- 对上传文件的配置 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
<property name="maxUploadSize">
<value>32505856</value><!-- 上传文件大小限制为31M,31*1024*1024 -->
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
form表单里面有文件上传时,必须要指定enctype属性值为multipart/form-data,意思是以二进制流的形式传输文件。否则会报错上传不了。
而因为在form表单中增加了:enctype="multipart/form-data"这个属性,会将数据转换为二进制,导致接收到的值都为空值,因此要在spring的配置文件中配置multipartResolver
4. addNews.jsp
<form action="addNewst" method="post" enctype="multipart/form-data"> <table> <tr> <td> <input type="file" size="50" name="newsPicture"/> </td> </tr> <!--省略其他字段的代码--> </table> </form>
5. NewsMapper.java和NewsDynaSqlProvider.java
(1) NewsMapper.java
//动态插入新闻 @SelectProvider(type=NewsDynaSqlProvider.class,method="insertNews") void save(News news);
(2) NewsDynaSqlProvider.java
//动态插入 public String insertNews(final News news){ return new SQL(){ { INSERT_INTO("news"); if(news.getNewsTitle() != null && !news.getNewsTitle().equals("")){ VALUES("newsTitle", "#{newsTitle}"); } if(news.getNewsAbstract() != null && !news.getNewsAbstract().equals("")){ VALUES("newsAbstract", "#{newsAbstract}"); } if(news.getNewsAuthor() != null && !news.getNewsAuthor().equals("")){ VALUES("newsAuthor", "#{newsAuthor}"); } if(news.getNewsTime() != null && !news.getNewsTime().equals("")){ VALUES("newsTime", "#{newsTime}"); } if(news.getNewsContent() != null && !news.getNewsContent().equals("")){ VALUES("newsContent", "#{newsContent}"); } if(news.getNewsPic() != null && !news.getNewsPic().equals("")){ VALUES("newsPic", "#{newsPic,jdbcType=BLOB}"); } } }.toString(); }
6. TestService.java和TestServiceImpl.java
(1) TestService.java
/** * 添加新闻 * @param News 新闻对象 * @MultipartFile newsPic 新闻图片 * @throws Exception */ void addNewsAndPic(News news, MultipartFile newsPic) throws Exception;
(2) TestServiceImpl.java
@Override public void addNewsAndPic(News news, MultipartFile newsPic) throws Exception { byte[] b1 = newsPic.getBytes(); news.setNewsPic(b1); newsMapper.save(news); }
7. NewsController.java
/** * 处理添加请求 * @param String flag 标记, 1表示跳转到添加页面,2表示执行添加操作 * @param News news 要添加的新闻对象 * @param ModelAndView mv * @throws Exception * */ @RequestMapping(value="/addNewst") public ModelAndView addNewst(String flag, @ModelAttribute News news, MultipartFile newsPicture, ModelAndView mv, HttpSession session) throws Exception{ if(flag.equals("1")){ mv.setViewName("addNews"); }else{ testService.addNewsAndPic(news, newsPicture); mv.setViewName("redirect:/htNews"); } return mv; }
SpringMVC中从前台到后台通过表单传递数据:
(1) 表单的name属性值必须和接受的参数同名。否则,接收到的参数为null
(2) 表单的name属性值必须和接收对象的属性同名。否则,接收到的参数为null
8. News.java
public class News implements Serializable{ private Integer newsID; private String newsTitle; private String newsAbstract; private String newsAuthor; @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date newsTime; private String newsContent; private byte[] newsPic;//新闻照片 public News(){ super(); } //setter and getter }
参考:https://blog.csdn.net/j277699931/article/details/50413864
二、.jsp改进,读取input:file的路径后,显示本地图片
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>title</title> <style type="text/css"> #imagePreview { width: 160px; height: 120px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale); } </style> </head> <body> <form action="addNewst" id="newsForm" method="post" enctype="multipart/form-data"> <table> <tr> <td> <div id="imagePreview"></div> <input id="imageInput" type="file" size="50" name="newsPicture" onchange="loadImageFile()"/> </td> </tr> <!--省略其他代码--> </table> </form> <script type="text/javascript"> var loadImageFile = (function () { if (window.FileReader) { var oPreviewImg = null, oFReader = new window.FileReader(), rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i; oFReader.onload = function (oFREvent) { if (!oPreviewImg) { var newPreview = document.getElementById("imagePreview"); oPreviewImg = new Image(); oPreviewImg.style.width = (newPreview.offsetWidth).toString() + "px"; oPreviewImg.style.height = (newPreview.offsetHeight).toString() + "px"; newPreview.appendChild(oPreviewImg); } oPreviewImg.src = oFREvent.target.result; }; return function () { var aFiles = document.getElementById("imageInput").files; if (aFiles.length === 0) { return; } if (!rFilter.test(aFiles[0].type)) { alert("You must select a valid image file!"); return; } oFReader.readAsDataURL(aFiles[0]); } } if (navigator.appName === "Microsoft Internet Explorer") { return function () { alert(document.getElementById("imageInput").value); document.getElementById("imagePreview").filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = document.getElementById("imageInput").value; } } })(); </script> </body> </html>
效果如图:
参考:https://blog.csdn.net/dracotianlong/article/details/38046939
------------------------------------------------------分界线------------------------------------------------------------
遇到的错误:
1. SpringMVC表单提交后,Controller接收到的值都是null,如图
报错如下:
四月 13, 2018 10:43:33 上午 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.service() for servlet [springmvc] in context with path [/SpringDemo] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException at com.game.controller.NewsController.addNewst(NewsController.java:58)
原因:没有配置multipartResolver,参考:https://blog.csdn.net/MODjie/article/details/79076455
2. 点击”新闻管理“的界面,就在显示图片的controller中报空指针异常java.lang.NullPointerException,但是页面的所有功能都能正常使用,开始始终不明白怎么回事,后来发现是因为有的新闻没有添加图片,造成在加载页面获取新闻的二进制文件流时报空指针异常。
java.lang.NullPointerException at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:106) at com.game.controller.NewsController.newsPic(NewsController.java:105)
如图:
------------------------------------------------------分界线------------------------------------------------------------
Mysql中的BLOB数据类型
在计算机中,BLOB是数据库中经常用来存储二进制文件的字段类型,典型的BLOB是一张图片或一个声音文件。
MySQL中,BLOB是个类型系列,包括:TinyBlob、Blob、MediumBlob、LongBlob,这几个类型之间的唯一区别是存储文件的最大大小的不同。
类型 | 大小(单位:字节) |
TinyBlob | 最大 255 |
Blob | 最大 65K |
MediumBlob | 最大 16M |
LongBlob | 最大 4G |