Nginx(4)之搭建图片服务器

最近在学nginx,然后想起了之前大学做的一个商城网站,图片就是用nginx作为图片服务器,在这里分享记录一下。

技术:Nginx,Vsftpd,Spring,SpringMVC,KindEditor,CentOS,注意KindEditor这个富文本编辑器他不是事先图片服务器的必要技术,只是使用 KindEditer 是为了更好的演示图片的上传,回显,批量效果。后台代码与KindEditer没有直接关系。

一、介绍

场景:用户将图片上传到 tomcat 服务器上,再由 tomcat 服务器通过FTP上传到 Nginx 服务器上。

项目结构:

 

二、代码介绍

首先要攻破核心技术。通过单元测试实现图片上传的功能。

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 的核心文件 pom.xml,添加下列对应版本的依赖即可,可前去https://mvnrepository.com/tags/maven 查找依赖。

<!--定义别名-->
    <properties>
        <java-version>1.8</java-version>
        <servlet-version>3.1.0</servlet-version>
        <junit-version>4.12</junit-version>
        <springframework-version>4.2.6.RELEASE</springframework-version>
        <mybatis-version>3.4.1</mybatis-version>
        <mybatis-spring-version>1.3.0</mybatis-spring-version>
        <mysql-version>5.1.38</mysql-version>
        <hibernate-validator-version>5.4.1.Final</hibernate-validator-version>
        <druid-version>1.0.28</druid-version>
        <commons-lang-version>2.6</commons-lang-version>
        <commons-fileupload-version>1.3.1</commons-fileupload-version>
        <commons-io-version>2.5</commons-io-version>
        <commons-codec-version>1.10</commons-codec-version>
        <commons-configuration-version>1.10</commons-configuration-version>
        <slf4j-version>1.7.19</slf4j-version>
        <log4j-version>1.2.17</log4j-version>
        <fastjson-version>1.2.30</fastjson-version>
        <shiro-version>1.3.2</shiro-version>
        <kaptcha-version>0.0.9</kaptcha-version>
        <velocity-version>1.7</velocity-version>
        <velocity-tools-version>2.0</velocity-tools-version>
        <jstl-version>1.2</jstl-version>
        <taglibs-version>1.1.2</taglibs-version>
        <freemarker-version>2.3.23</freemarker-version>
        <poi.version>3.15</poi.version>
        <sub.version>3.1.0</sub.version>
    </properties>

说明:和文件上传有直接关系的是:

<dependency>
     <groupId>commons-fileupload</groupId>
     <artifactId>commons-fileupload</artifactId>
</dependency>

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

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="taotao" version="2.5">
    <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 id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设定默认编码 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 设定文件上传的最大值5MB,5*1024*1024 -->
        <property name="maxUploadSize" value="5242880"></property>
    </bean>

最后是 Ftp 配置文件 resource.properties

#ftp图片服务器连接参数
#FTP_HOST=192.168.23.130
FTP_HOST=192.168.175.128
FTP_PROT=21
FTP_USERNAME=ftpuser
FTP_PASSWORD=199507
FTP_BASEURL=/home/ftpuser/mqc/image
##图片回显路径
PICTURE_BASEURL=http://192.168.175.128/image/
#PICTURE_BASEURL=http://192.168.23.130/image/

Service 层

package com.mqc.service.upload;

import com.mqc.common.result.PictureResult;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author 毛其传
 * @Description: 图片上传服务逻辑接口
 * @date 2018/4/11
 */
public interface IPictureService {

    /**
     * @Description: 上传图片到Nginx服务器
     * @author 毛其传
     * @date 2018/4/11
     */
    PictureResult uploadPicture(MultipartFile file);
}

上传图片接口实现类 PictureServiceImpl.java

package com.mqc.service.upload.impl;

import com.mqc.common.constant.PictureConstant;
import com.mqc.common.result.PictureResult;
import com.mqc.service.upload.IPictureService;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author 毛其传
 * @Description: 图片上传服务逻辑实现类
 * @date 2018/4/11
 */
@Service
public class PictureServiceImpl implements IPictureService {

    @Value("${FTP_HOST}")
    private String FTP_HOST;   //Nginx服务器地址
    @Value("${FTP_USERNAME}")
    private String FTP_USER;       //ftp用户名
    @Value("${FTP_PASSWORD}")
    private String FTP_PASSWORD;   //ftp密码
    @Value("${FTP_BASEURL}")
    private String PICTURE_BASE_URL;  //图片上传的基础路径
    @Value("${PICTURE_BASEURL}")
    private String PICTURE_URL;    //图片回调的基础路径

    /**
     * @Description: 上传图片到Nginx服务器
     * @author 毛其传
     * @date 2018/4/11
     */
    @Override
    public PictureResult uploadPicture(MultipartFile file) {
        PictureResult result = new PictureResult();
        try {
            if (null != file) {
                //图片原始名称
                String filename = file.getOriginalFilename();

                //图片的类型
                String fileType = filename.substring(filename.indexOf("."));

                //上传之后图片的名称
                String new_fileName = PictureConstant.genImageName() + fileType;

                FTPClient client = new FTPClient();

                client.connect(FTP_HOST);

                client.login(FTP_USER, FTP_PASSWORD);

                client.changeWorkingDirectory(PICTURE_BASE_URL);
                //解决上传0字节问题
                client.enterLocalPassiveMode();
                //设置图片上传格式为二进制
                client.setFileType(FTP.BINARY_FILE_TYPE);
                client.storeFile(new_fileName, file.getInputStream());

                client.logout();

                //图片上传成功
                result.setError(0);
                result.setUrl(PICTURE_URL + new_fileName);
            } else {
                result.setError(1);
                result.setMessage("上传图片不能为空");
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.setError(1);
            result.setMessage("上传失败");
        }

        return result;
    }
}

Controller 层:负责页面跳转的 PageController.java

@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

@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;
    }
}

Views视图层

<form action="pic/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="fileUpload" />
        <input type="submit" value="上传文件" />
    </form>
    <hr />
    <h3>借用KindEditor富文本编辑器实现批量上传图片</h3>
    <textarea id="kindEditorDesc" style="width:800px;height:300px;visibility:hidden;"></textarea>
    <script type="text/javascript">
        $(function(){
            //初始化富文本编辑器
            KindEditor.create("#kindEditorDesc", {
                // name值,必须和Controller 的参数对应,不然会提示 400 的错误
                filePostName : "fileUpload",
                // action值,
                uploadJson : '/pic/upload',
                // 设置上传类型,分别为image、flash、media、file
                dir : "image"
            });
        });
</script>   

说明:视图分为两个部分,第一个部分是为了测试上传图片功能的form表单。第二个部分是为了更好的体验上传,批量上传,回显功能的KindEditer 富文本编辑器。

总结

  • Nginx 搭建服务器的思维

  • Java实现 Ftp上传图片的功能

  • KindEditer 上传图片的功能

Nginx 搭建图片服务器到这里就结束了,有什么不足的地方,请赐教。如果觉得不错,可以点个赞哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值