nginx upload在java中的应用

[b]1.Nginx上传介绍[/b]

文件在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就按自己的需求写就可以了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值