2013-09-03 12 views
14

Desidero inviare un file al servizio web, ma ho bisogno di inviare più informazioni, quindi voglio inviarle con un json. Ma quando metto un file dentro il mio jsonObject ottengo un errore che dice che non è una stringa. La mia domanda è: dovrei prendere il mio file e convertirlo in una stringa, quindi mettere dentro il mio json e sul servizio web prenderlo e convertirlo in un file? O c'è un altro modo semplice?Invia file all'interno di JSONObject a REST WebService

Ecco il mio codice:

Cliente:

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

Dopo tutte le risposte, qui è il mio codice - grazie a tutti:

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

} 
+0

Che tipo è "dados'? –

+0

Mi dispiace ... ho dimenticato di cambiare il nome, ma dados = my_data – user2486187

+0

Era pensato per essere Base64.getDecoder(). Decode (file_string) forse? –

risposta

0

non so cosa dados si riferisce, forse un Map<String, String>, ma penso che si desidera essere con il JSONObject appena creato

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

Tuttavia questo è inutile e potrebbe non fare quello che pensi. Un oggetto File non contiene un file, contiene il percorso del file, ad es. C:/hi.txt. Se questo è ciò che inserisci nel tuo JSON, produrrà

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

Non conterrà il contenuto del file.

così si potrebbe anche semplicemente mettere il percorso del file direttamente

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

Se si sta cercando di fare un upload di file con JSON, un modo è quello di leggere i byte dal file con Java 7 di NIO

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

Base64 codifica quei byte e li scrive come stringa in JSONObject. Utilizzo di Apache Commons Codec

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

Non è necessario utilizzare Commons Codec; 'DatatypeConverter' fa parte dello standard (JAXB). –

+0

Grazie! Ho usato com.sun.jersey.core.util.Base64 che ha Base64.encode (byte) e Base64.decode (byte). – user2486187

-1

È necessario convertire il file in un array di byte e quindi inviarlo all'interno di JSON.

vedere il seguente: send file to webservice

+0

Ho pensato che questa soluzione fosse complicata ... Questa soluzione è migliore delle altre? Ho convertito il mio file in byte e poi lo stringo Base64 e l'ho inserito nel mio json, quindi il mio servizio web prende quella stringa e decodifica Base64 in byte e quindi creo il mio file. – user2486187

+0

Solo un esempio di ciò che hai già scoperto che devi fare per passare il tuo file. –

6

Si dovrebbe convertire i dati del file per la codifica Base64 e poi trasferirlo, per esempioin questo modo:

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

No. Sembra strano, è vero, ma fa quello che dovrebbe: convertire un array di byte in Base64. Utilizzare 'parseBase64Binary (String)' per convertire una stringa Base64 in una matrice di byte. –

+0

Grazie, bello sapere che abbiamo bisogno di usare Base64 !! Ho provato a farlo senza usare Base64, ma ho avuto problemi con i file PDF. – user2486187

+0

@MoritzPetersen, è una buona pratica? Penso che non sia una buona idea inviare un file come stringa incorporata a json – well

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

e del lato client (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(); 
+0

Come si sta convertendo un JSON? –

+0

Questo è il modo di caricare i dati dei file, leggere la domanda, vuole inviare i dati ma scegliere il modo sbagliato per farlo. –

+0

Perché è sbagliato? Ho pensato che inviare tutte le informazioni che voglio all'interno di un json dovrebbe essere più facile ... – user2486187

1

So che la sua un vecchio post, ma ho pensato che vorrei aggiungere un po 'per evitare la dipendenza esterna 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(); 
} 
0

modificare gentilmente l'indirizzo della macchina da localhost a indirizzo iP che si desidera che il tuo client si connetta per chiamare il servizio sotto indicato.

**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>