本文使用java代碼實現圖片遠程上傳到linux的圖片服務器上。
前提:linux安裝好了ftp模塊,nginx服務器,搭建好了圖片服務器,可以遠程訪問
搭建圖片服務器《一》-linux安裝ftp組件
搭建圖片服務器《二》-linux安裝nginx
搭建圖片服務器《三》:linux上nginx+ftp搭建圖片服務器
一個需求
通過springMVC接受圖片文件然后上傳到圖片服務器,把圖片在圖片服務器上的相對路徑(不包括圖片服務器的ip,防止圖片服務器ip改變)保存在數據庫中
實現環境:前台上傳圖片組件+springMVC+spring+mybatis+mysql
引入依賴
需要導入相關jar包,這里使用maven管理,導入依賴:
- <!-- 加入上傳文件組件 -->
- <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.1</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <version>1.3</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
- <dependency>
- <groupId>commons-net</groupId>
- <artifactId>commons-net</artifactId>
- <version>3.3</version>
- </dependency>
由於上傳文件需要圖片服務器相關的配置信息,這里為了不硬編碼在代碼中,模仿數據庫連接信息的方式配置在配置文件中,然后交給spring進行管理
圖片服務器需要的配置的配置文件放在classpath下:
ftp.properties
- #ftp相關配置
- FTP_ADDRESS=192.168.1.113
- FTP_PORT=21
- FTP_USERNAME=ftpuser_album
- FTP_PASSWORD=123456
- FTP_BASEPATH=/home/ftpuser_album/www/album_images
- #圖片服務器相關配置
- IMAGE_BASE_URL=http://192.168.1.113/album_images
配置文件內容讓spring讀取到容器中,然后存儲在實體類中:
spring配置
- <!-- 加載多個配置文件 -->
- <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="locations">
- <list>
- <value>classpath:db.properties</value>
- <value>classpath:ftp.properties</value>
- <value>classpath:redis.properties</value>
- </list>
- </property>
- </bean>
springMVC配置文件需要配置上傳文件的bean
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="defaultEncoding" value="utf-8"></property>
- <property name="maxUploadSize" value="10485760000"></property>
- <property name="maxInMemorySize" value="40960"></property>
- </bean>
實體類:FtpConfig.java
- @Component
- public class FtpConfig {
- /**
- * 獲取ip地址
- */
- @Value("${FTP_ADDRESS}")
- private String FTP_ADDRESS;
- /**
- * 端口號
- */
- @Value("${FTP_PORT}")
- private String FTP_PORT;
- /**
- * 用戶名
- */
- @Value("${FTP_USERNAME}")
- private String FTP_USERNAME;
- /**
- * 密碼
- */
- @Value("${FTP_PASSWORD}")
- private String FTP_PASSWORD;
- /**基本路徑
- */
- @Value("${FTP_BASEPATH}")
- private String FTP_BASEPATH;
- /**
- * 下載地址地基礎url
- */
- @Value("${IMAGE_BASE_URL}")
- private String IMAGE_BASE_URL;
- ...set和get方法就省略
- }
這樣哪里需要使用圖片服務器配置信息就可以通過@AutoWired注入FtpConfig對象即可
上傳案例
上傳的工具類:
- public class FtpUtil {
- /**
- * ftp上傳圖片方法
- *title:pictureUpload
- *@param ftpConfig 由spring管理的FtpConfig配置,在調用本方法時,可以在使用此方法的類中通過@AutoWared注入該屬性。由於本方法是靜態方法,所以不能在此注入該屬性
- *@param picNewName 圖片新名稱--防止重名 例如:"1.jpg"
- *@param picSavePath 圖片保存路徑。注:最后訪問路徑是 ftpConfig.getFTP_ADDRESS()+"/images"+picSavePath
- *@param file 要上傳的文件(圖片)
- *@return 若上傳成功,返回圖片的訪問路徑,若上傳失敗,返回null
- * @throws IOException
- */
- public static String pictureUploadByConfig(FtpConfig ftpConfig,String picNewName,String picSavePath,InputStream inputStream) throws IOException{
- String picHttpPath = null;
- boolean flag = uploadFile(ftpConfig.getFTP_ADDRESS(), ftpConfig.getFTP_PORT(), ftpConfig.getFTP_USERNAME(),
- ftpConfig.getFTP_PASSWORD(), ftpConfig.getFTP_BASEPATH(), picSavePath, picNewName, inputStream);
- if(!flag){
- return picHttpPath;
- }
- //picHttpPath = ftpConfig.getFTP_ADDRESS()+"/images"+picSavePath+"/"+picNewName;
- picHttpPath = ftpConfig.getIMAGE_BASE_URL()+picSavePath+"/"+picNewName;
- System.out.println("==="+picHttpPath);
- return picHttpPath;
- }
- /**
- * Description: 向FTP服務器上傳文件
- * @param host FTP服務器hostname
- * @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 成功返回true,否則返回false
- */
- public static boolean uploadFile(String host, String ftpPort, String username, String password, String basePath,
- String filePath, String filename, InputStream input) {
- int port = Integer.parseInt(ftpPort);
- 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);
- ftp.enterLocalPassiveMode();//這個設置允許被動連接--訪問遠程ftp時需要
- //上傳文件
- 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;
- }
- //下載文件方法不用看,可能日后有用,先留在這里==========================================
- /**
- * Description: 從FTP服務器下載文件
- * @param host FTP服務器hostname
- * @param port FTP服務器端口
- * @param username FTP登錄賬號
- * @param password FTP登錄密碼
- * @param remotePath FTP服務器上的相對路徑
- * @param fileName 要下載的文件名
- * @param localPath 下載后保存到本地的路徑
- * @return
- */
- public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
- String fileName, String localPath) {
- boolean result = false;
- FTPClient ftp = new FTPClient();
- try {
- int reply;
- ftp.connect(host, port);
- // 如果采用默認端口,可以使用ftp.connect(host)的方式直接連接FTP服務器
- ftp.login(username, password);// 登錄
- reply = ftp.getReplyCode();
- if (!FTPReply.isPositiveCompletion(reply)) {
- ftp.disconnect();
- return result;
- }
- ftp.changeWorkingDirectory(remotePath);// 轉移到FTP服務器目錄
- FTPFile[] fs = ftp.listFiles();
- for (FTPFile ff : fs) {
- if (ff.getName().equals(fileName)) {
- File localFile = new File(localPath + "/" + ff.getName());
- OutputStream is = new FileOutputStream(localFile);
- ftp.retrieveFile(ff.getName(), is);
- is.close();
- }
- }
- ftp.logout();
- result = true;
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (ftp.isConnected()) {
- try {
- ftp.disconnect();
- } catch (IOException ioe) {
- }
- }
- }
- return result;
- }
- }
springMVC的使用:
- @Autowired
- private FtpConfig ftpConfig;
- @RequestMapping("/uploadFiles")
- @ResponseBody
- public MSG uploadFiles(@RequestParam("albumId")Integer albumId,@RequestParam("file")MultipartFile[] files) throws IOException {
- List<Photo> photoList = new ArrayList<Photo>();
- //循環上傳多個圖片
- for(MultipartFile file:files){
- Photo photo = new Photo();
- String oldName = file.getOriginalFilename();
- String picNewName = UploadUtils.generateRandonFileName(oldName);//通過工具類產生新圖片名稱,防止重名
- String picSavePath = UploadUtils.generateRandomDir(picNewName);//通過工具類把圖片目錄分級
- photo.setPhotoUrl(picSavePath+"/"+picNewName);//設置圖片的url--》就是存儲到數據庫的字符串url
- photo.setAlbumId(albumId);//設置圖片所屬相冊id
- photo.setPhotoDesc(oldName);//設置圖片描述
- photoList.add(photo);
- FtpUtil.pictureUploadByConfig(ftpConfig,picNewName,picSavePath,file.getInputStream());//上傳到圖片服務器的操作
- }
- //添加到數據庫
- iPhotoService.savePhotoList(photoList);//調用service層方法
- return MSG.success();//上傳成功做的操作,我這里返回上傳成功的信號
- }
UploadUtils.java工具類:
- public class UploadUtils {
- /**
- * 得到真實文件名
- * @param fileName
- * @return
- */
- public static String subFileName(String fileName){
- //查找最后一個 \ (文件分隔符)位置
- int index = fileName.lastIndexOf(File.separator);
- if(index == -1){
- //沒有分隔符,說明是真實名稱
- return fileName;
- }else {
- return fileName.substring(index+1);
- }
- }
- /**
- * 獲得隨機UUID文件名
- * @param fileName
- * @return
- */
- public static String generateRandonFileName(String fileName){
- //首相獲得擴展名,然后生成一個UUID碼作為名稱,然后加上擴展名
- String ext = fileName.substring(fileName.lastIndexOf("."));
- return UUID.randomUUID().toString()+ext;
- }
- /**
- * 獲得hashcode 生成二級目錄
- * @param uuidFileName
- * @return
- */
- public static String generateRandomDir(String uuidFileName){
- int hashCode = uuidFileName.hashCode();//得到它的hashcode編碼
- //一級目錄
- int d1 = hashCode & 0xf;
- //二級目錄
- int d2 = (hashCode >> 4) & 0xf;
- return "/"+d1+"/"+d2;
- }
- }
最后親測能夠實現上傳。
轉載自:http://blog.csdn.net/maoyuanming0806/article/details/78068091
