我有一个要求,我需要编写一个rest API以允许上传文件以及基于Java的客户端来调用带有文件信息的API。
以下是我目前编写的代码 -
@POST
@Path("/uploadFile")
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
String name = file.getOriginalFilename();
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(new File(uploadLocation + name)));
stream.write(bytes);
stream.close();
return "You successfully uploaded " + name + " into " + uploadLocation + name;
} catch (Exception e) {
return "You failed to upload " + name + " => " + e.getMessage();
}
} else {
return "You failed to upload " + name + " because the file was empty.";
}
}
以下是我写的java客户端 -
public class TestFileUpload {
public static void main(String args[]) throws Exception
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://localhost:8080/upload/uploadFile");
httppost.setHeader("content-type", "false");
File file = new File("C:\\dummyUpload.txt");
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(file, "multipart/form-data");
mpEntity.addPart("file", cbFile);
httppost.setEntity(mpEntity);
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
}
}
然而,当我启动服务器时,我可以看到API正在运行,当我运行客户端代码时,我收到400个错误请求。
任何线索,可能是什么问题。
BR,
AJ
答案 0 :(得分:0)
您通常会构建一个类似的文件上传请求(从HttpClient example复制):
var base64Data = data.replace(/^data:image\/png;base64,/, "");
require("fs").writeFile("out.png", base64Data, 'base64', function(err) {
console.log(err);
});
问题是您将/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.examples.entity.mime;
import java.io.File;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* Example how to use multipart/form encoded POST request.
*/
public class ClientMultipartFormPost {
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("File path not given");
System.exit(1);
}
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost("http://localhost:8080" +
"/servlets-examples/servlet/RequestInfoExample");
FileBody bin = new FileBody(new File(args[0]));
StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("bin", bin)
.addPart("comment", comment)
.build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
}
EntityUtils.consume(resEntity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
设置为Content-Type
, 是有效的内容类型。它似乎不应该在使用HttpClient库时设置,并且false
的内容类型必须与您尝试上传的文件的内容类型相匹配 - 在这种情况下,它是&#39 ; sa文本文件,因此ContentBody
是合适的。
您也不能将text/plain
设置为Content-Type
- 您还必须在其上设置multipart/form-data
属性,例如:boundary
,用于分隔文件。
编辑:可以处理它的控制器看起来像:
Content-Type: multipart/form-data; boundary=1234567890ABCDEF
答案 1 :(得分:0)
&#39;内容类型&#39;标题值&#39; false&#39;是无效的。它应该反映您数据的内容类型。
例如,如果您的内容正文是JSON,那么Content-Type标题应设置为&#39; application / json &#39;,XML应设置为&#39; 应用/ XML 强>&#39;等。如果您的内容是纯文本,您只需设置&#39; text / plain &#39;。
您可以阅读可用内容类型here。
答案 2 :(得分:0)
如果已为表单数据添加任何内容,则删除标题ContentType