2013-09-03 3 views
14

Я хочу отправить файл в webservice, но мне нужно отправить больше информации, поэтому я хочу отправить их с помощью json. Но когда я помещаю файл внутри jsonObject, я получаю сообщение об ошибке, говоря, что это не строка. Мой вопрос в том, должен ли я взять файл и преобразовать его в строку, а затем положить в свой json и на веб-службу взять его и преобразовать эту строку в файл? Или есть еще один простой способ?Отправить файл внутри JSONObject для REST WebService

Вот мой код:

Клиент:

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

После ответов на все вопросы, вот мой код - спасибо всем:

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

Клиент

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

Какой тип 'dados'? –

+0

Прошу прощения ... я забыл переименовать, но dados = my_data – user2486187

+0

Возможно, это был Base64.getDecoder(). Decode (file_string)? –

ответ

0

Я не знаю, что 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 Codec

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

Не нужно использовать Commons Codec; 'DatatypeConverter' является частью стандарта (JAXB). –

+0

Спасибо! Я использовал com.sun.jersey.core.util.Base64, у которого есть Base64.encode (байты) и Base64.decode (байты). – user2486187

-1

Вам необходимо преобразовать файл в массив байтов, а затем отправить его в формате JSON.

увидеть следующее: send file to webservice

+0

Я думал, что это решение сложное ... Является ли это решение лучше, чем другие? Я преобразовал свой файл в байты, а затем в строку Base64 и поместил его в свой json, поэтому мой веб-сервис принимает эту строку и декодирует Base64 в байты, а затем создаю свой файл. – user2486187

+0

Просто пример того, что вы уже обнаружили, вам нужно сделать, чтобы передать файл. –

6

Вы должны преобразовать данные файла в кодировке Base64, а затем передать его, например,как это:

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

Нет. Выглядит странно, это правильно, но он делает то, что должен: преобразовать массив байтов в Base64. Используйте 'parseBase64Binary (String)' для преобразования строки Base64 в массив байтов. –

+0

Спасибо, приятно знать, что нам нужно использовать Base64 !! Я попытался сделать это без использования Base64, но у меня были проблемы с файлами PDF. – user2486187

+0

@MoritzPetersen, это хорошая оценка? Я думаю, что неплохо отправить файл как строку, встроенную в 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(); 
} 

и на стороне клиента (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

Как это преобразование любого JSON? –

+0

Это способ загрузить данные файла, прочитать вопрос, он хочет отправить данные, но выбрать неправильный способ сделать это. –

+0

Почему это не так? Я думал, что отправить всю информацию, которую я хочу внутри json, должно быть проще ... – user2486187

1

Я знаю его старый пост, но я просто думал, что я хотел бы добавить немного, чтобы избежать на внешних Зависимость от 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

Пожалуйста, измените адрес машины с локального хоста к вам 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> 
Смежные вопросы