在开始向您解释我的问题之前,我想与您分享我使用的库版本和服务器:
javax.ws.rs-api: 2.0.1
jersey-container-servlet: 2.13
jersey-media-multipart: 2.13
jackson: 2.4.3
I also use Apache Tomcat Server version 7.0.55.
所以我在下面编码:
/**
* On the client side.
*/
public void uploadAFile() {
Client client = ClientBuilder.newBuilder()
.register(MultiPartFeature.class)
.build();
WebTarget target = null;
try {
target = client
.target("https://blo-bla.rhcloud.com/rest")
.path("v1").path("upload");
} catch (IllegalArgumentException | NullPointerException e) {
LOG_TO_CONSOLE.fatal(e, e);
LOG_TO_FILE.fatal(e, e);
}
Builder builder = target.request(MediaType.TEXT_PLAIN);
builder.header("Authorization",
getValidBasicAuthenticationStrEncrypted());
FormDataMultiPart form = new FormDataMultiPart();
form.field("anotherParam", "Bozo");
String fileName = "/Users/drizzy/Documents/Divx/CaseDepartFolder/sample.avi";
File file = new File(fileName);
form.bodyPart(new FileDataBodyPart("file", file,
MediaType.APPLICATION_OCTET_STREAM_TYPE));
Response response = builder.post(Entity.entity(form,
MediaType.MULTIPART_FORM_DATA_TYPE));
LOG_TO_CONSOLE.debug(response.getStatus());
LOG_TO_CONSOLE.debug(response.readEntity(String.class));
}
/**
* On the server side.
*/
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
public String uploadFile(@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileDisposition,
@FormDataParam("anotherParam") String str)
throws FileNotFoundException, IOException
{
System.out.println("str: " + str);
final String basePath = "/Users/drizzy/eclipse-workspace/tomcat7jbossews"
+ "/src/main/resources/uploads/";
final String fileName = fileDisposition.getFileName();
System.out.println(new StringBuilder().append("***** fileName ")
.append(fileName)
.toString());
final String filePath = new StringBuilder().append(basePath)
.append(fileName)
.toString();
System.out.println(filePath);
try (OutputStream fileOutputStream = new FileOutputStream(filePath)) {
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = fileInputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, read);
}
}
return "File Upload Successfully !!";
}
在客户端产生这些例外:
Java Heap space error
和
Java binding Exception: Already connected
所以我的问题是要知道是否有人可以使用jersey-client V2.13向客户端提供代码示例,该客户端将客户端上的大文件上传到服务器?或者甚至可以告诉我上面的代码有什么问题?
注意:我只想使用jersey-client V2.13来处理这个问题,所以请不要使用第三方库或不使用jersey-client V2.13的解决方案。
答案 0 :(得分:1)
最后我找到了解决问题的方法:
1 - 用于修复"已连接"异常。强>
Java 7引入了默认启用的SNI支持。我发现某些配置错误的服务器会发送一个"无法识别的名称" SSL握手中的警告被大多数客户端忽略...除了Java。正如@Bob Kerns所提到的,Oracle工程师拒绝修复"这个错误/功能。
作为解决方法,他们建议设置jsse.enableSNIExtension属性。要允许您的程序无需重新编译即可运行,请将您的应用程序运行为:
"-Djsse.enableSNIExtension=false"
此信息的来源here。
该属性也可以在Java代码中设置,但必须在任何SSL操作之前设置。加载SSL库后,您可以更改属性,但不会对SNI状态产生任何影响。要在运行时禁用SNI(具有上述限制),请使用:
System.setProperty("jsse.enableSNIExtension", "false");
2 - 用于修复chunkedTransferMode的激活和java堆空间错误。
Java堆空间错误:我不得不增加客户端使用的jvm内存:
为了做到这一点在日食中,转到Run>运行配置...>选择客户端类>参数> VM参数:
-Xms1024m -Xmx2500m -XX:+PrintFlagsFinal
我自己用来修复该问题的来源:source 1,source 2,source 3。
关于启用chunkedTransferMode的事实,我不需要这样做,因为我在jersey-client的文档中发现默认情况下在jersey-client V2.13中启用了chunkedTransferMode。
最后,我们将这些参数传递给客户端的JVM:
"-Djsse.enableSNIExtension=false" "your classes ..." -Xms1024m -Xmx2500m -XX:+PrintFlagsFinal
答案 1 :(得分:0)
好吧,似乎问题是一个非常大的文件(350Mb),你正在达到各种限制。因此,我建议以不同的方式解决问题。
可能的解决方案:
我更喜欢2.解决方案,因为它可能是最容易实现的。 希望这会有所帮助。