maven依赖
这里我是用的maven项目,还有就是我的文件是通过ftp上传到我的另一个服务器上的,除去最基本的依赖后,还需要三个依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
spring配置
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 限制上传文件大小上限5M -->
<property name="maxUploadSize" value="5242880" />
</bean>
FtpUtil
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.*;
/**
* @Author:Gaara
* @Description:ftp上传工具
* @Date:Created in 2018/1/3 9:55
* @Modified By:
*/
public class FtpUtil {
/**
* @param host ftp服务器host
* @param port ftp服务器端口
* @param username ftp登录账号
* @param password ftp登录密码
* @param basePath ftp服务器基础目录
* @param filePath ftp服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return
*/
public static boolean uploadFile(String host, int port, String username, String password, String basePath,
String filePath, String filename, InputStream input) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
//切换到上传目录
if (!ftp.changeWorkingDirectory(basePath+filePath)) {
//如果目录不存在创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir)) continue;
tempPath += "/" + dir;
if (!ftp.changeWorkingDirectory(tempPath)) {
if (!ftp.makeDirectory(tempPath)) {
return result;
} else {
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//上传文件
if (!ftp.storeFile(filename, input)) {
return result;
}
input.close();
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
}
controller
package com.xxxx.controller;
import com.xxxx.entity.ResultEntity;
import com.xxxx.util.FtpUtil;
import com.xxxx.util.IDUtil;
import com.xxxx.util.PropertyPlaceholder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
/**
* @Author:Gaara
* @Description:
* @Date:Created in 2018/1/2 16:59
* @Modified By:
*/
@Controller
@RequestMapping("/upload")
public class UploadController {
@value("${ftpHost}")
private String host;
@value("${ftpUser}")
private String userName;
@value("${ftpPwd}")
private String userPwd;
@value("${ftpBasePath}")
private String basePath;
@ResponseBody
@RequestMapping(value = "/uploadImg")
public ResultEntity uploadImg(HttpServletRequest req) throws IOException {
MultipartHttpServletRequest request = (MultipartHttpServletRequest) req;
MultipartFile file = request.getFile("file");
if (file != null){
// 获取文件的后缀
String originalName = file.getOriginalFilename();
String suffix = originalName.substring(originalName.lastIndexOf("."));
// 时间戳+随机数生成文件名
String fileName = String.valueOf(System.currentTimeMillis())+(int)((Math.random()*9+1)*100000)+suffix;
// 将文件转化为字节流
InputStream is = file.getInputStream();
boolean uploadRes = FtpUtil.uploadFile(host, 21, userName, userPwd, basePath, "/", fileName, is);
if (uploadRes){
return ResultEntity.ok(fileName);
}
}
return ResultEntity.build("1000","图片上传失败");
}
}
Html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>测试</title>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<input type="file" id="file" onchange="ajaxFileUpload();" />
</body>
<script>
function ajaxFileUpload() {
var form = new FormData; //创建一个FormData对象
form.append('file',$("#file").get(0).files[0]);
//将文件放到FormData对象中
console.log(form);
$.ajax({
url : "http://127.0.0.1:8080/upload/uploadImg",//访问路径
contentType: false,
processData: false,
type:"post",
data :form,
dataType : "json"
}).success(function(data,status){
if(status=="success"){
if(data.code==200){
alert("文件上传成功");
}
if(data.code==400){
alert("文件上传失败");
}
}
}).error(function(){
alert("服务器未响应");
});
}
</script>
</html>
到这里前,测试上传文件已经可以实现,但是还有两个问题:
- 文件大小超出限制时不能返回友好的json进行提示
- 不能限制上传文件的后缀(比如只想上传图片)
文件大小超出限制时返回友好的json进行提示
- 自定义异常处理器类
package com.xxxx.aspect;
import com.xxxx.entity.ResultEntity;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Author:Gaara
* @Description: 自定义异常处理器类
* @Date:Created in 2018/1/4 16:44
* @Modified By:
*/
public class MaxUploadSizeExceptionHandler implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView mv = new ModelAndView(new MappingJackson2JsonView());
if (e instanceof MaxUploadSizeExceededException){
mv.addObject(ResultEntity.build("1111","图片大小不能超过5M"));
return mv;
}
return null;
}
}
- spring配置
<bean class="com.xxxx.aspect.MaxUploadSizeExceptionHandler" />
限制上传文件的后缀
- 自定义一个文件上传类型限制的拦截器
package com.xxxx.aspect;
import com.alibaba.fastjson.JSON;
import com.xxxx.entity.ResultEntity;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;
import java.util.Map;
/**
* @Author:Gaara
* @Description:全局文件类型拦截器
* @Date:Created in 2018/1/4 18:36
* @Modified By:
*/
public class FileTypeInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Boolean flag = true;
if (request instanceof MultipartHttpServletRequest){
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String,MultipartFile> files = multipartRequest.getFileMap();
Iterator<String> iterator = files.keySet().iterator();
// 对多部件请求资源进行遍历
while (iterator.hasNext()){
String formKey = iterator.next();
MultipartFile multipartFile = multipartRequest.getFile(formKey);
String fileName = multipartFile.getOriginalFilename();
// 判断是否为限制文件类型
if (!checkFile(fileName)){
ServletOutputStream out = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("text/json;charset=UTF-8");
String json = JSON.toJSONString(ResultEntity.build("1000","不支持的类型",""));
out = response.getOutputStream();
out.write(json.getBytes("UTF-8"));
flag = false;
}
}
}
return flag;
}
/**
* 判断是否为允许的上传文件类型,true表示允许
* @param fileName
* @return
*/
private Boolean checkFile(String fileName){
String suffixList = "jpg,gif,png,ico,bmp,jpeg";
String suffix = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());
if (suffixList.contains(suffix.trim().toLowerCase())){
return true;
}
return false;
}
}
- spring配置
<mvc:interceptors>
<mvc:interceptor>
<!--/**表示所有URL和子URL路径-->
<mvc:mapping path="/**"/>
<!--配置定义的文件上传类型限制拦截器-->
<bean class="com.xyzq.aspect.FileTypeInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
最后感谢下,下面各位博主的文章还有传智的入云龙老师(看了不少老师的视频)
最最后,有个疑问filter、interceptor和aspect到底有啥区别啊?