Nginx 搭建圖片服務器

Nginx 搭建圖片服務器

來自 | ITDragon龍

鏈接 | cnblogs.com/itdragon/p/7864916.html

本章內容通過Nginx 和 FTP 搭建圖片服務器。在學習本章內容前,請確保您的Linux 系統已經安裝了Nginx 和 Vsftpd。

Nginx 安裝

http://www.cnblogs.com/itdragon/p/7850985.html

Vsftpd 安裝

http://www.cnblogs.com/itdragon/p/7857649.html

本章知識點

效果圖:

Nginx 搭建图片服务器

需求:實現圖片的上傳和批量上傳

技術:Nginx,Vsftpd,Spring,SpringMVC,KindEditor,CentOS

說明:本章節內容主要是實現圖片的上傳功能。使用 KindEditer 是為了更好的演示圖片的上傳,回顯,批量效果。後臺代碼與KindEditer沒有直接關係,放心閱讀。另外源碼中有Mybatis的jar,不用理會,本章內容用不到,是為後續內容做準備!

源碼:見文章底部

場景:用戶將圖片上傳到 tomcat 服務器上,再由 tomcat 服務器通過FTP上傳到 Nginx 服務器上。

Nginx 搭建图片服务器

項目結構:

Nginx 搭建图片服务器

單元測試

首先要攻破核心技術。通過單元測試實現圖片上傳的功能。

<code>public class PictureFTPTest {/<code>
<code> // 測試 ftp 上傳圖片功能/<code><code> @Test/<code><code> public void testFtpClient throws Exception {/<code><code> // 1. 創建一個FtpClient對象/<code><code> FTPClient ftpClient = new FTPClient;/<code><code> // 2. 創建 ftp 連接/<code><code> ftpClient.connect("192.168.0.11", 21);/<code><code> // 3. 登錄 ftp 服務器/<code><code> ftpClient.login("ftpuser", "root");/<code><code> // 4. 讀取本地文件/<code><code> FileInputStream inputStream = new FileInputStream(new File("F:\\\\hello.png"));/<code><code> // 5. 設置上傳的路徑/<code><code> ftpClient.changeWorkingDirectory("/usr/local/nginx/html/images");/<code><code> // 6. 修改上傳文件的格式為二進制/<code><code> ftpClient.setFileType(FTP.BINARY_FILE_TYPE);/<code><code> // 7. 服務器存儲文件,第一個參數是存儲在服務器的文件名,第二個參數是文件流/<code><code> ftpClient.storeFile("hello.jpg", inputStream);/<code><code> // 8. 關閉連接/<code><code> ftpClient.logout;/<code>
<code> }/<code>

<code>}/<code>

說明:這裡的ip地址,端口,ftp用戶名,密碼,本地文件路徑,以及Nginx服務器圖片路徑等,這些字符串參數都要根據自己實際設置的來填寫的。如果你的Nginx和Vsftpd安裝是按照我提供的鏈接來做的。那你只需要改ip地址即可。

Maven 的Web 項目

搭建Maven的Web 項目,之前有寫過。這裡就不過多描述。

項目核心配置文件

首先是 Maven 的核心文件 pom.xml,添加下列對應版本的依賴即可,可前去https://mvnrepository.com/tags/maven 查找依賴。

<code> <junit.version>4.12/<junit.version>/<code><code> <spring.version>4.1.3.RELEASE/<spring.version>/<code><code> <mybatis.version>3.2.8/<mybatis.version>/<code><code> <mybatis.spring.version>1.2.2/<mybatis.spring.version>/<code><code> <mybatis.paginator.version>1.2.15/<mybatis.paginator.version>/<code><code> <mysql.version>5.1.6/<mysql.version>/<code><code> <slf4j.version>1.6.4/<slf4j.version>/<code><code> <jackson.version>2.4.2/<jackson.version>/<code><code> <druid.version>1.0.9/<druid.version>/<code><code> <httpclient.version>4.3.5/<httpclient.version>/<code><code> <jstl.version>1.2/<jstl.version>/<code><code> <servlet-api.version>2.5/<servlet-api.version>/<code><code> <jsp-api.version>2.0/<jsp-api.version>/<code><code> <joda-time.version>2.5/<joda-time.version>/<code><code> <commons-lang3.version>3.3.2/<commons-lang3.version>/<code><code> <commons-io.version>1.3.2/<commons-io.version>/<code><code> <commons-net.version>3.3/<commons-net.version>/<code><code> <pagehelper.version>3.4.2/<pagehelper.version>/<code><code> <jsqlparser.version>0.9.1/<jsqlparser.version>/<code><code> <commons-fileupload.version>1.3.1/<commons-fileupload.version>/<code><code> <jedis.version>2.7.2/<jedis.version>/<code><code> <solrj.version>4.10.3/<solrj.version>/<code>

說明:和文件上傳有直接關係的是:

<code><dependency>/<code><code> <groupid>commons-fileupload/<groupid>/<code><code> <artifactid>commons-fileupload/<artifactid>/<code><code>

然後是 Web 項目的核心文件 web.xml

<code>/<code><code><web-app>www.w3.org/2001/XMLSchema-instance"/<web-app>/<code><code> xmlns="http://java.sun 
.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"/<code><code> xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"/<code><code> id="taotao" version="2.5">/<code><code> <display-name>pictrue-service/<display-name>/<code><code> /<code><code> <context-param>/<code><code> <param-name>contextConfigLocation/<param-name>/<code><code> <param-value>classpath:spring/applicationContext-*.xml/<param-value>/<code><code> /<code><code> <listener>/<code><code> <listener-class>org.springframework.web.context.ContextLoaderListener/<listener-class>/<code><code> /<code><code> /<code><code> <filter>/<code><code> <filter-name>CharacterEncodingFilter/<filter-name>/<code><code> <filter-class>org.springframework.web.filter.CharacterEncodingFilter/<filter-class>/<code><code> <init-param>/<code><code> <param-name>encoding/<param-name>/<code><code> <param-value>utf-8/<param-value>/<code><code> /<code><code> /<code><code> <filter-mapping>/<code><code> <filter-name>CharacterEncodingFilter/<filter-name>/<code><code> <url-pattern>/*/<url-pattern>/<code><code> /<code><code> /<code><code> <servlet>/<code><code> <servlet-name>pictrue-service/<servlet-name>/<code><code> <servlet-class>org.springframework.web.servlet.DispatcherServlet/<servlet-class>/<code><code> <init-param>/<code><code> <param-name>contextConfigLocation/<param-name>/<code><code> <param-value>classpath:spring/springmvc.xml/<param-value>/<code><code> /<code><code> <load-on-startup>1/<load-on-startup>/<code><code> /<code><code> <servlet-mapping>/<code><code> <servlet-name>pictrue-service/<servlet-name>/<code><code> <url-pattern>//<url-pattern>/<code><code> /<code><code>

再是 SpringMVC 配置文件 springmvc.xml,需要添加文件上傳解析器

<code>/<code><code> <bean><code> class="org.springframework.web.multipart.commons.CommonsMultipartResolver">/<code><code> /<code><code> <property>/<code><code> /<code><code> <property>/<code><code> /<code>/<bean>/<code>

最後是 Ftp 配置文件 resource.properties

<code>FTP_ADDRESS=192.168.0.11/<code><code>FTP_PORT=21/<code><code>FTP_USERNAME=ftpuser/<code><code>FTP_PASSWORD=root/<code><code>FTP_BASE_PATH=/usr/local/nginx/html/images/<code><code>IMAGE_BASE_URL=http://192.168.0.11/images/<code>

Service 層

上傳圖片的接口 PictureService.java

<code>/**/<code><code> * 上傳,批量上傳接口/<code><code> * @param uploadFile/<code><code> * @return/<code><code> *//<code><code> Map uploadPicture(MultipartFile uploadFile);/<code><code>}/<code>

上傳圖片接口實現類 PictureServiceImpl.java

<code>@Service/<code><code>@SuppressWarnings({"rawtypes", "unchecked"})/<code><code>public class PictureServiceImpl implements PictureService {/<code>
<code> // 通過 Spring4 的 Value註解,獲取配置文件中的屬性值/<code><code> @Value("${FTP_ADDRESS}")/<code><code> private String FTP_ADDRESS; // ftp 服務器ip地址/<code><code> @Value("${FTP_PORT}")/<code><code> private Integer FTP_PORT; // ftp 服務器port,默認是21/<code><code> @Value("${FTP_USERNAME}")/<code><code> private String FTP_USERNAME; // ftp 服務器用戶名/<code><code> @Value("${FTP_PASSWORD}")/<code><code> private String FTP_PASSWORD; // ftp 服務器密碼/<code><code> @Value("${FTP_BASE_PATH}")/<code><code> private String FTP_BASE_PATH; // ftp 服務器存儲圖片的絕對路徑/<code><code> @Value("${IMAGE_BASE_URL}")/<code><code> private String IMAGE_BASE_URL; // ftp 服務器外網訪問圖片路徑/<code>

<code> @Override/<code><code> public Map uploadPicture(MultipartFile uploadFile) {/<code><code> Map resultMap = new HashMap<>;/<code><code> try {/<code><code> // 1. 取原始文件名/<code><code> String oldName = uploadFile.getOriginalFilename;/<code>
<code> // 2. ftp 服務器的文件名/<code><code> String newName = oldName;/<code><code> //圖片上傳/<code><code> boolean result = uploadFile(FTP_ADDRESS, FTP_PORT, FTP_USERNAME, FTP_PASSWORD, /<code><code> uploadFile.getInputStream, FTP_BASE_PATH, newName);/<code><code> //返回結果/<code><code> if(!result) {/<code><code> resultMap.put("error", 1);/<code><code> resultMap.put("message", "upload Fail");/<code><code> return resultMap;/<code><code> }/<code><code> resultMap.put("error", 0);/<code><code> resultMap.put("url", IMAGE_BASE_URL + "/" + newName);/<code><code> return resultMap;/<code>
<code> } catch (Exception e) {/<code><code> e.printStackTrace;/<code><code> resultMap.put("error", 1);/<code><code> resultMap.put("message", "upload Fail");/<code><code> return resultMap;/<code><code> }/<code><code> }/<code>
<code> /**/<code><code> * ftp 上傳圖片方法/<code><code> * @param ip ftp 服務器ip地址/<code><code> * @param port ftp 服務器port,默認是21/<code><code> * @param account ftp 服務器用戶名/<code><code> * @param passwd ftp 服務器密碼/<code><code> * @param inputStream 文件流/<code><code> * @param workingDir ftp 服務器存儲圖片的絕對路徑/<code><code> * @param fileName 上傳到ftp 服務器文件名/<code><code> * @throws Exception/<code><code> * /<code><code> *//<code><code> public boolean uploadFile(String ip, Integer port, String account, String passwd,/<code><code> InputStream inputStream, String workingDir, String fileName) throws Exception{/<code><code> boolean result = false;/<code><code> // 1. 創建一個FtpClient對象/<code><code> FTPClient ftpClient = new FTPClient;/<code><code> try {/<code><code> // 2. 創建 ftp 連接/<code><code> ftpClient.connect(ip, port);/<code><code> // 3. 登錄 ftp 服務器/<code><code> ftpClient.login(account, passwd);/<code><code> int reply = ftpClient.getReplyCode; // 獲取連接ftp 狀態返回值/<code><code> System.out.println("code : " + reply);/<code><code> if (!FTPReply.isPositiveCompletion(reply)) {/<code><code> ftpClient.disconnect; // 如果返回狀態不再 200 ~ 300 則認為連接失敗/<code><code> return result;/<code><code> }/<code><code> // 4. 讀取本地文件/<code><code>// FileInputStream inputStream = new FileInputStream(new File("F:\\\\hello.png"));/<code><code> // 5. 設置上傳的路徑/<code><code> ftpClient.changeWorkingDirectory(workingDir);/<code><code> // 6. 修改上傳文件的格式為二進制/<code><code> ftpClient.setFileType(FTP.BINARY_FILE_TYPE);/<code><code> // 7. 服務器存儲文件,第一個參數是存儲在服務器的文件名,第二個參數是文件流/<code><code> if (!ftpClient.storeFile(fileName, inputStream)) {/<code><code> return result;/<code><code> }/<code><code> // 8. 關閉連接/<code><code> inputStream.close;/<code><code> ftpClient.logout;/<code><code> result = true;/<code><code> } catch (Exception e) {/<code><code> e.printStackTrace;/<code><code> }finally {/<code><code> // FIXME 聽說,項目裡面最好少用try catch 捕獲異常,這樣會導致Spring的事務回滾出問題???難道之前寫的代碼都是假代碼!!!/<code><code> if (ftpClient.isConnected) {/<code><code> try {/<code><code> ftpClient.disconnect;/<code><code> } catch (IOException ioe) {/<code><code> }/<code><code> }/<code><code> }/<code><code> return result;/<code><code> }/<code><code>}/<code>

說明:

  • @Value 註解是Spring4 中提供的,@Value("${XXX}")

  • 返回值是一個Map,並且key有error,url,message。這是根據KindEditer的語法要求來的。詳情見鏈接。http://kindeditor.net/docs/upload.html

Controller 層

負責頁面跳轉的 PageController.java

<code>@Controller/<code><code>public class PageController {/<code>
<code> /**/<code><code> * 打開首頁/<code><code> *//<code><code> @RequestMapping("/")/<code><code> public String showIndex {/<code><code> return "index";/<code><code> }/<code>
<code> @RequestMapping("/{page}")/<code><code> public String showpage(@PathVariable String page) {/<code><code> System.out.println("page : " + page);/<code><code> return page;/<code><code> }/<code><code>}/<code>

負責圖片上傳的 PictureController.java

<code>@RestController/<code><code>public class PictureController {/<code>
<code> @Autowired/<code><code> private PictureService pictureService;/<code>
<code> @RequestMapping("pic/upload")/<code><code> public String pictureUpload(@RequestParam(value = "fileUpload") MultipartFile uploadFile) {/<code><code> String json = "";/<code><code> try {/<code><code> Map result = pictureService.uploadPicture(uploadFile);/<code><code> // 瀏覽器擅長處理json格式的字符串,為了減少因為瀏覽器內核不同導致的bug,建議用json/<code><code> json = new ObjectMapper.writeValueAsString(result);/<code><code> } catch (JsonProcessingException e) {/<code><code> e.printStackTrace;/<code><code> }/<code><code> return json;/<code><code> }/<code><code>}/<code>

說明:

  • @RestController 也是Spring4 提供的,是 @Controller + @ResponseBody 的組合註解。

  • Controller層的返回值是一個json格式的字符串。是考慮到瀏覽器對json解析兼容性比較好。

Views視圖層

負責上傳圖片的視圖頁面:

<code><form>/<code><code> /<code><code> /<code><code> /<code><code> 
/<code><code>

借用KindEditor富文本編輯器實現批量上傳圖片

/<code><code> <textarea>dden;">/<textarea>/<code><code> /<code><code> $(function{/<code><code> //初始化富文本編輯器/<code><code> KindEditor.create("#kindEditorDesc", {/<code><code> // name值,必須和Controller 的參數對應,不然會提示 400 的錯誤/<code><code> filePostName : "fileUpload",/<code><code> // action值,/<code><code> uploadJson : '/pic/upload',/<code><code> // 設置上傳類型,分別為image、flash、media、file/<code><code> dir : "image"/<code><code> });/<code><code> });/<code><code> /<code>

說明:視圖分為兩個部分,第一個部分是為了測試上傳圖片功能的form表單。第二個部分是為了更好的體驗上傳,批量上傳,回顯功能的KindEditer 富文本編輯器。

總結

  • Nginx 搭建服務器的思維

  • Java實現 Ftp上傳圖片的功能

  • KindEditer 上傳圖片的功能

源碼:https://github.com/ITDragonBlog/daydayup/tree/master/Nginx

Nginx 搭建圖片服務器到這裡就結束了,有什麼不足的地方,請賜教。如果覺得不錯,可以點個贊哦!

如果喜歡本篇文章,歡迎轉發、點贊。關注訂閱號「Web項目聚集地」,回覆「全棧」即可獲取 2019 年最新 Java、Python、前端學習視頻資源。


分享到:


相關文章: