【问题标题】:Send file inside JSONObject to REST WebService将 JSONObject 中的文件发送到 REST WebService
【发布时间】:2013-09-07 03:25:31
【问题描述】:

我想向 web 服务发送文件,但我需要发送更多信息,所以我想用 json 发送它们。但是当我在我的 jsonObject 中放入一个文件时,我得到一个错误,说它不是一个字符串。我的问题是,我应该把我的文件转换成一个字符串,然后把它放在我的 json 中,然后在网络服务上把它转换成一个文件吗?还是有其他简单的方法?

这是我的代码:

客户:

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();
}

网络服务

@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";
}

得到所有答案后,这是我的代码 - 谢谢大家:

网络服务

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();
    }
}

客户

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));
    }

}

【问题讨论】:

  • dados是什么类型?
  • 对不起...我忘了重命名,但是 dados = my_data
  • 可能是 Base64.getDecoder().decode(file_string) 吗?

标签: java json web-services rest


【解决方案1】:

您应该将文件数据转换为 Base64 编码,然后将其传输,例如像这样:

byte[] bytes = Files.readAllBytes(file_upload.toPath());
dados.put("File", DatatypeConverter.printBase64Binary(bytes));

【讨论】:

  • 不。看起来很奇怪,没错,但它做了它应该做的:将一个字节数组转换为 Base64。使用parseBase64Binary(String) 将 Base64 字符串转换为字节数组。
  • 谢谢,很高兴知道我们需要使用 Base64!我尝试在不使用 Base64 的情况下制作它,但我遇到了 pdf 文件的问题。
  • @MoritzPetersen,这是一个好的做法吗?我认为将文件作为嵌入在 json 中的字符串发送不是一个好主意
【解决方案2】:
@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();
 }

和客户端(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();

【讨论】:

  • 如何转换任何 JSON?
  • 那是上传文件数据的方式,看问题,他想发送数据但是选择了错误的方式。
  • 为什么是错误的方式?我认为在 json 中发送我想要的所有信息应该更容易......
  • 原因: 1. 发送编码文件的payload多于上行。 2. 它是更多的 REST 方式。 3. REST API 对 javascript 也有效 4. 节省 RAM,而不需要将上传的数据加载到内存中。我已经成功实现了很多次,但我看不出创建一个大的付费 JSON 的原因。
  • 我明白了。感谢您的帮助!我使用它做了一个新的实现......但是我在使用 @FormDataParam ("image") 注释时遇到了一些问题,所以我将参数更改为 FormDataMultiPart 并且它起作用了。
【解决方案3】:

我知道这是一篇旧帖子,但我只是想添加一些内容以避免对外部库的依赖。

//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();
}

【讨论】:

    【解决方案4】:

    我不知道dados 指的是什么,可能是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);
    

    但是,这是无用的,并且可能不会按照您的想法进行。 File 对象不保存文件,它保存文件的路径,即。 C:/hi.txt。如果这就是你放入 JSON 的内容,它会产生

    {"File" : "C:/hi.txt"}
    

    它不会包含文件内容。

    所以你还不如直接放文件路径

    JSONObject my_data = new JSONObject();
    my_data.put("User", "Beth");
    my_data.put("Date", "22-07-2013");
    my_data.put("File", "C:/hi.txt");
    

    如果您尝试使用 JSON 进行文件上传,一种方法是使用 Java 7 的 NIO 从文件中读取字节

    byte[] bytes = Files.readAllBytes(file_upload .toPath());
    

    Base64 对这些字节进行编码,并将它们作为字符串写入 JSONObject。使用 Apache Commons 编解码器

    Base64.encodeBase64(bytes);
    my_data.put("File", new String(bytes));
    

    【讨论】:

    • 无需使用Commons Codec; DatatypeConverter 是标准 (JAXB) 的一部分。
    • 谢谢!我使用了具有 Base64.encode(bytes) 和 Base64.decode(bytes) 的 com.sun.jersey.core.util.Base64。
    【解决方案5】:

    请把机器地址从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>
    

    【讨论】:

      【解决方案6】:

      您需要将文件转换为字节数组,然后在 json 中发送。

      请参阅以下内容:send file to webservice

      【讨论】:

      • 我认为这个解决方案很复杂......这个解决方案比其他解决方案更好吗?我将文件转换为字节,然后转换为字符串 Base64 并将其放入我的 json 中,因此我的 Web 服务获取该字符串并将 Base64 解码为字节,然后创建我的文件。
      • 只是一个示例,说明您已经发现传递文件所需要做的事情。
      猜你喜欢
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      相关资源
      最近更新 更多