Java 将 JSONObject 中的文件发送到 REST WebService
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18599985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Send file inside JSONObject to REST WebService
提问by user2486187
I want to send a file to webservice, but i need send more informations, so i want to send them with a json. But when i put a file inside my jsonObject i get an error saying that it isn't a string. My question is, should i take my File and convert to a string, then put inside my json and on web service take it and convert that string to a file? Or is there another simple way?
我想向 webservice 发送文件,但我需要发送更多信息,所以我想用 json 发送它们。但是当我将一个文件放入我的 jsonObject 时,我收到一个错误,说它不是一个字符串。我的问题是,我应该将我的文件转换为字符串,然后放入我的 json 并在 Web 服务中获取它并将该字符串转换为文件吗?或者还有其他简单的方法吗?
Here is my code:
这是我的代码:
Client:
客户:
private void send() throws JSONException{
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
client.addFilter(new LoggingFilter());
WebResource service = client.resource("http://localhost:8080/proj/rest/file/upload_json");
JSONObject my_data = new JSONObject();
File file_upload = new File("C:/hi.txt");
my_data.put("User", "Beth");
my_data.put("Date", "22-07-2013");
my_data.put("File", file_upload);
ClientResponse client_response = service.accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, my_data);
System.out.println("Status: "+client_response.getStatus());
client.destroy();
}
WebService
网络服务
@POST
@Path("/upload_json")
@Consumes(MediaType.APPLICATION_JSON)
@Produces("text/plain")
public String receive(JSONObject json) throws JSONException {
//Here I'll save my file and make antoher things..
return "ok";
}
After all the answers, here is my code - thanks everyone:
在所有答案之后,这是我的代码 - 谢谢大家:
WebService
网络服务
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import com.sun.jersey.core.util.Base64;
@Path("/file")
public class ReceiveJSONWebService {
@POST
@Path("/upload_json")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public JSONObject receiveJSON(JSONObject json) throws JSONException, IOException {
convertFile(json.getString("file"), json.getString("file_name"));
//Prints my json object
return json;
}
//Convert a Base64 string and create a file
private void convertFile(String file_string, String file_name) throws IOException{
byte[] bytes = Base64.decode(file_string);
File file = new File("local_path/"+file_name);
FileOutputStream fop = new FileOutputStream(file);
fop.write(bytes);
fop.flush();
fop.close();
}
}
Client
客户
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import javax.ws.rs.core.MediaType;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.LoggingFilter;
import com.sun.jersey.core.util.Base64;
import com.sun.jersey.multipart.FormDataMultiPart;
import com.sun.jersey.multipart.file.FileDataBodyPart;
import com.sun.jersey.multipart.impl.MultiPartWriter;
public class MyClient {
public static void main(String[] args) throws JSONException, IOException
{
MyClient my_client = new MyClient();
File file_upload = new File("local_file/file_name.pdf");
my_client.sendFileJSON(file_upload);
}
private void sendFileJSON(File file_upload) throws JSONException, IOException{
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
client.addFilter(new LoggingFilter());
WebResource service = client.resource("my_rest_address_path");
JSONObject data_file = new JSONObject();
data_file.put("file_name", file_upload.getName());
data_file.put("description", "Something about my file....");
data_file.put("file", convertFileToString(file_upload));
ClientResponse client_response = service.accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, data_file);
System.out.println("Status: "+client_response.getStatus());
client.destroy();
}
//Convert my file to a Base64 String
private String convertFileToString(File file) throws IOException{
byte[] bytes = Files.readAllBytes(file.toPath());
return new String(Base64.encode(bytes));
}
}
回答by Sotirios Delimanolis
I don't know what dados
is referring to, possibly a Map<String, String>
, but I think you want to be using the JSONObject
you just created
我不知道dados
指的是什么,可能是 a Map<String, String>
,但我认为您想使用JSONObject
刚刚创建的
JSONObject my_data = new JSONObject();
File file_upload = new File("C:/hi.txt");
my_data.put("User", "Beth");
my_data.put("Date", "22-07-2013");
my_data.put("File", file_upload);
However this is useless and might not be doing what you think. A File
object doesn't hold a file, it holds the path to the file, ie. C:/hi.txt
. If that's what you put in your JSON, it'll produce
但是,这是无用的,并且可能不会按照您的想法行事。一个File
对象不保存文件时,它保存文件路径,即。C:/hi.txt
. 如果这就是您放入 JSON 中的内容,它将产生
{"File" : "C:/hi.txt"}
It won't contain the file content.
它不会包含文件内容。
So you might as well just put the file path directly
所以你不妨直接把文件路径
JSONObject my_data = new JSONObject();
my_data.put("User", "Beth");
my_data.put("Date", "22-07-2013");
my_data.put("File", "C:/hi.txt");
If you're trying to do a file upload with JSON, one way is to read the bytes from the file with Java 7's NIO
如果您尝试使用 JSON 进行文件上传,一种方法是使用 Java 7 的 NIO 从文件中读取字节
byte[] bytes = Files.readAllBytes(file_upload .toPath());
Base64 encode those bytes and write them as a String in the JSONObject. Using Apache Commons Codec
Base64 对这些字节进行编码,并将它们作为字符串写入 JSONObject。使用 Apache Commons 编解码器
Base64.encodeBase64(bytes);
my_data.put("File", new String(bytes));
回答by Dan Rowe
You need to convert your file to a byte array and then send it within the json.
您需要将文件转换为字节数组,然后在 json 中发送它。
see the following:send file to webservice
请参阅以下内容:将文件发送到网络服务
回答by Moritz Petersen
You should convert the file data to Base64 encoding and then transfer it, e.g. like this:
您应该将文件数据转换为 Base64 编码,然后传输它,例如:
byte[] bytes = Files.readAllBytes(file_upload.toPath());
dados.put("File", DatatypeConverter.printBase64Binary(bytes));
回答by moshe beeri
@POST
@Path("/uploadWeb")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadWeb( @FormDataMultiPart("image") InputStream uploadedInputStream,
@FormDataParam("image") FormDataContentDisposition fileDetail ) {
int read = 0;
byte[] bytes = new byte[1024];
while ((read = uploadedInputStream.read(bytes)) != -1)
System.out.write(bytes, 0, read);
return Response.status(HttpStatus.SC_OK).entity(c).build();
}
and of the client side (see this post):
和客户端(见这篇文章):
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
FileBody fileContent= new FileBody(new File(fileName));
StringBody comment = new StringBody("Filename: " + fileName);
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("file", fileContent);
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
回答by Palmeta
I know its an old post but I just thought I'd add a little to avoid the dependancy on external librarys.
我知道它是一个旧帖子,但我只是想我会添加一点以避免对外部库的依赖。
//Convert my file to a Base64 String
public static final String convertFileToString(File file) throws IOException{
byte[] bytes = Files.readAllBytes(file.toPath());
return new String(Base64.getEncoder().encode(bytes));
}
//Convert a Base64 string and create a file
public static final void convertFile(String file_string, String file_name) throws IOException{
byte[] bytes = Base64.getDecoder().decode(file_string);
File file = new File("local_path/"+file_name);
FileOutputStream fop = new FileOutputStream(file);
fop.write(bytes);
fop.flush();
fop.close();
}
回答by Shankar Saran Singh
Kindly change the machine address from localhost to ip address you want your client to connect with to call below mentioned service.
请将机器地址从 localhost 更改为您希望客户端连接以调用下面提到的服务的 IP 地址。
**CLIENT TO CALL REST WEBSERVICE**
package in.india.client.downloadfiledemo;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.multipart.BodyPart;
import com.sun.jersey.multipart.MultiPart;
public class DownloadFileClient {
private static final String BASE_URI = "http://localhost:8080/DownloadFileDemo/services/downloadfile";
public DownloadFileClient() {
try {
Client client = Client.create();
WebResource objWebResource = client.resource(BASE_URI);
ClientResponse response = objWebResource.path("/")
.type(MediaType.TEXT_HTML).get(ClientResponse.class);
System.out.println("response : " + response);
if (response.getStatus() == Status.OK.getStatusCode()
&& response.hasEntity()) {
MultiPart objMultiPart = response.getEntity(MultiPart.class);
java.util.List<BodyPart> listBodyPart = objMultiPart
.getBodyParts();
BodyPart filenameBodyPart = listBodyPart.get(0);
BodyPart fileLengthBodyPart = listBodyPart.get(1);
BodyPart fileBodyPart = listBodyPart.get(2);
String filename = filenameBodyPart.getEntityAs(String.class);
String fileLength = fileLengthBodyPart
.getEntityAs(String.class);
File streamedFile = fileBodyPart.getEntityAs(File.class);
BufferedInputStream objBufferedInputStream = new BufferedInputStream(
new FileInputStream(streamedFile));
byte[] bytes = new byte[objBufferedInputStream.available()];
objBufferedInputStream.read(bytes);
String outFileName = "D:/"
+ filename;
System.out.println("File name is : " + filename
+ " and length is : " + fileLength);
FileOutputStream objFileOutputStream = new FileOutputStream(
outFileName);
objFileOutputStream.write(bytes);
objFileOutputStream.close();
objBufferedInputStream.close();
File receivedFile = new File(outFileName);
System.out.print("Is the file size is same? :\t");
System.out.println(Long.parseLong(fileLength) == receivedFile
.length());
}
} catch (UniformInterfaceException e) {
e.printStackTrace();
} catch (ClientHandlerException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String... args) {
new DownloadFileClient();
}
}
**SERVICE TO RESPONSE CLIENT**
package in.india.service.downloadfiledemo;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.sun.jersey.multipart.MultiPart;
@Path("downloadfile")
@Produces("multipart/mixed")
public class DownloadFileResource {
@GET
public Response getFile() {
java.io.File objFile = new java.io.File(
"D:/DanGilbert_2004-480p-en.mp4");
MultiPart objMultiPart = new MultiPart();
objMultiPart.type(new MediaType("multipart", "mixed"));
objMultiPart
.bodyPart(objFile.getName(), new MediaType("text", "plain"));
objMultiPart.bodyPart("" + objFile.length(), new MediaType("text",
"plain"));
objMultiPart.bodyPart(objFile, new MediaType("multipart", "mixed"));
return Response.ok(objMultiPart).build();
}
}
**JAR NEEDED**
jersey-bundle-1.14.jar
jersey-multipart-1.14.jar
mimepull.jar
**WEB.XML**
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>DownloadFileDemo</display-name>
<servlet>
<display-name>JAX-RS REST Servlet</display-name>
<servlet-name>JAX-RS REST Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>in.india.service.downloadfiledemo</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS REST Servlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>