1.Nginx上传介绍
文件在POST上传到nginx服务器时,nginx会自己将这个文件先保存下来,然后再往后端发送。
在这个过程中,文件会被保存成一个临时文件,待文件传送完成后,nginx向后端(如resin)通知临时文件的文件信息(如上传文件原有的文件名、存在本地磁盘哪个目录下、临时文件名、文件的md5、文件的类型、文件的大小等)。
后端服务拿到这个文件名可以直接读取缓存的文件,进行迁移转码等后续逻辑。
2.安装
下载nginx upload模块
http://www./nginx/upload.en.html
- tar zxvf nginx_upload_module-2.2.0.tar.gz
在nginx添加该模块
- ./configure --prefix=/usr/local/nginx --with-pcre=/root/pcre-8.11 --with-http_stub_status_module --with-http_realip_module --add-module=/root/nginx_upload_module-2.2.0 --add-module=/root/masterzen-nginx-upload-progress-module-3d8e105/
3.配置nginx.conf
- # Upload form should be submitted to this location
- location /upload {
- # Pass altered request body to this location
- upload_pass @test;
-
- upload_pass_args on;
- upload_max_file_size 1m;
-
- # Store files to this directory
- # The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist
- upload_store /tmp 1;
-
- # Allow uploaded files to be read only by user
- upload_store_access user:r;
- # Set specified fields in request body
- upload_set_form_field "${upload_field_name}.name" $upload_file_name;
- upload_set_form_field "${upload_field_name}.content_type" $upload_content_type;
- upload_set_form_field "${upload_field_name}.path" $upload_tmp_path;
-
- # Inform backend about hash and size of a file
- #upload_aggregate_form_field "${upload_field_name}.md5" $upload_file_md5;
- upload_aggregate_form_field "${upload_field_name}.crc32" $upload_file_crc32;
- upload_aggregate_form_field "${upload_field_name}.size" $upload_file_size;
- upload_pass_form_field "^submit$|^test$";
-
- upload_cleanup 400 404 499 500-505;
-
- }
-
- # Pass altered request body to a backend
- location @test {
- proxy_pass http://resin;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
指定上传文件的大小
- keepalive_timeout 200;
- client_max_body_size 100m;
二、.resin端程序的接收
1.上传的页面index.html
- <html>
- <head>
- <title>Test upload</title>
- </head>
- <body>
- <form enctype="multipart/form-data" action="/upload.so" method="post">
- <input type="hidden" name="test" value="上传">
-
- 选择文件1:
- <input type="file" name="filename1" />
- <br />
- 选择文件2:
- <input type="file" name="filename2" />
- <br />
- 选择文件3:
- <input type="file" name="filename3" />
- <br />
- <input type="submit" value="上载" />
- </form>
- </body>
2.添加一个Servlet.修改web.xml
- <servlet>
- <servlet-name>upload</servlet-name>
- <servlet-class>com.XXX.servlet.Upload</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>upload</servlet-name>
- <url-pattern>/upload.so</url-pattern>
- </servlet-mapping>
3.编写Servlet,
将file的信息封装到upFiles的map中。
页面的其他信息(如:test),封装到agrs的map中
- package com.XXXX.web.servlet;
-
- import java.io.IOException;
- import java.lang.reflect.Method;
- import java.text.MessageFormat;
- import java.util.HashMap;
- import java.util.Map;
-
- import javax.servlet.ServletContext;
- import javax.servlet.ServletException;
- import javax.servlet.ServletInputStream;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.springframework.web.context.WebApplicationContext;
- import org.springframework.web.context.support.WebApplicationContextUtils;
-
- import com.XXXX.model.UpFile;
- import com.XXXX.UploadManager;
-
- /**
- * @author winston
- *
- */
- public class Upload extends HttpServlet{
-
- private final Log log = LogFactory.getLog(Upload.class);
-
- private Map<String, UpFile> upFiles = new HashMap<String, UpFile>();
-
- private Map<String, String> agrs = new HashMap<String, String>();
-
- private ServletInputStream sis = null; //
-
- private byte[] b = new byte[4096]; //
-
- private static String rturl = "http://XXXXXX/ok.html";
-
- public static final String FILE_NAME="filename";
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
-
- ServletContext application = getServletContext();
- WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(application);//获取spring的context
- UploadManager uploadManager = (UploadManager) wac.getBean("uploadManager");
-
- sis = request.getInputStream();
- int a = 0;
- int k = 0;
- String s = "";
- while ((a = sis.readLine(b, 0, b.length)) != -1) {
- s = new String(b, 0, a);
-
- if ((k = s.indexOf("name=\"")) != -1) {
- String fieldName = s.substring(k + 6, s.length() - 3);
- sis.readLine(b, 0, b.length);
- StringBuffer fieldValue = new StringBuffer(b.length);
- while ((a = sis.readLine(b, 0, b.length)) != -1) {
- s = new String(b, 0, a - 2);
- if ((b[0] == 45) && (b[1] == 45) && (b[2] == 45)
- && (b[3] == 45) && (b[4] == 45)) {
- break;
- } else {
- fieldValue.append(s);
- }
- }
-
-
- if(fieldName.startsWith(FILE_NAME)){
- setField(fieldName, fieldValue.toString());
- }else{
- agrs.put(fieldName, fieldValue.toString());
- }
-
-
-
- // fields.put(fieldName, fieldValue.toString());
- }
- }
-
-
- //业务处理
- uploadManager.saveUpload(upFiles, agrs);
-
- response.sendRedirect(rturl);
- }
-
- private void setField(String file_name, String file_value){
-
- String[] str = file_name.split("\\.");
- UpFile upFile = null;
- if(upFiles.containsKey(str[0])){
- upFile = upFiles.get(str[0]);
- }else{
- upFile = new UpFile();
- }
-
- String fieldName = str[1];
- String value = file_value;
-
- String setMethodName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
-
-
- try {
- Method setMethod = upFile.getClass().getMethod(setMethodName, String.class);
- if (value != null) {
- setMethod.invoke(upFile, value);
- }
- } catch (Exception e) {
- e.printStackTrace();
- log.error(MessageFormat.format("Could not set ''{0}.{1} with value {2}",
- upFile, fieldName, value));
- }
-
- upFiles.put(str[0], upFile);
- }
-
- }
2。对应nginx传递的参数,封装的对象
- package com.XXX.model;
-
- import org.apache.commons.lang.builder.ToStringBuilder;
- import org.apache.commons.lang.builder.ToStringStyle;
- import org.apache.commons.lang.builder.EqualsBuilder;
- import org.apache.commons.lang.builder.HashCodeBuilder;
-
- public class UpFile {
-
- private String name;
-
- private String content_type;
-
- private String path;
-
- private String crc32;
-
- private String size;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getContent_type() {
- return content_type;
- }
-
- public void setContent_type(String content_type) {
- this.content_type = content_type;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public String getCrc32() {
- return crc32;
- }
-
- public void setCrc32(String crc32) {
- this.crc32 = crc32;
- }
-
- public String getSize() {
- return size;
- }
-
- public void setSize(String size) {
- this.size = size;
- }
-
- public String toString() {
- return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
- .append("name", this.name)
- .append("content_type", this.content_type)
- .append("path", this.path)
- .append("crc32", this.crc32)
- .append("size", this.size)
- .toString();
- }
-
- /**
- * @see java.lang.Object#equals(Object)
- */
- public boolean equals(Object object) {
- if (!(object instanceof UpFile)) {
- return false;
- }
- UpFile rhs = (UpFile) object;
- return new EqualsBuilder().appendSuper(super.equals(object)).append(
- this.content_type, rhs.content_type)
- .append(this.size, rhs.size).append(this.path, rhs.path)
- .append(this.crc32, rhs.crc32).append(this.name, rhs.name)
- .isEquals();
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- public int hashCode() {
- return new HashCodeBuilder(-404694209, 2059458549).appendSuper(
- super.hashCode()).append(this.content_type).append(this.size)
- .append(this.path).append(this.crc32).append(this.name)
- .toHashCode();
- }
-
-
- }
3.业务处理uploadManager就按自己的需求写就可以了
|