范例说明
在网页中,上传以及下载文件是最常用的功能之一,比如用户设置个人信息时,上传本地图片作为自己的头像。电商网站管理员在后台为某件商品上传图片。诸如此类操作数不胜数,而上传和下载文件所涉及到的知识点和难点十分多,本例就以一个简单例子,基于SSM(Spring + SpringMVC + Mybatis)框架为大家演示一次。上传本地图片到服务器的例子,为大家排疑解惑。实验过程如图所示:
注意:本例不教如何搭建 SSM(Spring + SpringMVC + Mybatis)框架 ,请大家一定要在 SSM(Spring + SpringMVC + Mybatis)框架 搭建好的基础上来进行操作。
技术要点
(1)FormData 对象
运用该对象接口,调用其 append 方法,将需要上传的数据一个个加进去。
语法:
var formFile = new FormData ();
formFile.append("userPhoto", userPhotoObj);formFile.append("uid", uid);
(2) 利用 ajax 方式 或者 post 方式提交数据到服务器。
将需要的数据,处理数据的地址,若用 ajax 方式提交可以写返回函数来验证结果。若用 post 方式提交则观察跳转页面的结果显示进行验证。
语法:
$.ajax();或者
post(url, params)
(3) PhotoUtil 自定义工具类
提供相关处理上传图片的方法。
语法:
public static BufferedImage change2jpg(File f){}
(4)通过session获取文件存储的位置。
语法:
session.getServletContext().getRealPath("img/userPhoto");
(1)数据库中的 userPhoto 表以及 userPhoto 关联的 user 表。
要先在数据库创建对应的 userPhoto 表来储存相应的用户头像信息。
CREATE TABLE userPhoto ( id int(11) NOT NULL AUTO_INCREMENT, uid int(11) DEFAULT NULL, PRIMARY KEY (id), CONSTRAINT fk_userPhoto_user FOREIGN KEY (uid) REFERENCES user (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
注意:本例只给出关键代码,非相关代码请自行填补完整。
(2)UserPhoto 实体类。
用来与数据库中的userPhoto表进行映射。
package com.pojo; public class UserPhoto { private Integer id; private Integer uid; private User user; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
(3)UserPhotoMapper 类
用来与配置文件中的 UserPhotoMapper.xml 进行映射
public interface UserPhotoMapper { void add(UserPhoto up); }
(4)UserPhotoService接口
功能接口
public interface UserPhotoService { void add(UserPhoto up); }
(5)UserPhotoServiceImpl类
UserPhotoService接口的实现类
@Service public class UserPhotoServiceImpl implements UserPhotoService { @Autowired UserPhotoMapper userPhotoMapper; @Override public void add(UserPhoto up) { userPhotoMapper.add(up); } }
(6)SpringMVC配置文件
添加上传文件相关配置信息。
<!-- 对上传文件的解析--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/> </beans>
注意:基础配置信息本教程不提供,只提供上传文件必须的相关配置信息。
(7)uploadPhoto 功能类 (存放在util包,大家自己创建)
用于文件的注入。在服务器方法中获取上传文件。
public class UploadPhoto { /*MultipartFile 类型的属性,用于接受上传文件的注入*/ MultipartFile userPhoto; public MultipartFile getUserPhoto() { return userPhoto; } public void setUserPhoto(MultipartFile userPhoto) { this.userPhoto = userPhoto; } }
注意:这里MultipartFile的变量名 "userPhoto" 一定要与上传文件代码<input type="file' name="userPhoto">的name值相同
(8)PhotoUtil工具类(存放在util包中,大家自己创建)
提供相关处理上传图片的方法。
change2jpg(File f) 方法是为了将上传的图片都转换成 jpg格式文件,这样方便保存以及不会使得图片格式杂乱。如果需要统一转成别的方式也可以自行修改。 (有很低的几率出现问题)
如果仅仅使用 ImageIO.write(img, "jpg", file); 不一定能能将使 jpg图片显示正常。
public class PhotoUtil { public static BufferedImage change2jpg(File f) { try { Image i = Toolkit.getDefaultToolkit().createImage(f.getAbsolutePath()); PixelGrabber pg = new PixelGrabber(i, 0, 0, -1, -1, true); pg.grabPixels(); int width = pg.getWidth(), height = pg.getHeight(); final int[] RGB_MASKS = { 0xFF0000, 0xFF00, 0xFF }; final ColorModel RGB_OPAQUE = new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]); DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight()); WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null); BufferedImage img = new BufferedImage(RGB_OPAQUE, raster, false, null); return img; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } }
(9)上传文件页面代码:
<table style="margin:15px auto;" border:1> <tr> <td> <input type="text" id="user" value="请输入用户ID" /> <input id="userPhoto" type="file" name="userPhoto" /> <button id="uploadUserPhotoButton">上传</button> </td> </tr> </table>
(10) 处理页面数据并上传部分js函数。 (本例使用ajax方式提交数据,如果需要post方式提交请自行更改)
$(function(){ $("#uploadUserPhotoButton").click(function(){ var userPhotoObj = document.getElementById("userPhoto").files[0]; if(typeof (userPhotoObj) == "undefined" || userPhotoObj.size <= 0){ alert("请选择图片"); return; } var uid = $("#user").val(); var formFile = new FormData(); formFile.append("userPhoto", userPhotoObj); formFile.append("uid", uid); var data = formFile; $.ajax({ url: "addUserPhoto", data: data, type: "post", dataType: "json", processData: false,//用于对data参数进行序列化处理 这里必须false contentType: false, //必须 }); return false; }); }); });
注意: 这一步十分重要,请大家一定要注意填写。出现问题的时候很可能是某个标点或者某个字母。
(10)addUserPhoto 上传文件功能方法。
该方法接受页面上传的数据和文件并且处理。
1. 将数据插入数据库。
2.根据session.getServletContext().getRealPath("img/userPhoto");获取文件存储的位置。
3.文件名以 " xxx .jpg"的形式保存。
4.通过uploadPhoto保存文件。
5.通过PhotoUtil.change2jpg() 将文件将换成真正的 jpg文件,而不仅仅是后缀名为jpg。
6.最后返回处理信息。
@RequestMapping("addUserPhoto") @ResponseBody public String addUserPhoto(String uid, HttpSession session, UploadedImageFile uploadedImageFile){ UserPhoto up = new UserPhoto(); up.setUid(Integer.parseInt(uid)); userPhotoService.add(up); String ImageFolder = session.getServletContext().getRealPath("img/userPhoto"); String ImageName = "用户"+uid+"的图片"+".jpg"; File f = new File(ImageFolder, ImageName); f.getParentFile().mkdirs(); try{ uploadedImageFile.getUserPhoto().transferTo(f); BufferedImage img = ImageUtil.change2jpg(f); ImageIO.write(img , "jpg", f); } catch (Exception e) { e.printStackTrace(); return "fail"; } return "success"; }
(11)存放文件的位置
当收到页面返回信息,大家可以到自定义存放文件的位置,查看是否有上传成功并保存。