文件上传的前提:
- form 表单的 enctype 取值必须是:
multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型 - method 属性取值必须是
Post
- 提供一个文件选择域
<input type=”file” />
一、传统方式实现文件上传
上传的文件和访问的应用存在于同一台服务器上:
依赖:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="/user/fileupload1" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
controller:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/fileupload1")
public String fileupload1(HttpServletRequest request) throws Exception{
System.out.println("开始文件上传");
// 使用fileupload组件完成文件上传
// 上传的位置
String path = request.getSession().getServletContext().getRealPath("/uploads/");
//D:\apache\apache-tomcat-8.5.0\webapps\ROOT\uploads\
System.out.println("路径是:"+path);
// 判断路径是否存在
File file = new File(path);
if(!file.exists()){
// 创建该文件夹
file.mkdirs();
}
// 解析request对象,获取上传文件项
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析request
List<FileItem> items = upload.parseRequest(request);
// 遍历
for(FileItem item:items){
// 进行判断,当前item对象是否是上传文件项
if(item.isFormField()){
// 普通表单项
}else{
// 上传文件项
// 获取上传文件的名称
String filename = item.getName();
// 把文件的名称设置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid+"_"+filename;
// 完成文件上传
item.write(new File(path,filename));
// 删除临时文件
item.delete();
}
}
System.out.println("文件上传完毕");
return "success";
}
}
二、使用springmvc实现文件上传
配置文件解析器:
<!--配置文件解析器对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"></property>
</bean>
jsp:
<form action="/user/fileupload2" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload"><br>
<input type="submit" value="上传">
</form>
controller:
@Controller
@RequestMapping("/user")
public class UserController {
/**
* springmvc实现文件上传
*
* @param request
* @param upload 参数名必须和表单的name保持一致
* @return
* @throws Exception
*/
@RequestMapping("/fileupload2")
public String fileupload2(HttpServletRequest request, MultipartFile upload) throws Exception {
System.out.println("springmvc开始文件上传");
// 上传的位置
String path = request.getSession().getServletContext().getRealPath("/uploads/");
//D:\apache\apache-tomcat-8.5.0\webapps\ROOT\uploads\
System.out.println("路径是:" + path);
// 判断路径是否存在
File file = new File(path);
if (!file.exists()) {
// 创建该文件夹
file.mkdirs();
}
//获取文件名
String filename = upload.getOriginalFilename();
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid + "_" + filename;
// 完成文件上传
upload.transferTo(new File(path, filename));
System.out.println("springmvc开始文件上传完毕");
return "success";
}
}
三、使用springmvc实现跨服务器文件上传
在本地模拟一台文件服务器
pom.xml:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
jsp:
<form action="/user/fileupload3" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload"><br>
<input type="submit" value="上传">
</form>
controller:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/fileupload3")
public String fileupload3(MultipartFile upload) throws Exception {
System.out.println("springmvc跨服务器文件上传");
//获取文件名
String filename = upload.getOriginalFilename();
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid + "_" + filename;
//定义上传文件服务器路径
String path="http://localhost:8081/uploads/";
//创建客户端对象
Client client = Client.create();
//连接图片服务器
WebResource resource = client.resource(path + filename);
// 完成文件上传
resource.put(upload.getBytes());
System.out.println("springmvc开始文件上传完毕");
return "success";
}
}
四、Springmvc文件上传到ftp服务器
FileServiceImpl:
package com.hcx.service.impl;
import com.google.common.collect.Lists;
import com.hcxmall.service.IFileService;
import com.hcxmall.util.FTPUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* 文件上传
*
* @author HCX
* @create 2017 - 11 - 16 15:01
*/
@Service("iFileService")
public class FileServiceImpl implements IFileService{
private Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
@Override
public String upload(MultipartFile file,String path){
String fileName = file.getOriginalFilename();
//获取扩展名
String fileExtensionName = fileName.substring(fileName.lastIndexOf(".") + 1);
//为了防止用户上传了相同的文件名
String uploadFileName = UUID.randomUUID().toString()+"."+fileExtensionName;
//记录日志
logger.info("开始上传文件,上传文件的文件名:{},上传的路径:{},新文件名:{}",fileName,path,uploadFileName);
File fileDir = new File(path);
if(!fileDir.exists()){
//赋予权限:可写
fileDir.setWritable(true);
//makedir():当前级别
//makedirs():如果上传的文件所在的文件夹是-a-b-c-d,上传到服务器 这些目录都没有,则使用makedirs()
fileDir.mkdirs();
}
File targetFile = new File(path,uploadFileName);
try {
file.transferTo(targetFile);
//文件已经上传成功了
//将targetFile上传到我们的FTP服务器上
FTPUtil.uploadFile(Lists.newArrayList(targetFile));
//上传完之后,删除upload下面的文件
targetFile.delete();
} catch (IOException e) {
logger.error("上传文件异常",e);
return null;
}
return targetFile.getName();
}
}
FTPUtil:
package com.hcx.util;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
/**
* 文件上传到服务器
*
* @author HCX
* @create 2017 - 11 - 16 15:36
*/
public class FTPUtil {
private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class);
private static String ftpIp = PropertiesUtil.getProperty("ftp.server.ip");
private static String ftpUser = PropertiesUtil.getProperty("ftp.user");
private static String ftpPass = PropertiesUtil.getProperty("ftp.pass");
private String ip;
private int port;
private String user;
private String pwd;
private FTPClient ftpClient;
public FTPUtil(String ip, int port, String user, String pwd) {
this.ip = ip;
this.port = port;
this.user = user;
this.pwd = pwd;
}
public static boolean uploadFile(List<File> fileList) throws IOException {
//port是固定的21
FTPUtil ftpUtil = new FTPUtil(ftpIp,21,ftpUser,ftpPass);
logger.info("开始连接ftp服务器");
//传到ftp服务器文件夹下的img文件夹
boolean result = ftpUtil.uploadFile("img",fileList);
logger.info("开始连接ftp服务器,结束上传,上传结果:{}");
return result;
}
/**
*
* @param remotePath 远程路径:上传到ftp服务器上,ftp服务器在Linux下是一个文件夹,
* 如果需要上传到ftp文件夹中再下一层文件的话,就需要使用remotePath,使上传的路径多一些
* @param fileList
* @return
* @throws IOException
*/
private boolean uploadFile(String remotePath,List<File> fileList) throws IOException {
boolean uploaded = true;
FileInputStream fis = null;
//连接FTP服务器
if(connectServer(this.ip,this.port,this.user,this.pwd)){
try {
//更改工作目录:切换文件夹,不想切换传空即可
ftpClient.changeWorkingDirectory(remotePath);
//设置缓冲区
ftpClient.setBufferSize(1024);
ftpClient.setControlEncoding("UTF-8");
//文件类型设置成二进制,防止乱码
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
//打开本地被动模式
ftpClient.enterLocalPassiveMode();
for(File fileItem : fileList){
fis = new FileInputStream(fileItem);
//存储文件
ftpClient.storeFile(fileItem.getName(),fis);
}
} catch (IOException e) {
logger.error("上传文件异常",e);
uploaded = false;
e.printStackTrace();
}finally {
//关闭流
fis.close();
//释放连接
ftpClient.disconnect();
}
}
return uploaded;
}
/**
* 连接ftp服务器
* @param ip
* @param port
* @param user
* @param pwd
* @return
*/
private boolean connectServer(String ip,int port,String user,String pwd){
boolean isSuccess = false;
ftpClient = new FTPClient();
try {
//连接
ftpClient.connect(ip);
//登录
isSuccess = ftpClient.login(user,pwd);
} catch (IOException e) {
logger.error("连接FTP服务器异常",e);
}
return isSuccess;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public FTPClient getFtpClient() {
return ftpClient;
}
public void setFtpClient(FTPClient ftpClient) {
this.ftpClient = ftpClient;
}
}
上传到ftp服务器的一些配置信息hcxmall.properties:
ftp.server.ip=182.92.82.103
ftp.user=hcxmallftp
ftp.pass=ftppassword
#搭建的图片服务器的前缀
ftp.server.http.prefix=http://img.hcxmall.com/
读取properties文件的工具类:
package com.hcx.util;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
/**
* 配置文件工具类
* @author HCX
* @create 2017 - 11 - 15 18:28
*/
public class PropertiesUtil {
private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
private static Properties props;
//在tomcat启动时读取里面的配置:使用静态代码块
//执行顺序:静态代码块(在类被加载的时候执行且仅执行一次)>普通代码块>构造代码块
//静态代码块:一般用于初始化静态变量。
static{
String fileName = "hcxmall.properties";
props = new Properties();
try {
props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8"));
} catch (IOException e) {
logger.error("配置文件读取异常",e);
}
}
/**
* 获取hcxmall.propeties文件中的信息:通过key获取value
* @param key
* @return
*/
public static String getProperty(String key){
String value = props.getProperty(key.trim());
if(StringUtils.isBlank(value)){
return null;
}
return value.trim();
}
public static String getProperty(String key,String defaultValue){
String value = props.getProperty(key.trim());
if(StringUtils.isBlank(value)){
value = defaultValue;
}
return value.trim();
}
}
调用:
/**
* 文件上传
* @param file
* @param request
* @return
*/
@RequestMapping("upload.do")
@ResponseBody
public ServerResponse upload(HttpSession session,
@RequestParam(value = "upload_file",required = false) MultipartFile file,
HttpServletRequest request){
User user = (User) session.getAttribute(Const.CURRENT_USER);
if(user == null){
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),"用户未登录,请登录管理员");
}
if(iUserService.checkAdminRole(user).isSuccess()){
//上传到upload文件夹,此目录为webapp下的,即跟WEB-INF同级
String path = request.getSession().getServletContext().getRealPath("upload");
String targetFileName = iFileService.upload(file, path);
String url = PropertiesUtil.getProperty("ftp.server.http.prefix") + targetFileName;
Map fileMap = Maps.newHashMap();
fileMap.put("uri",targetFileName);
fileMap.put("url",url);
return ServerResponse.createBySuccess(fileMap);
}else {
return ServerResponse.createByErrorMessage("无权限操作");
}
}
五、SpringMVC实现富文本文件上传
富文本中对于返回值有自己的要求,这里使用simditor 所以按照simditor的要求进行返回 该种富文本上传只针对simditor插件:
{
"success":true/false,
"msg":"error message",# optional
"file_path":"[real file path]"
}
demo:
@RequestMapping("richtext_img_upload.do")
@ResponseBody
public Map richtextImgUpload(HttpSession session,
@RequestParam(value = "upload_file",required = false) MultipartFile file,
HttpServletRequest request,
HttpServletResponse response){
Map resultMap = Maps.newHashMap();
User user = (User) session.getAttribute(Const.CURRENT_USER);
if(user == null){
resultMap.put("success",false);
resultMap.put("msg","请登录管理员");
return resultMap;
}
if(iUserService.checkAdminRole(user).isSuccess()){
String path = request.getSession().getServletContext().getRealPath("upload");
String targetFileName = iFileService.upload(file, path);
if(StringUtils.isBlank(targetFileName)){
resultMap.put("success",false);
resultMap.put("msg","上传失败");
return resultMap;
}
String url = PropertiesUtil.getProperty("ftp.server.http.prefix") + targetFileName;
resultMap.put("success",false);
resultMap.put("msg","上传成功");
resultMap.put("file_path",url);
//只需要处理正常的成功的返回
response.addHeader("Access-Control-Allow-Headers","X-File-Name");
return resultMap;
}else {
resultMap.put("success",false);
resultMap.put("msg","无权限操作");
return resultMap;
}
}
网友评论