`
奔跑的羚羊
  • 浏览: 570633 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

nginx upload在java中的应用

    博客分类:
  • java
阅读更多
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就按自己的需求写就可以了


0
0
分享到:
评论
2 楼 yhq1212 2015-08-16  
如何禁止NGINX先本地缓存呢
1 楼 zhaoshuli99 2011-01-17  
你还搞了个博客,呵呵;
这个upload还行吧,但不能断点续传

相关推荐

Global site tag (gtag.js) - Google Analytics