文件上传功能,是信息系统开发中的常用功能,在传统的开发流程中,前端通过表单上传文件,后端进行文件处理。不利之处在于
基于以上不利之处,我们结合包含了upload_module和upload-progress_module的nginx,以及nginx本身作为http服务器的特性,设计了本文件上传服务器,希望能减少大家的开发量。
部署Nginx上传服务器在上一篇文章已经说明,这里就不再赘述,详见docker 安装 Nginx 作为上传服务器
启动Nginx。
①使用iframeUplaod上传文件插件,该代码基本原理就是动态创建一个iframe,在iframe中再增加一个form,最后数据放到这个form中提交给服务器,前端代码如下:
提交
②如何在Java应用中集成上传文件组件
●在项目的pom.xml文件中添加相关依赖
com.jcraft
jsch
0.1.54
com.jcabi
jcabi-ssh
1.5.2
commons-fileupload
commons-fileupload
1.3.1
commons-codec
commons-codec
1.8
org.apache.commons
commons-lang3
3.3.2
这里省略了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文件
classpath:conf.properties
●在spring-mvc.xml文件中配置文件上传解析器
● 编写上传文件工具类,获取上传后的图片地址以及重命名文件
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;
}
}
项目源码已同步到GitHub:https://github.com/yinZh0522/nginx-upload