nginx upload在java中的施用
nginx upload在java中的应用
1.Nginx上传介绍
文件在POST上传到nginx服务器时,nginx会自己将这个文件先保存下来,然后再往后端发送。
在这个过程中,文件会被保存成一个临时文件,待文件传送完成后,nginx向后端(如resin)通知临时文件的文件信息(如上传文件原有的文件名、存在本地磁盘哪个目录下、临时文件名、文件的md5、文件的类型、文件的大小等)。
后端服务拿到这个文件名可以直接读取缓存的文件,进行迁移转码等后续逻辑。
2.安装
下载nginx upload模块
http://www.grid.net.ru/nginx/upload.en.html
在nginx添加该模块
3.配置nginx.conf
指定上传文件的大小
二、.resin端程序的接收
1.上传的页面index.html
2.添加一个Servlet.修改web.xml
3.编写Servlet,
将file的信息封装到upFiles的map中。
页面的其他信息(如:test),封装到agrs的map中
2。对应nginx传递的参数,封装的对象
3.业务处理uploadManager就按自己的需求写就可以了
1.Nginx上传介绍
文件在POST上传到nginx服务器时,nginx会自己将这个文件先保存下来,然后再往后端发送。
在这个过程中,文件会被保存成一个临时文件,待文件传送完成后,nginx向后端(如resin)通知临时文件的文件信息(如上传文件原有的文件名、存在本地磁盘哪个目录下、临时文件名、文件的md5、文件的类型、文件的大小等)。
后端服务拿到这个文件名可以直接读取缓存的文件,进行迁移转码等后续逻辑。
2.安装
下载nginx upload模块
http://www.grid.net.ru/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就按自己的需求写就可以了
1 楼
zhaoshuli99
2011-01-17
你还搞了个博客,呵呵;
这个upload还行吧,但不能断点续传
这个upload还行吧,但不能断点续传