大家好,欢迎来到IT知识分享网。
文件上传
前端提交文件方式:
- 请求方式为POST:< form action=”uploadServlet” method=”post” />
- 使用file的表单域:< input type=”file” name=”file” />
- 用multipart/form-data的请求编码方式:< form action=”uploadServlet” method=”post” enctype=”multipart/form-data” />
< form action="uploadServlet" method="post" enctype="multipart/form-data">
File: < input type="file" name="file"/>
< input type="submit" value="Submit"/>
</ form>
方式一:JavaWeb 的HttpServlet
-
需要commons-fileupload-1.4.jar ,commons-io-2.11.0.jar, 使用HttpServletRequest时需要导入servlet-api的包
commons-fileupload需要commons-io
-
需要在web.xml中添加servlet映射路径
public class FileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 文件上传
// 1. 判断上传的表单是普通表单还是文件表单
if(!ServletFileUpload.isMultipartContent(req)){
return ; // 终止程序,说明这是一个普通的表单
}
// 2. 创建上传文件的保存路径,建议在web-inf目录下,用户不能直接访问到
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
File file = new File(uploadPath);
// 目录不存在就创建这个目录,针对第一次上传时
if(!file.exists()){
file.mkdir(); // 创建目录
}
// 缓存,针对上传的文件较大时,存入缓存文件中,需要永久保存才转到upload文件夹下
/**处理文件上传,一般都会通过流的方式进行操作,
* 这里使用apache提供的组件进行实现 common-fileupload
* */
// 3. 获取DiskFileItemFactory对象,处理文件上传的路径或者大小限制,都有默认的
DiskFileItemFactory factory = new DiskFileItemFactory();
//4. 获取ServletFileUpload
ServletFileUpload upload = new ServletFileUpload(factory);
// 5. 处理上传的文件
//把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
try {
List<FileItem> fileItems = upload.parseRequest(req);
// 遍历每一个FileItem,表单中的每一项input被封装成一个FileItem对象
for (FileItem fileItem : fileItems) {
// 判断是否是普通类型,表单中的项
if (fileItem.isFormField()){
// 普通类型
}else {
//文件类型
// 获取到上传的文件的路径,进而获取到文件名
String filePath = fileItem.getName();
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
// 通过uuid+fileName获取到新的文件名
String newFileName = UUID.randomUUID().toString() + fileName;
// 获取FileItem的流
InputStream in = fileItem.getInputStream();
// 把文件复制服务器上
String newFilePath = uploadPath+"/" + newFileName;
FileOutputStream out = new FileOutputStream(newFilePath);
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1){
out.write(buffer,0,len);
}
// 关闭资源 , 清除fileItem的缓存
out.close();
in.close();
fileItem.delete();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
}
MultipartResolver 是一个接口,它的实现类如下图所示,分为 CommonsMultipartResolver 类和 StandardServletMultipartResolver
方式二:CommonsMultipartResolver
基于Apache fileupload文件上传(了解)
在web阶段中我们用到的是 Apache fileupload这个组件来实现上传,在springmvc中对它进行了封装,让我们使用起来比较方便,但是底层还是由Apache fileupload来实现的。
-
需要commons-fileupload-1.4.jar ,commons-io-2.11.0.jar
commons-fileupload需要commons-io
-
配置MultipartResolver处理器(文件上传解析器) bean的名字必须为:multipartResolver
<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<property name="maxUploadSize" value="10485760000" />
<property name="maxInMemorySize" value="40960" />
</bean>
解析HttpServletRequest的方式
@RequestMapping(value = "/addproduct", method = RequestMethod.POST) @ResponseBody private Map<String, Object> addProduct(HttpServletRequest request) { Map<String, Object> modelMap = new HashMap<String, Object>(); //接受前端参数的变量的初始化,包括商品、缩略图、详情图列表实体类 ObjectMapper mapper = new ObjectMapper(); Product product = null; String productStr = HttpServiceRequestUtil.getString(request, "productStr"); MultipartHttpServletRequest multipartRequest = null; ImageHolder thumbnail = null; List<ImageHolder> productImgList = new ArrayList<ImageHolder>(); //通用的解析器 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext()); try { //若请求中存在文件流,则取出相关的文件(包括缩略图和详情图) //isMutipart是用来判断是否有文件上传 if (multipartResolver.isMultipart(request)) { multipartRequest = (MultipartHttpServletRequest) request; //取出缩略图并构建ImageHolder对象 CommonsMultipartFile thumbnailFile = (CommonsMultipartFile) multipartRequest.getFile("thumbnail"); thumbnail = new ImageHolder(thumbnailFile.getOriginalFilename(), thumbnailFile.getInputStream()); //取出详情图列表并构建List<ImageHolder>列表对象,最多支持六张图片上传 for (int i = 0; i < IMAGEMAXCOUNT; i++) { CommonsMultipartFile productImgFile = (CommonsMultipartFile) multipartRequest.getFile("productImg" + i); if (productImgFile != null) { ImageHolder productImg = new ImageHolder(productImgFile.getOriginalFilename(), productImgFile.getInputStream()); productImgList.add(productImg); } else { //若取出的第i个详情图片文件流为空,则终止循环 break; } } } else { modelMap.put("success", false); modelMap.put("errMsg", "上传图片不能为空"); return modelMap; } } catch (Exception e) { modelMap.put("success", false); modelMap.put("errMsg", e.toString()); return modelMap; } }
狂神文件输入输出的上传:
@Controller
public class FileController {
//@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
//批量上传CommonsMultipartFile则为数组即可
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
//获取文件名 : file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
//如果文件名为空,直接回到首页!
if ("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
System.out.println("上传文件名 : "+uploadFileName);
//上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
//如果路径不存在,创建一个
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
System.out.println("上传文件保存地址:"+realPath);
InputStream is = file.getInputStream(); //文件输入流
OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
//读取写出
int len=0;
byte[] buffer = new byte[1024];
while ((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
os.flush();
}
os.close();
is.close();
return "redirect:/index.jsp";
}
}
transferTo()形式上传:
/*
* 采用file.Transto 来保存上传的文件
*/
@RequestMapping("/upload2")
public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
//上传文件地址
System.out.println("上传文件保存地址:"+realPath);
//通过CommonsMultipartFile的方法直接写文件(注意这个时候)
file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));
return "redirect:/index.jsp";
}
方式三:StandardServletMultipartResolver
基于Servlet3.0以上版本的文件上传
-
需要依赖Servlet3.0以上版本
-
配置MultipartResolver处理器(文件上传解析器) bean的名字必须为:multipartResolver
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
-
Conreoller
@RequestMapping("/upload")
public Result<?> upload(MultipartFile file, HttpServletRequest request) throws IllegalStateException, IOException {
Result<Object> result = new Result<>();
result.setSuccess(false);
//检查文件是否为空
if (file.isEmpty()) {
result.setMessage("上传文件不能为空");
return result;
}
//检查文件大小 2097152 =2M
if(file.getSize() > 2097152) {
result.setMessage("文件大于2M");
return result;
}
//检查是否是图片
try {
BufferedImage bi = ImageIO.read(file.getInputStream());
if(bi == null){
result.setMessage("不是图片");
return result;
}
} catch (IOException e) {
e.printStackTrace();
}
// 获取文件存储路径(绝对路径),实际开发中,建议直接使用一个服务器的绝对地址
String path = request.getServletContext().getRealPath("/WEB-INF/upload/");
// System.out.println("服务器中的相对/WEB-INF/upload/完整路径:"+path);
//获取上传文件后缀名
// System.out.println("客户端上传的文件名:"+file.getOriginalFilename());
String originalFilename = file.getOriginalFilename();
String suff = originalFilename.substring(originalFilename.lastIndexOf("."));
// 获取文件名
String fileName = UUID.randomUUID().toString().replaceAll("-","")+suff;
// 创建文件实例
File filePath = new File(path, fileName);
// 如果文件目录不存在,创建目录
if (!filePath.getParentFile().exists()) {
filePath.getParentFile().mkdirs();
System.out.println("创建目录" + filePath);
}
// 写入文件
file.transferTo(filePath);
result.setMessage("上传成功");
result.setCode(200);
result.setSuccess(true);
return result;
}
说明:如果前端的文件上传控件的name名和处理器方法参数名不一致可以使用该注解@RequestPart(“参数名”)或@RequestParam(“参数名”)
@RequestPart在前后端不分离的文件上传(基于表单文件上传)中和@RequestParam意义效果一致
@RequestPart可以处理特殊的数据格式,如JSON
一致:(实际开发中建议方式)
//前端:
<input type="file" name="file">
//后端:
public String upload(MultipartFile file, HttpServletRequest request){}
如果不一致:
//前端:
<input type="file" name="uploadFile">
//后端:
public String upload(@RequestParam("uploadFile") MultipartFile file, ....){}
//或
public String upload(@RequestPart("uploadFile") MultipartFile file, ....){}
多文件上传
多文件上传只需要把html代码中的多个< input type=”file” name=”file” >name属性设置为一样的就好。然后在controller中使用MultipartFile数组接受就行。
@RequestMapping(value="/upload", method=RequestMethod.POST)
public String fileUpload(@RequestParam("file") MultipartFile[] file){
//遍历数组单个上传
for (MultipartFile multipartFile : file) {
}
}
补充:如果想要限制文件上传类型
解决思路:
1)基于前端,限制文件类型
2)基于后端,建议使用SpringMVC框架的拦截器进行拦截校验
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/32524.html