Java实现Nginx图片上传

简介

文件上传功能,是信息系统开发中的常用功能,在传统的开发流程中,前端通过表单上传文件,后端进行文件处理。不利之处在于

  1. 后端需要写重复代码,每开发一个包含上传功能的系统,就需要写一遍上传逻辑。
  2. 当文件未保存在共享服务器时,其它开发人员无法获取上传的文件的正确地址。
  3. 当文件保存在共享文件系统时,需要对共享文件系统进行读写获取对应文件。

       基于以上不利之处,我们结合包含了upload_module和upload-progress_module的nginx,以及nginx本身作为http服务器的特性,设计了本文件上传服务器,希望能减少大家的开发量。

1.文件上传服务器原理

2.部署Nginx上传服务器

部署Nginx上传服务器在上一篇文章已经说明,这里就不再赘述,详见docker 安装 Nginx 作为上传服务器

启动Nginx。

3.上传控件的使用

    ①使用iframeUplaod上传文件插件,该代码基本原理就是动态创建一个iframe,在iframe中再增加一个form,最后数据放到这个form中提交给服务器,前端代码如下:

<body>
<div id="uploadFile" class="upload">

</div>
<a href="javascript:void(0);" id="submit">提交</a>
<div class="pic-upload fl">
    <div id="imgPreview">
        <img class="picIcon" id="picIcon" src="${basePath}/resources/theme/images/user_default.jpg">
    </div>
    <input type="hidden" id="iconUrl" value="${basePath}/resources/theme/images/user_default.jpg">
</div>
<script src="${basePath}/resources/others/jquery/jquery-1.8.3.min.js"></script>
<script src="${basePath}/resources/upload/iframeUpload.js"></script>
<script language="javaScript">
    $(function () {
        var localPath = 'http://'+document.domain + ":" +
                window.location.port + basePath+"/result";
        var submitForm = IframeUpload.create({
            id: "1",
            url: basePath+"/fastdfs/systemIcon",
            //progressUrl:"http://192.168.2.125:10000/progress",
            interval:300,
            containerId: 'uploadFile',
            resultPath:localPath,
            success: function (res) {
            	if (res.result == 'success') {
                    $("#iconUrl").val(res.msg);
                    $(".picIcon").attr('src', res.msg);
                } else {
                	alert("上传失败!!!");
                }
            },
        });

        $('a#submit').click(function(){
            submitForm.submit();
        });
    });
 </script>
</body>

 

②如何在Java应用中集成上传文件组件

    ●在项目的pom.xml文件中添加相关依赖 

<dependency>
	<groupId>com.jcraft</groupId>
	<artifactId>jsch</artifactId>
	<version>0.1.54</version>
</dependency>
<dependency>
	<groupId>com.jcabi</groupId>
	<artifactId>jcabi-ssh</artifactId>
	<version>1.5.2</version>
</dependency> 
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.8</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.3.2</version>
</dependency>

      这里省略了spring相关依赖,若需要其他依赖,读者可自行查找添加。

    ●将config.properties中的内容复制到项目所在的properties文件中,并配置以下内容

remote.host=192.168.2.125           #文件上传服务器ip
remote.port=22                      #文件上传服务器的SSH端口
remote.user=root                    #文件上传服务器的SSH用户名
remote.password=123456              #文件上传服务器的密码
remote.dir=/root/nginx/files/       #nginx配置的上传文件目录
nginx.port=10000                    #nginx中配置监听的端口
nginx.fileuri=/files                #nginx配置转发文件uri
remote.extern.host=192.168.2.125    #访问路径的host

    ●在spring-mvc.xml文件中引入conf.properties文件

<bean id="appProperty"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
         <array>
             <value>classpath:conf.properties</value>
          </array>
    </property>
</bean>

    ●在spring-mvc.xml文件中配置文件上传解析器

<!-- 文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"></property>
    <property name="maxUploadSize" value="524288000"></property>
</bean>

● 编写上传文件工具类,获取上传后的图片地址以及重命名文件

package com.eshore.upload.util;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.jcabi.ssh.SSHByPassword;
import com.jcabi.ssh.Shell;

@Component
public class FileUploadUtil {
    @Value("${remote.host}")
    private String remoteHost;

    @Value("${remote.port}")
    private String remotePort;

    @Value("${remote.user}")
    private String remoteUser;

    @Value("${remote.password}")
    private String remotePassword;

    @Value("${remote.dir}")
    private String remoteDir;

    @Value("${nginx.port}")
    private String nginxPort;

    @Value("${nginx.fileuri}")
    private String nginxFileUri;

    public String getUrlFromRequest(HttpServletRequest request,String filename) throws NullPointerException{
        StringBuilder builder = new StringBuilder("http://");
        builder.append(remoteHost);
        builder.append(":");
        builder.append(nginxPort);
        builder.append(nginxFileUri);
        builder.append("/");
        builder.append(filename);
        return builder.toString();
    }

    public String renameFile(HttpServletRequest request) throws IOException,NullPointerException{
		Shell shell = new SSHByPassword(remoteHost, Integer.valueOf(remotePort), remoteUser, remotePassword);

		Shell.Plain plain = new Shell.Plain(shell);

		String orgFile = request.getParameter("file_name");

		if (orgFile == null) {
			throw new NullPointerException("文件名不存在");
		}
		orgFile.replaceAll(" ", "");
		String hostFile = request.getParameter("file_path");
		if (hostFile == null) {
			throw new NullPointerException("文件路径不存在");
		}

		String timestamp = new SimpleDateFormat("YYYY-MM-dd-HH-mm-ss").format(new Date()).toString();
		String filename = new StringBuilder(timestamp).append("-").append(orgFile).toString().replaceAll(" ", "").replaceAll("/", "");

		String hostFilePath = remoteDir.concat(hostFile.substring(hostFile.lastIndexOf("/") + 1));
		String orgFilePath = remoteDir.concat(filename);

		String renameCmd = new StringBuilder("mv ").append("\'").append(hostFilePath).append("\'").append(" ")
				.append("\'").append(orgFilePath).append("\'").toString();

		String result = plain.exec(renameCmd);

		if (!result.isEmpty()) {
			throw new NullPointerException("命令运行失败,请检查文件名是否有特殊符号,如()");
		}

		return filename;
    }
}

    ●Controller层处理,返回结果,图片url入库

package com.eshore.upload.controller;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;

import com.eshore.upload.util.FileUploadUtil;

@Controller
public class UploadController {
	
	@Autowired
    private FileUploadUtil fileUploadUtil;
	
	@RequestMapping("/hello")
	public String hello() {
		return "hello";
	}
	
	@RequestMapping("/systemIcon")
    public RedirectView uploadSystemIcon(HttpServletRequest request,
                                         HttpServletResponse response, RedirectAttributes ra) {
        String url = null; //这个URL是最终跳转返回的URL,本实例中,为/upload/result
        String newUrl = request.getParameter("org");
        try {

            //重命名文件名称
            String filename = fileUploadUtil.renameFile(request);
            //获取返回的URL
            url = fileUploadUtil.getUrlFromRequest(request, filename);
            /**
             * 如果需要保存图片信息,这里可以将url存入到数据库
             */
        } catch (NullPointerException | IOException e) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            ra.addAttribute("result", "fail");
            ra.addAttribute("msg", "exception happened");
            return new RedirectView(newUrl);
        }

        ra.addAttribute("result", "success");
        ra.addAttribute("msg", url);
        
        return new RedirectView(newUrl);
    }

    @RequestMapping("/result")
    public ModelAndView result(HttpServletRequest request) throws IOException {
        ModelAndView view = new ModelAndView("upload/result");
        return view;
    }
    
    @RequestMapping("/file")
    public ModelAndView file(HttpServletRequest request) throws IOException {
        ModelAndView view = new ModelAndView("upload/upload");
        return view;
    }

}

4.项目源码

    项目源码已同步到GitHub:https://github.com/yinZh0522/nginx-upload

      

发布了11 篇原创文章 · 获赞 12 · 访问量 2万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览