从Java客户端到Grails web应用程序的可恢复上传?
在谷歌搜索了将近两个工作日,并尝试了我在网上发现的几种不同的可能性之后,我在这里提出了这个问题,希望我能最终得到答案 首先,我想做的是: 我正在开发一个客户机和一个服务器应用程序,目的是在一台服务器上的多个客户机之间交换大量大型文件。客户端是在纯Java(JDK1.6)中开发的,而web应用程序是在Grails(2.0.0)中开发的 由于客户端的目的是允许用户交换大量的大文件(通常每个文件大约2GB),因此我必须以某种方式实现它,以便上传是可恢复的,即用户可以随时停止和恢复上传 以下是我迄今为止所做的: 实际上,我做到了我想做的事情,将大文件流式传输到服务器,同时仍然能够使用原始套接字暂停和恢复上传。我会向服务器发送一个常规请求(使用Apache的HttpClient库),让服务器向我发送一个免费使用的端口,然后在服务器上打开一个ServerSocket并从客户端连接到该特定的套接字 这就是问题所在: 事实上,这至少有两个问题:从Java客户端到Grails web应用程序的可恢复上传?,java,grails,upload,inputstream,resume-upload,Java,Grails,Upload,Inputstream,Resume Upload,在谷歌搜索了将近两个工作日,并尝试了我在网上发现的几种不同的可能性之后,我在这里提出了这个问题,希望我能最终得到答案 首先,我想做的是: 我正在开发一个客户机和一个服务器应用程序,目的是在一台服务器上的多个客户机之间交换大量大型文件。客户端是在纯Java(JDK1.6)中开发的,而web应用程序是在Grails(2.0.0)中开发的 由于客户端的目的是允许用户交换大量的大文件(通常每个文件大约2GB),因此我必须以某种方式实现它,以便上传是可恢复的,即用户可以随时停止和恢复上传 以下是我迄今为止
request.inputStream
总是产生一个空的inputStream,因此我永远无法从中读取任何内容(当然)。但这正是我想要做的(这样我就可以将要上传到服务器的文件流化,从InputStream读取并保存到一个文件),这是相当令人失望的
我尝试了不同的HTTP方法,不同的数据有效负载,并且一遍又一遍地重新排列代码,但似乎无法解决问题
我希望找到什么
当然,我希望找到解决我问题的办法。任何东西都值得高度赞赏:提示、代码片段、库建议等等。也许我甚至都搞错了,需要走完全不同的方向
那么,我如何实现从Java客户机到Grails web应用程序的相当大(二进制)文件的可恢复文件上载,而不必手动打开服务器端的端口呢?HTTP GET方法具有用于范围检索的特殊头文件:大多数下载程序都使用它从服务器进行可恢复下载 据我所知,在POST/PUT请求中使用此标题没有标准实践,但这取决于您,对吗?您可以制作非常标准的Grails控制器,它将接受标准的http上传,标题类似于
范围:bytes=500-999
。控制器应该把500个上传的字节从客户端放到文件中,从位置500开始
在这种情况下,您不需要打开任何套接字,也不需要制定自己的协议等
p.S.500字节只是一个例子,可能您使用的是更大的部件。客户端Java编程:
public class NonFormFileUploader {
static final String UPLOAD_URL= "http://localhost:8080/v2/mobileApp/fileUploadForEOL";
static final int BUFFER_SIZE = 4096;
public static void main(String[] args) throws IOException {
// takes file path from first program's argument
String filePath = "G:/study/GettingStartedwithGrailsFinalInfoQ.pdf";
File uploadFile = new File(filePath);
System.out.println("File to upload: " + filePath);
// creates a HTTP connection
URL url = new URL(UPLOAD_URL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
// sets file name as a HTTP header
httpConn.setRequestProperty("fileName", uploadFile.getName());
// opens output stream of the HTTP connection for writing data
OutputStream outputStream = httpConn.getOutputStream();
// Opens input stream of the file for reading data
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
System.out.println("bytesRead:"+bytesRead);
outputStream.write(buffer, 0, bytesRead);
outputStream.flush();
}
System.out.println("Data was written.");
outputStream.flush();
outputStream.close();
inputStream.close();
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// reads server's response
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String response = reader.readLine();
System.out.println("Server's response: " + response);
} else {
System.out.println("Server returned non-OK code: " + responseCode);
}
}
}
服务器端Grails程序:
public class NonFormFileUploader {
static final String UPLOAD_URL= "http://localhost:8080/v2/mobileApp/fileUploadForEOL";
static final int BUFFER_SIZE = 4096;
public static void main(String[] args) throws IOException {
// takes file path from first program's argument
String filePath = "G:/study/GettingStartedwithGrailsFinalInfoQ.pdf";
File uploadFile = new File(filePath);
System.out.println("File to upload: " + filePath);
// creates a HTTP connection
URL url = new URL(UPLOAD_URL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
// sets file name as a HTTP header
httpConn.setRequestProperty("fileName", uploadFile.getName());
// opens output stream of the HTTP connection for writing data
OutputStream outputStream = httpConn.getOutputStream();
// Opens input stream of the file for reading data
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
System.out.println("bytesRead:"+bytesRead);
outputStream.write(buffer, 0, bytesRead);
outputStream.flush();
}
System.out.println("Data was written.");
outputStream.flush();
outputStream.close();
inputStream.close();
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// reads server's response
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String response = reader.readLine();
System.out.println("Server's response: " + response);
} else {
System.out.println("Server returned non-OK code: " + responseCode);
}
}
}
控制器内部:
在服务类内部:
def fileUploadForEOL(请求){
def状态=假;
整数代码=500
def map=[:]
试一试{
字符串文件名=request.getHeader(“文件名”);
文件保存文件=新文件(保存目录+文件名);
System.out.println(“==beginheaders===”);
枚举名称=request.getHeaderNames();
while(names.hasMoreElements()){
字符串headerName=names.nextElement();
System.out.println(headerName+“=”+request.getHeader(headerName));
}
System.out.println(“=======结束头========\n”);
//打开读取数据请求的输入流
InputStream InputStream=request.getInputStream();
//打开输出流以写入文件
FileOutputStream outputStream=新的FileOutputStream(保存文件);
字节[]缓冲区=新字节[缓冲区大小];
int bytesRead=inputStream.read(缓冲区);
长计数=字节读取
while(字节读取!=-1){
写入(缓冲区,0,字节读取);
bytesRead=inputStream.read(缓冲区);
计数+=字节读取
}
println“计数:”+计数
System.out.println(“数据接收”);
outputStream.close();
inputStream.close();
System.out.println(“文件写入:”+saveFile.getAbsolutePath());
代码=200
}捕获(例外e){
log(java.util.logging.Level.SEVERE,“fileUploadForEOL中的异常”,e);
}最后{
地图
public class NonFormFileUploader {
static final String UPLOAD_URL= "http://localhost:8080/v2/mobileApp/fileUploadForEOL";
static final int BUFFER_SIZE = 4096;
public static void main(String[] args) throws IOException {
// takes file path from first program's argument
String filePath = "G:/study/GettingStartedwithGrailsFinalInfoQ.pdf";
File uploadFile = new File(filePath);
System.out.println("File to upload: " + filePath);
// creates a HTTP connection
URL url = new URL(UPLOAD_URL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
// sets file name as a HTTP header
httpConn.setRequestProperty("fileName", uploadFile.getName());
// opens output stream of the HTTP connection for writing data
OutputStream outputStream = httpConn.getOutputStream();
// Opens input stream of the file for reading data
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
System.out.println("bytesRead:"+bytesRead);
outputStream.write(buffer, 0, bytesRead);
outputStream.flush();
}
System.out.println("Data was written.");
outputStream.flush();
outputStream.close();
inputStream.close();
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// reads server's response
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String response = reader.readLine();
System.out.println("Server's response: " + response);
} else {
System.out.println("Server returned non-OK code: " + responseCode);
}
}
}
def fileUploadForEOL(){
def result
try{
result = mobileAppService.fileUploadForEOL(request);
}catch(Exception e){
log.error "Exception in fileUploadForEOL service",e
}
render result as JSON
}
def fileUploadForEOL(request){
def status = false;
int code = 500
def map = [:]
try{
String fileName = request.getHeader("fileName");
File saveFile = new File(SAVE_DIR + fileName);
System.out.println("===== Begin headers =====");
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
String headerName = names.nextElement();
System.out.println(headerName + " = " + request.getHeader(headerName));
}
System.out.println("===== End headers =====\n");
// opens input stream of the request for reading data
InputStream inputStream = request.getInputStream();
// opens an output stream for writing file
FileOutputStream outputStream = new FileOutputStream(saveFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = inputStream.read(buffer);
long count = bytesRead
while(bytesRead != -1) {
outputStream.write(buffer, 0, bytesRead);
bytesRead = inputStream.read(buffer);
count += bytesRead
}
println "count:"+count
System.out.println("Data received.");
outputStream.close();
inputStream.close();
System.out.println("File written to: " + saveFile.getAbsolutePath());
code = 200
}catch(Exception e){
mLogger.log(java.util.logging.Level.SEVERE,"Exception in fileUploadForEOL",e);
}finally{
map <<["code":code]
}
return map
}