今天使用图片上传,上传GIF图片,使用FileItem的getInputStream()不能获取到流。
上传图片接口如下:
@RequestMapping(value = "/fileupload_psize_plength", method = RequestMethod.POST)
public @ResponseBody IRestResponse fileupload_psize_plength(HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException {
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Allow-Origin", "*");
request.setCharacterEncoding("utf-8");// 处理文件中文乱码问题
IRestResponse rst = new IRestResponse();
rst.setResult("0");
String uptype = request.getParameter("uptype");// 上传类型(1、本地2、oss)
String widthsize = request.getParameter("widthsize");// 尺寸
if (ValidateUtil.isNull(uptype) || ValidateUtil.isNull(widthsize)) {
rst.setResult("1");
rst.addError("error", "传参异常");
return rst;
}
ResponseBuilder rp = Response.status(200);
// 获得磁盘文件条目工厂。
DiskFileItemFactory factory = new DiskFileItemFactory();
// 获取文件上传需要保存的路径,upload文件夹需存在。
String path = request.getSession().getServletContext().getRealPath("/file");
// 根据日期创建文件夹
String picPath = Utils.mkdirs(path);
path = path + "/" + picPath;
// 设置暂时存放文件的存储室,这个存储室可以和最终存储文件的文件夹不同。因为当文件很大的话会占用过多内存所以设置存储室。
factory.setRepository(new File(path));
// 设置缓存的大小,当上传文件的容量超过缓存时,就放到暂时存储室。
factory.setSizeThreshold(1024 * 1024);
// 上传处理工具类(高水平API上传处理?)
ServletFileUpload upload = new ServletFileUpload(factory);
try {
// 调用 parseRequest(request)方法 获得上传文件 FileItem 的集合list 可实现多文件上传。
String ct = request.getContentType();
if (ValidateUtil.isNull(ct)) {
rst.setResult("1");
rst.addError("error", "图片格式错误!");
return rst;
}
List<FileItem> list = (List<FileItem>) upload.parseRequest(request);
for (FileItem item : list) {
String upfilename = item.getName();
String prefix = upfilename.substring(upfilename.lastIndexOf(".") + 1);
if (ValidateUtil.isNull(prefix)) {
rst.setResult("1");
rst.addError("error", "图片格式错误!");
return rst;
} else {
prefix = prefix.toUpperCase();
if ("JPG".equals(prefix) || "JPEG".equals(prefix) || "PNG".equals(prefix)) {
String param = upfilename.substring(upfilename.indexOf(".") + 1);
if (!item.isFormField()) {
String filename = IdGenerator.generateStr() + "." + param;
item.write(new File(path + "/" + filename));
double fileSize = item.getSize() / 1024;
double limitSize = 300;
if (fileSize > limitSize) {
rst.setResult("1");
rst.addError("error",
"上传图片文件大小(" + fileSize + "kb),超过系统允许上传大小(" + limitSize + "kb),请对图片进行压缩处理!");
new File(path + "/" + filename).delete();
return rst;
}
File files = new File(path + "/" + filename);
File nfiles = new File(path + "/" + filename);
Image srcFile = ImageIO.read(files);
int w = srcFile.getWidth(null);
int h = srcFile.getHeight(null);
int h1 = 2 * w / 3;
int w1 = 4 * w / 3;
if (h < h1 || h > w1) {
rst.setResult("1");
rst.addError("error", "上传图片不符合要求,建议上传正方形或接近正方形比例的图片。");
files.delete();
return rst;
}
if (w > Integer.parseInt(widthsize)) {
double bili = Integer.parseInt(widthsize) / (double) w;
try {
Thumbnails.of(files).scale(bili).toFile(nfiles);
} catch (Exception e) {
files.delete();
rst.setResult("1");
rst.addError("error", "图片压缩异常");
return rst;
}
if (nfiles.length() / 1024 > 50) {
rst.setResult("1");
rst.addError("error", "上传图片压缩后大小为(" + nfiles.length() / 1024
+ "kb),超过系统允许上传大小(50kb),请对图片进行压缩处理!");
nfiles.delete();
return rst;
}
}
if (w < Integer.parseInt(widthsize) && fileSize > 50) {
try {
Thumbnails.of(files).scale(1f).toFile(nfiles);
} catch (Exception e) {
files.delete();
rst.setResult("1");
rst.addError("error", "图片压缩异常");
return rst;
}
if (nfiles.length() / 1024 > 50) {
rst.setResult("1");
rst.addError("error", "上传图片压缩后大小为(" + nfiles.length() / 1024
+ "kb),超过系统允许上传大小(50kb),请对图片进行压缩处理!");
nfiles.delete();
return rst;
}
}
if ("1".equals(uptype)) {// 上传本地
rst.addMessage("imgpath", picPath + "/" + filename);
return rst;
} else {// 上传OSS
try {
String filePath =AliOssUtil.file_upload(item, "dolptech-oss-server-109",
"OSS_Files/");
// 上传本地图片
try {
files.delete();
} catch (Exception e) {
rst.setResult("1");
rst.addError("error", "删除服务器图片失败");
return rst;
}
if ("#".equals(filePath)) {
rst.setResult("1");
rst.addError("error", "文件上传失败,请重试!");
return rst;
} else {
rst.addMessage("imgpath", filePath);
return rst;
}
} catch (Exception e) {
rst.setResult("1");
rst.addError("error", "文件上传失败,请重试!");
return rst;
}
}
} else {
rst.setResult("1");
rst.addError("error", "文件格式错误!");
return rst;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return rst;
}
AliOssUtil工具类file_upload接口部分代码:
public static String file_upload(FileItem fitem,String bucketName,String folder){
String fileName = fitem.getName();
//重新对文件进行命名
String param = fileName.substring(fileName.indexOf(".") + 1);
fileName = IdGenerator.generateStr() + "."+param;
Long fileSize = fitem.getSize();
**InputStream is = fitem.getInputStream();**
}
执行到InputStream is = fitem.getInputStream();
出现错误
java.io.FileNotFoundException: D:\apache-tomcat-7.0.56\webapps\dmsys\file\2020\05\12\upload_956c14d7_54d0_4a7f_854e_4985a94fa784_00000016.tmp (系统找不到指定的文件。)
解决:
FileItem类的 void write(File file)方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。
该方法说明了使用write(File file )方法后,临时文件会清空。那么图片上传时,什么时候回保存临时文件?
ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中, 在使用ServletFileUpload对象解析请求时需要根据DiskFileItemFactory对象的属性**sizeThreshold(临界值)和repository(临时目录)**来决定将解析得到的数据保存在内存还是临时文件中,如果是临时文件,保存在哪个临时目录中?。
我的sizeThreshold设置为1024*1024(1M),当我上传GIF为1.5M大于了1M,上传类容保存在临时文件,而不是内存中。所以可以通过把sizeThreshold设置大点。
我因为业务需求对图片进行压缩处理,把图片保存到本地,然后通过图片文件获取输入流上传到OSS上。
public static String uploadOSS(File file,String bucketName,String folder){
try{
//以输入流的形式上传文件
InputStream is = new FileInputStream(file);
//文件名
String fileName = file.getName();
//文件大小
Long fileSize = file.length();
}