Java实现文件上传到服务器,并返回可访问的URL地址,本文以上传图片为例。
1.配置spring的配置文件,在配置文件中定义上传路径的根路径,通过@Value("${file.path}")在代码中使用
#文件上传根路径
file:
path: D:/upload/
2.配置资源映射文件
这一步很重要。通过URL能不能找到文件这一步其决定性作用。
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 图片保存路径,自动从yml文件中获取数据
* 示例: D:/upload/
*/
@Value("${file.path}")
private String fileSavePath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 配置资源映射
* 意思是:如果请求地址是以“/upload/”开头的,
* 就给映射到本机的“D:/upload/”这个文件夹内,去找你要的资源
* 注意:D:/upload/ 后面的 “/”一定要带上
*/
registry.addResourceHandler("/upload/**")
.addResourceLocations("file:"+fileSavePath);
}
}
3.上传方法封装
因为考虑到多文件上传,所以使用List<MultipartFile>
泛型接收文件。
public class UploadUtil {
/**
* @description 检查是否是 bmp/gif/jpg/png图片
* @auther zzd
* @date 2020-06-23 09:50
* @param fileList
* @return java.lang.Boolean
*/
public static Boolean checkImg(List<MultipartFile> fileList){
if(fileList.isEmpty()){
return false;
}else {
for (MultipartFile file:fileList) {
try {
//通过ImageIO检查是否是 bmp/gif/jpg/png图片,是则有东西返回(具体是啥,我也不清楚)
Image image = ImageIO.read(file.getInputStream());
return image!=null;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
return false;
}
}
/**
* @description 图片上传
* @auther zzd
* @date 2020-06-23 09:55
* @param fileList
* @param request
* @return java.lang.String
*/
public static String upload(List<MultipartFile> fileList, HttpServletRequest request, String dirPath){
//定义URI地址
String fileDownloadUri="";
for (MultipartFile file: fileList) {
// 获取文件名
String fileName = file.getOriginalFilename();
//获取年份,月份,天
Calendar date = Calendar.getInstance();
String year = String.valueOf(date.get(Calendar.YEAR));
String month = String.valueOf(date.get(Calendar.MONTH)+1);
String day = String.valueOf(date.get(Calendar.DAY_OF_MONTH));
// 新文件名
fileName =year+"/"+month+"/"+day+"/"+System.currentTimeMillis() + fileName;
//创建文件
File dest = new File(dirPath+fileName);
//判断文件父目录是否存在
if(!dest.getParentFile().exists()){
dest.getParentFile().mkdirs(); //这里因为创建的是多级目录,所以需要使用mkdirs()方法。使用mkdir()方法则文件夹创建不成功,会报找不到路径错误。
}
try {
//将文件内容写入创建的文件中
file.transferTo(dest);
//获得本机Ip(获取的是服务器的Ip)
InetAddress inetAddress=InetAddress.getLocalHost();
String ip=inetAddress.getHostAddress();
//URL地址的格式:http://ip:port/文件路径
if (fileDownloadUri==""){
fileDownloadUri=request.getScheme()+"://"+ ip+":"+request.getServerPort()+"/upload/"+fileName;
}else {
fileDownloadUri=fileDownloadUri+","+request.getScheme()+"://"+ ip+":"+request.getServerPort()+"/upload/"+fileName;
}
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
//返回Url地址,以逗号分隔
return fileDownloadUri;
}
/**
* @description 删除文件
* @auther zzd
* @date 2020-06-24 17:08
* @param "http://10.168.1.148:8080/upload/2020/6/23/1592897372738ChMkJlbK5pqIcV7dAAQDU4JGja0AALKWgKa4WUABANr295.jpg"
* @return Boolean
*/
public static Boolean deleteFile(String dirPath,String url){
//截取第四个“/”后面的字符串
int i1=url.indexOf('/');
int i2=url.indexOf('/',i1+1);
int i3=url.indexOf('/',i2+1);
int i4=url.indexOf("/",i3+1);
String substring=url.substring(i4+1,url.length());
String relPath=dirPath+substring;
Boolean flag = false;
File file = new File(relPath);
if (file.isFile() && file.exists()) {
file.delete();
flag = true;
}
return flag;
}
}
至此,图片上传准备工作结束。只要在业务逻辑中调用即可完成。
例:
controller层代码
@RestController
@RequestMapping("/upload")
public class UploadController {
@Autowired
private UploadService uploadService;
@ApiOperation("图片上传")
@PostMapping("/uploadImg")
public ResultBody uploadImg(@RequestBody List<MultipartFile> fileList, HttpServletRequest request){
String imgURL=uploadService.uploadImg(fileList,request);
return ResultBody.ok(imgURL);
}
}
Service层代码
service层接口这里就不写了(就一两句)
@Service
public class UploadServiceImpl implements UploadService {
//获取根路径
@Value("${file.path}")
private String dirPath;
@Autowired
private UploadMapper uploadMapper;
@Override
public String uploadImg(List<MultipartFile> fileList, HttpServletRequest request) {
Boolean img =UploadUtil.checkImg(fileList);
if (img){
String URL=UploadUtil.upload(fileList,request,dirPath);
return URL;
}else {
return "请上传bmp/gif/jpg/png格式的图片";
}
}
}
Mapper层代码和XML文件中的SQL语句这里就不写了,看具体的业务逻辑做具体的功能。
本例中未书写限制图片大小的方法。方法很多,如需要,请自行查找。
注意:如果浏览器通过URL访问上传的资源,报401(未授权错误)时,可能是因为项目做了权限校验,则此时须查看该请求是否放行(URL地址也是请求地址)本例中放行了所有upload开头的请求。