2013-09-03 7 views
14

Chcę wysłać plik do serwisu internetowego, ale potrzebuję wysłać więcej informacji, więc chcę je wysłać za pomocą json. Ale kiedy umieszczam plik wewnątrz mojego jsonObject, pojawia się komunikat, że nie jest ciągiem znaków. Moje pytanie brzmi: czy powinienem wziąć mój plik i przekonwertować go na ciąg znaków, a następnie umieścić go w moim jsonie i usłudze sieciowej, a następnie przekonwertować ten ciąg do pliku? Czy istnieje inny prosty sposób?Wyślij plik wewnątrz JSONObject do usługi REST WebService

Oto mój kod:

Klient:

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

Po wszystkich odpowiedzi, tutaj jest mój kod - dzięki wszystkim:

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

Jakiego rodzaju jest 'dados'? –

+0

Przepraszam ... zapomniałem zmienić nazwy, ale dados = moja_data – user2486187

+0

Czy to miało być Base64.getDecoder(). Dekode (file_string) może? –

Odpowiedz

0

Nie wiem, co ma na myśli dados, ewentualnie Map<String, String>, ale myślę, że chcesz być pomocą JSONObject po prostu stworzony

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

Jest to jednak bezużyteczne i może nie działać tak, jak myślisz. Obiekt File nie przechowuje pliku, przechowuje ścieżkę do pliku, tj. C:/hi.txt. Jeśli to właśnie umieścisz w swoim JSON-ie, wygeneruje on

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

Nie będzie zawierać treści pliku.

Więc równie dobrze można po prostu umieścić ścieżkę do pliku bezpośrednio

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

Jeśli próbujesz zrobić upload pliku z JSON, jednym ze sposobów jest do odczytu bajtów z pliku z Java 7 jest NIO

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

Base64 koduje te bajty i zapisuje je jako ciąg w obiekcie JSONObject. Korzystanie z Apache Commons Codec

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

Nie trzeba używać Commons Codec; 'DatatypeConverter' jest częścią standardu (JAXB). –

+0

Dzięki! Użyłem com.sun.jersey.core.util.Base64, który ma Base64.encode (bytes) i Base64.decode (bytes). – user2486187

-1

Trzeba przekonwertować plik do tablicy bajtów, a następnie wysłać go w json.

zobacz: send file to webservice

+0

Myślałem, że to rozwiązanie jest skomplikowane ... Czy to rozwiązanie jest lepsze od innych? Przekształciłem mój plik na bajty, a następnie napisałem Base64 i umieszczałem go w moim jsonie, więc moja usługa internetowa pobiera ten ciąg i dekoduje Base64 na bajty, a następnie tworzę mój plik. – user2486187

+0

Tylko przykład tego, co już odkryłeś, musisz zrobić, aby przekazać swój plik. –

6

należy przekonwertować plik danych do kodowania Base64, a następnie przenieść go na przykładtak:

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

Nie. Wygląda dziwnie, to prawda, ale robi to, co powinien: przekształcić tablicę bajtów w Base64. Użyj 'parseBase64Binary (String)', aby przekonwertować ciąg Base64 na tablicę bajtów. –

+0

Dzięki, dobrze wiedzieć, że potrzebujemy użyć Base64 !! Próbowałem zrobić to bez użycia Base64, ale miałem problemy z plikami pdf. – user2486187

+0

@MoritzPetersen, czy to dobry pomysł? Myślę, że nie jest dobrym pomysłem wysłanie pliku jako łańcucha osadzonego pod adresem 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(); 
} 

i po stronie klienta (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

Jak to konwertuje dowolny JSON? –

+0

W ten sposób można przesłać dane pliku, przeczytać pytanie, wysłać dane, ale wybrać niewłaściwy sposób. –

+0

Dlaczego jest to niewłaściwy sposób? Pomyślałem, że wysłanie wszystkich informacji, które chcę w jsonie, powinno być łatwiejsze ... – user2486187

1

Znam Jego stary słupek, ale po prostu pomyślałem, że dodam trochę uniknąć Zależność od zewnętrznych Biblioteki.

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

Prosimy zmienić adres urządzenia z localhost na adres IP, który chce, aby Twój klient łączył się, aby zadzwonić pod wspomnianą usługę.

**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> 
Powiązane problemy