Nginx怎么搭建圖片服務器

效果圖:

Nginx怎么搭建圖片服務器

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

技術:nginx,vsftpd,spring,springmvc,kindeditor,centos

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

源碼:見文章底部

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

Nginx怎么搭建圖片服務器

項目結構:

Nginx怎么搭建圖片服務器

單元測試

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

package?com.itdragon.test;  import?Java.io.file; import?java.io.fileinputstream;  import?org.apache.commons.net.ftp.ftp; import?org.apache.commons.net.ftp.ftpclient; import?org.junit.test;  public?class?pictureftptest?{  ??//?測試?ftp?上傳圖片功能 ??@test ??public?void?testftpclient()?throws?exception?{ ????//?1.?創建一個ftpclient對象 ????ftpclient?ftpclient?=?new?ftpclient(); ????//?2.?創建?ftp?連接 ????ftpclient.connect("192.168.0.11",?21); ????//?3.?登錄?ftp?服務器 ????ftpclient.login("ftpuser",?"root"); ????//?4.?讀取本地文件 ????fileinputstream?inputstream?=?new?fileinputstream(new?file("f:hello.png")); ????//?5.?設置上傳的路徑 ????ftpclient.changeworkingdirectory("/usr/local/nginx/html/images"); ????//?6.?修改上傳文件的格式為二進制 ????ftpclient.setfiletype(ftp.binary_file_type); ????//?7.?服務器存儲文件,第一個參數是存儲在服務器的文件名,第二個參數是文件流 ????ftpclient.storefile("hello.jpg",?inputstream); ????//?8.?關閉連接 ????ftpclient.logout(); ???? ??} ?? }

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

maven 的web 項目

搭建maven的web 項目,之前有寫過。這里就不過多描述。

項目核心配置文件

首先是 maven 的核心文件 pom.xml

<project> ??<modelversion>4.0.0</modelversion> ??<groupid>com.itdragon.upload</groupid> ??<artifactid>pictrue-service</artifactid> ??<version>0.0.1-snapshot</version> ??<packaging>war</packaging>  ??<!-- 集中定義依賴版本號 --> ??<properties> ????<junit.version>4.12</junit.version> ????<spring.version>4.1.3.release</spring.version> ????<mybatis.version>3.2.8</mybatis.version> ????<mybatis.spring.version>1.2.2</mybatis.spring.version> ????<mybatis.paginator.version>1.2.15</mybatis.paginator.version> ????<mysql.version>5.1.6</mysql.version> ????<slf4j.version>1.6.4</slf4j.version> ????<jackson.version>2.4.2</jackson.version> ????<druid.version>1.0.9</druid.version> ????<httpclient.version>4.3.5</httpclient.version> ????<jstl.version>1.2</jstl.version> ????<servlet-api.version>2.5</servlet-api.version> ????<jsp-api.version>2.0</jsp-api.version> ????<joda-time.version>2.5</joda-time.version> ????<commons-lang3.version>3.3.2</commons-lang3.version> ????<commons-io.version>1.3.2</commons-io.version> ????<commons-net.version>3.3</commons-net.version> ????<pagehelper.version>3.4.2</pagehelper.version> ????<jsqlparser.version>0.9.1</jsqlparser.version> ????<commons-fileupload.version>1.3.1</commons-fileupload.version> ????<jedis.version>2.7.2</jedis.version> ????<solrj.version>4.10.3</solrj.version> ??</properties> ??<dependencies> ????<!-- 時間操作組件 --> ????<dependency> ??????<groupid>joda-time</groupid> ??????<artifactid>joda-time</artifactid> ??????<version>${joda-time.version}</version> ????</dependency> ????<!-- apache工具組件 --> ????<dependency> ??????<groupid>org.apache.commons</groupid> ??????<artifactid>commons-lang3</artifactid> ??????<version>${commons-lang3.version}</version> ????</dependency> ????<dependency> ??????<groupid>org.apache.commons</groupid> ??????<artifactid>commons-io</artifactid> ??????<version>${commons-io.version}</version> ????</dependency> ????<dependency> ??????<groupid>commons-net</groupid> ??????<artifactid>commons-net</artifactid> ??????<version>${commons-net.version}</version> ????</dependency> ????<!-- jackson json處理工具包 --> ????<dependency> ??????<groupid>com.fasterxml.jackson.core</groupid> ??????<artifactid>jackson-databind</artifactid> ??????<version>${jackson.version}</version> ????</dependency> ????<!-- httpclient --> ????<dependency> ??????<groupid>org.apache.httpcomponents</groupid> ??????<artifactid>httpclient</artifactid> ??????<version>${httpclient.version}</version> ????</dependency> ????<!-- 單元測試 --> ????<dependency> ??????<groupid>junit</groupid> ??????<artifactid>junit</artifactid> ??????<version>${junit.version}</version> ??????<scope>test</scope> ????</dependency> ????<!-- 日志處理 --> ????<dependency> ??????<groupid>org.slf4j</groupid> ??????<artifactid>slf4j-log4j12</artifactid> ??????<version>${slf4j.version}</version> ????</dependency> ????<!-- mybatis --> ????<dependency> ??????<groupid>org.mybatis</groupid> ??????<artifactid>mybatis</artifactid> ??????<version>${mybatis.version}</version> ????</dependency> ????<dependency> ??????<groupid>org.mybatis</groupid> ??????<artifactid>mybatis-spring</artifactid> ??????<version>${mybatis.spring.version}</version> ????</dependency> ????<dependency> ??????<groupid>com.github.miemiedev</groupid> ??????<artifactid>mybatis-paginator</artifactid> ??????<version>${mybatis.paginator.version}</version> ????</dependency> ????<dependency> ??????<groupid>com.github.pagehelper</groupid> ??????<artifactid>pagehelper</artifactid> ??????<version>${pagehelper.version}</version> ????</dependency> ????<!-- mysql --> ????<dependency> ??????<groupid>mysql</groupid> ??????<artifactid>mysql-connector-java</artifactid> ??????<version>${mysql.version}</version> ????</dependency> ????<!-- 連接池 --> ????<dependency> ??????<groupid>com.alibaba</groupid> ??????<artifactid>druid</artifactid> ??????<version>${druid.version}</version> ????</dependency> ????<!-- spring --> ????<dependency> ??????<groupid>org.springframework</groupid> ??????<artifactid>spring-context</artifactid> ??????<version>${spring.version}</version> ????</dependency> ????<dependency> ??????<groupid>org.springframework</groupid> ??????<artifactid>spring-beans</artifactid> ??????<version>${spring.version}</version> ????</dependency> ????<dependency> ??????<groupid>org.springframework</groupid> ??????<artifactid>spring-webmvc</artifactid> ??????<version>${spring.version}</version> ????</dependency> ????<dependency> ??????<groupid>org.springframework</groupid> ??????<artifactid>spring-jdbc</artifactid> ??????<version>${spring.version}</version> ????</dependency> ????<dependency> ??????<groupid>org.springframework</groupid> ??????<artifactid>spring-aspects</artifactid> ??????<version>${spring.version}</version> ????</dependency> ????<!-- jsp相關 --> ????<dependency> ??????<groupid>jstl</groupid> ??????<artifactid>jstl</artifactid> ??????<version>${jstl.version}</version> ????</dependency> ????<dependency> ??????<groupid>javax.servlet</groupid> ??????<artifactid>servlet-api</artifactid> ??????<version>${servlet-api.version}</version> ??????<scope>provided</scope> ????</dependency> ????<dependency> ??????<groupid>javax.servlet</groupid> ??????<artifactid>jsp-api</artifactid> ??????<version>${jsp-api.version}</version> ??????<scope>provided</scope> ????</dependency> ????<!-- 文件上傳組件 --> ????<dependency> ??????<groupid>commons-fileupload</groupid> ??????<artifactid>commons-fileupload</artifactid> ??????<version>${commons-fileupload.version}</version> ????</dependency> ????<!-- redis客戶端 --> ????<dependency> ??????<groupid>redis.clients</groupid> ??????<artifactid>jedis</artifactid> ??????<version>${jedis.version}</version> ????</dependency> ????<!-- solr客戶端 --> ????<dependency> ??????<groupid>org.apache.solr</groupid> ??????<artifactid>solr-solrj</artifactid> ??????<version>${solrj.version}</version> ????</dependency> ??</dependencies>  ??<build> ????<finalname>${project.artifactid}</finalname> ????<plugins> ??????<!-- 資源文件拷貝插件 --> ??????<plugin> ????????<groupid>org.apache.maven.plugins</groupid> ????????<artifactid>maven-Resources-plugin</artifactid> ????????<version>2.7</version> ????????<configuration> ??????????<encoding>utf-8</encoding> ????????</configuration> ??????</plugin> ??????<!-- java編譯插件 --> ??????<plugin> ????????<groupid>org.apache.maven.plugins</groupid> ????????<artifactid>maven-compiler-plugin</artifactid> ????????<version>3.2</version> ????????<configuration> ??????????<source>1.7</source> ??????????<target>1.7</target> ??????????<encoding>utf-8</encoding> ????????</configuration> ??????</plugin> ????</plugins> ????<pluginmanagement> ??????<plugins> ????????<!-- 配置tomcat插件 --> ????????<plugin> ??????????<groupid>org.apache.tomcat.maven</groupid> ??????????<artifactid>tomcat7-maven-plugin</artifactid> ??????????<version>2.2</version> ????????</plugin> ??????</plugins> ????</pluginmanagement> ??</build></project>

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

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

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

<?xml  version="1.0" encoding="utf-8"?><web-app> ??<display-name>pictrue-service</display-name> ??<!-- 加載spring容器 --> ??<context-param> ????<param-name>contextconfiglocation</param-name> ????<param-value>classpath:spring/applicationcontext-*.xml</param-value> ??</context-param> ??<listener> ????<listener-class>org.springframework.web.context.contextloaderlistener</listener-class> ??</listener> ??<!-- 解決post亂碼 --> ??<filter> ????<filter-name>characterencodingfilter</filter-name> ????<filter-class>org.springframework.web.filter.characterencodingfilter</filter-class> ????<init-param> ??????<param-name>encoding</param-name> ??????<param-value>utf-8</param-value> ????</init-param> ??</filter> ??<filter-mapping> ????<filter-name>characterencodingfilter</filter-name> ????<url-pattern>/*</url-pattern> ??</filter-mapping> ??<!-- springmvc的前端控制器 --> ??<servlet> ????<servlet-name>pictrue-service</servlet-name> ????<servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class> ????<init-param> ??????<param-name>contextconfiglocation</param-name> ??????<param-value>classpath:spring/springmvc.xml</param-value> ????</init-param> ????<load-on-startup>1</load-on-startup> ??</servlet> ??<servlet-mapping> ????<servlet-name>pictrue-service</servlet-name> ????<url-pattern>/</url-pattern> ??</servlet-mapping></web-app>

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

<!-- 定義文件上傳解析器 --> ??<bean> ????<!-- 設定默認編碼 --> ????<property></property> ????<!-- 設定文件上傳的最大值5mb,5*1024*1024 --> ????<property></property> ??</bean>

最后是 ftp 配置文件 resource.properties

ftp_address=192.168.0.11 ftp_port=21 ftp_username=ftpuser ftp_password=root ftp_base_path=/usr/local/nginx/html/images image_base_url=http://192.168.0.11/images

service 層

上傳圖片的接口 pictureservice.java

package?com.itdragon.service; import?java.util.map; import?org.springframework.web.multipart.multipartfile; public?interface?pictureservice?{  ??/** ???*?上傳,批量上傳接口 ???*?@param?uploadfile ???*?@return ???*/ ??map?uploadpicture(multipartfile?uploadfile); }

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

package?com.itdragon.service.impl;  import?java.io.ioexception; import?java.io.inputstream; import?java.util.hashmap; import?java.util.map;  import?org.apache.commons.net.ftp.ftp; import?org.apache.commons.net.ftp.ftpclient; import?org.apache.commons.net.ftp.ftpreply; import?org.springframework.beans.factory.annotation.value; import?org.springframework.stereotype.service; import?org.springframework.web.multipart.multipartfile;  import?com.itdragon.service.pictureservice;  @service @suppresswarnings({"rawtypes",?"unchecked"}) public?class?pictureserviceimpl?implements?pictureservice?{ ?? ??//?通過?spring4?的?value注解,獲取配置文件中的屬性值 ??@value("${ftp_address}") ??private?string?ftp_address;???//?ftp?服務器ip地址 ??@value("${ftp_port}") ??private?integer?ftp_port;????//?ftp?服務器port,默認是21 ??@value("${ftp_username}") ??private?string?ftp_username;??//?ftp?服務器用戶名 ??@value("${ftp_password}") ??private?string?ftp_password;??//?ftp?服務器密碼 ??@value("${ftp_base_path}") ??private?string?ftp_base_path;??//?ftp?服務器存儲圖片的絕對路徑 ??@value("${image_base_url}") ??private?string?image_base_url;?//?ftp?服務器外網訪問圖片路徑  ??@override ??public?map?uploadpicture(multipartfile?uploadfile)?{ ????map?resultmap?=?new?hashmap(); ????try?{ ??????//?1.?取原始文件名 ??????string?oldname?=?uploadfile.getoriginalfilename(); ?????? ??????//?2.?ftp?服務器的文件名 ??????string?newname?=?oldname; ??????//圖片上傳 ??????boolean?result?=?uploadfile(ftp_address,?ftp_port,?ftp_username,?ftp_password,? ??????????uploadfile.getinputstream(),?ftp_base_path,?newname); ??????//返回結果 ??????if(!result)?{ ????????resultmap.put("Error",?1); ????????resultmap.put("message",?"upload?fail"); ????????return?resultmap; ??????} ??????resultmap.put("error",?0); ??????resultmap.put("url",?image_base_url?+?"/"?+?newname); ??????return?resultmap; ?????? ????}?catch?(exception?e)?{ ??????e.printstacktrace(); ??????resultmap.put("error",?1); ??????resultmap.put("message",?"upload?fail"); ??????return?resultmap; ????} ??} ?? ??/** ???*?ftp?上傳圖片方法 ???*?@param?ip??????ftp?服務器ip地址 ???*?@param?port?????ftp?服務器port,默認是21 ???*?@param?account????ftp?服務器用戶名 ???*?@param?passwd????ftp?服務器密碼 ???*?@param?inputstream??文件流 ???*?@param?workingdir??ftp?服務器存儲圖片的絕對路徑 ???*?@param?filename???上傳到ftp?服務器文件名 ???*?@throws?exception ???*? ???*/ ??public?boolean?uploadfile(string?ip,?integer?port,?string?account,?string?passwd, ??????inputstream?inputstream,?string?workingdir,?string?filename)?throws?exception{ ????boolean?result?=?false; ????//?1.?創建一個ftpclient對象 ????ftpclient?ftpclient?=?new?ftpclient(); ????try?{ ??????//?2.?創建?ftp?連接 ??????ftpclient.connect(ip,?port); ??????//?3.?登錄?ftp?服務器 ??????ftpclient.login(account,?passwd); ??????int?reply?=?ftpclient.getreplycode();?//?獲取連接ftp?狀態返回值 ??????system.out.println("code?:?"?+?reply); ??????if?(!ftpreply.ispositivecompletion(reply))?{ ????????ftpclient.disconnect();?//?如果返回狀態不再?200?~?300?則認為連接失敗 ????????return?result; ??????} ??????//?4.?讀取本地文件 //?????fileinputstream?inputstream?=?new?fileinputstream(new?file("f:hello.png")); ??????//?5.?設置上傳的路徑 ??????ftpclient.changeworkingdirectory(workingdir); ??????//?6.?修改上傳文件的格式為二進制 ??????ftpclient.setfiletype(ftp.binary_file_type); ??????//?7.?服務器存儲文件,第一個參數是存儲在服務器的文件名,第二個參數是文件流 ??????if?(!ftpclient.storefile(filename,?inputstream))?{ ????????return?result; ??????} ??????//?8.?關閉連接 ??????inputstream.close(); ??????ftpclient.logout(); ??????result?=?true; ????}?catch?(exception?e)?{ ??????e.printstacktrace(); ????}finally?{ ??????//?fixme?聽說,項目里面最好少用try?catch?捕獲異常,這樣會導致spring的事務回滾出問題???難道之前寫的代碼都是假代碼!!! ??????if?(ftpclient.isconnected())?{ ????????try?{ ??????????ftpclient.disconnect(); ????????}?catch?(ioexception?ioe)?{ ????????} ??????} ????} ????return?result; ??}  }

說明:

① @value 注解是spring4 中提供的,@value(“${xxx}”)

② 返回值是一個map,并且key有error,url,message。這是根據kindediter的語法要求來的。

controller 層

負責頁面跳轉的 pagecontroller.java

package?com.itdragon.controller;  import?org.springframework.stereotype.controller; import?org.springframework.web.bind.annotation.pathvariable; import?org.springframework.web.bind.annotation.requestmapping;  @controller public?class?pagecontroller?{  ??/** ???*?打開首頁 ???*/ ??@requestmapping("/") ??public?string?showindex()?{ ????return?"index"; ??} ?? ??@requestmapping("/{page}") ??public?string?showpage(@pathvariable?string?page)?{ ????system.out.println("page?:?"?+?page); ????return?page; ??} }

負責圖片上傳的 picturecontroller.java

package?com.itdragon.controller;  import?java.util.map;  import?org.springframework.beans.factory.annotation.autowired; import?org.springframework.web.bind.annotation.requestmapping; import?org.springframework.web.bind.annotation.requestparam; import?org.springframework.web.bind.annotation.restcontroller; import?org.springframework.web.multipart.multipartfile;  import?com.fasterxml.jackson.core.jsonprocessingexception; import?com.fasterxml.jackson.databind.objectmapper; import?com.itdragon.service.pictureservice;  @restcontroller public?class?picturecontroller?{  ??@autowired ??private?pictureservice?pictureservice; ?? ??@requestmapping("pic/upload") ??public?string?pictureupload(@requestparam(value?=?"fileupload")?multipartfile?uploadfile)?{ ????string?json?=?""; ????try?{ ??????map?result?=?pictureservice.uploadpicture(uploadfile); ??????//?瀏覽器擅長處理json格式的字符串,為了減少因為瀏覽器內核不同導致的bug,建議用json ??????json?=?new?objectmapper().writevalueasstring(result); ????}?catch?(jsonprocessingexception?e)?{ ??????e.printstacktrace(); ????} ????return?json; ??} }

說明:

① @restcontroller 也是spring4 提供的,是 @controller + @responsebody 的組合注解。

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

views視圖層

負責上傳圖片的jsp頁面 pic-upload.jsp

 nbsp;html&gt;   <meta><title>itdragon?圖片上傳</title> ??<link> ??<script></script>? ??<script></script> ??<script></script>? ? ??<h3>測試上傳圖片功能接口的form表單</h3> ??
???? ???? ??

??


??

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

?? ??<script> $(function(){ //初始化富文本編輯器 kindeditor.create("#kindeditordesc", { // name值,必須和controller 的參數對應,不然會提示 400 的錯誤 filepostname : "fileupload", // action值, uploadjson : &#39;/pic/upload&#39;, // 設置上傳類型,分別為image、flash、media、file dir : "image" }); }); </script>??

? 版權聲明
THE END
喜歡就支持一下吧
點贊13 分享