Spring Boot筆記之上傳圖片(Base64和MultipartFile)
阿新 • • 發佈:2018-12-28
SpringMVC接收圖片
圖片的上傳
form表單上傳
<form action="/user/upload/file" method="post" enctype="multipart/form-data">
<input type="file" name="img" />
<input type="submit" />
</form>
jquery.form.js提供的ajax上傳
function updateFile() {
$('#file').ajaxSubmit({
url: url,
type: 'POST',
//contentType: false,
xhrFields: {
withCredentials: true
},
crossDomain: true,
success: function (result) {
},
error: function (result) {
}
});
}
Base64格式上傳
有些APP外掛會這麼幹,這裡就不寫了。
SpringMVC接收
MultipartFile接收
SpringMVC
提供的org.springframework.web.multipart.MultipartFile
很強大,接收file
只需要@RequestParam(value = "img") MultipartFile file
就可以了,MultipartFile
還提供的幾個很好用的API:
- 獲取檔案型別getContentType()
- 獲取檔案大小getSize()
- 儲存檔案transferTo(java.io.File file)
接收、校驗和儲存:
@Controller
@RequestMapping("/user")
public class UserController extends BaseController {
private static Logger logger = LoggerFactory.getLogger(UserController.class);
@Value(value = "${image.path:./img}")
private String imagePath;
@Value(value = "${image.host:http://localhost}")
private String imageHost;
@RequestMapping(value = "/upload/file", method = RequestMethod.POST)
@ResponseBody
public Result<String> saveFile(@RequestParam(value = "img") MultipartFile file) {
StringBuffer fileName = new StringBuffer();
fileName.append(UUID.randomUUID().toString().replaceAll("-", ""));
String type = file.getContentType();
if ("image/png".equals(type)) {
fileName.append(".png");
} else if ("image/jpeg".equals(type)) {
fileName.append(".jpeg");
} else if ("image/gif".equals(type)) {
fileName.append(".gif");
} else {
return new Result.Builder<String>()
.code(-1)
.msg("請選擇.png.jpg格式的圖片")
.build();
}
if (file.getSize() > 1024000L) {
return new Result.Builder<String>()
.code(-1)
.msg("圖片超過1Mb")
.build();
}
try {
file.transferTo(new File(imagePath, fileName.toString()));
return new Result.Builder<String>()
.code(0)
.msg("成功")
.data(imageHost + fileName.toString())
.build();
} catch (IOException e) {
e.printStackTrace();
return new Result.Builder<String>()
.code(-1)
.msg("儲存失敗")
.build();
}
}
}
Base64字串接收
@RequestMapping(value = "/upload/base64", method = RequestMethod.POST)
@ResponseBody
public Result<String> saveBase64(@RequestParam(value = "img") String base64Str) {
StringBuffer fileName = new StringBuffer();
fileName.append(UUID.randomUUID().toString().replaceAll("-", ""));
if (StringUtils.isBlank(base64Str)) {
return new Result.Builder<String>()
.code(-1)
.msg("file不可預設")
.build();
} else if (base64Str.indexOf("data:image/png;") != -1) {
base64Str = base64Str.replace("data:image/png;base64,", "");
fileName.append(".png");
} else if (base64Str.indexOf("data:image/jpeg;") != -1) {
base64Str = base64Str.replace("data:image/jpeg;base64,", "");
fileName.append(".jpeg");
} else {
return new Result.Builder<String>()
.code(-1)
.msg("請選擇.png.jpg格式的圖片")
.build();
}
File file = new File(imagePath, fileName.toString());
byte[] fileBytes = Base64.getDecoder().decode(base64Str);
try {
FileUtils.writeByteArrayToFile(file, fileBytes);
} catch (IOException e) {
e.printStackTrace();
return new Result.Builder<String>()
.code(-1)
.msg("儲存失敗")
.build();
}
return new Result.Builder<String>()
.code(0)
.msg("成功")
.data(imageHost + fileName.toString())
.build();
}
為了避免檔案重名、Linux檔案系統與Windows檔案系統差異等因素會引起的異常,我通常使用UUID重新命名後再儲存。
nginx配置
上面程式碼中的image.path
是檔案的儲存路徑, image.host
是提供給前端的訪問方式,具體配置要結合nginx
代理的配置:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /data/www;
……
}
這是一個本地測試環境的配置,僅供參考。image.path
配置為/data/www/img/
,image.host
配置為http://localhost/img/
,這樣,圖片檔案會儲存在/data/www/img/
,http訪問img/test.jpeg
時,nginx
就會響應這張圖片。