尝试将文件上传到JAX-RS(泽西岛)服务器

我正在尝试使用带有Jersey的multipart / form-data客户端上传文件和其他表单数据。 我也使用Jersey上传到REST Web服务。 这是服务器代码:

@POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) public String create(@FormDataParam("file") InputStream file, @FormDataParam("file") FormDataContentDisposition fileInfo, @FormDataParam("name") String name, @FormDataParam("description") String description) { Ingredient ingredient = new Ingredient(); ingredient.setName(name); ingredient.setDescription(description); ingredient.setImageName(fileInfo.getFileName()); ingredient.setImagePath(context.getRealPath("/resources/uploads/")); // TODO save the file. try { JSONObject json = new JSONObject(); try { ingredientService.create(ingredient); } catch (final InvalidParameterException ex) { logger.log(Level.INFO, ex.getMessage()); json.put("result", false); json.put("error", ex.getMessage()); return json.toString(); } catch (final GoodDrinksException ex) { logger.log(Level.WARNING, null, ex); json.put("result", false); json.put("error", ex.getMessage()); return json.toString(); } json.put("ingredient", JsonUtil.ingredientToJSON(ingredient)); return json.put("result", true).toString(); } catch (JSONException ex) { logger.log(Level.SEVERE, null, ex); return "{\"result\",false}"; } } 

我已经在桌面上使用基本的html表单测试了服务器代码,它运行正常。 问题似乎在客户端。 这是相关的客户端代码。

 ClientConfig config = new DefaultClientConfig(); client = Client.create(config); client.addFilter(new LoggingFilter()); webResource = client.resource("http://localhost:8080/webapp/resources").path("ingredient"); FormDataMultiPart fdmp = new FormDataMultiPart(); if (file != null) { fdmp.bodyPart(new FileDataBodyPart("file", file, MediaType.APPLICATION_OCTET_STREAM_TYPE)); } fdmp.bodyPart(new FormDataBodyPart("name", ingredient.getName())); fdmp.bodyPart(new FormDataBodyPart("description", ingredient.getDescription())); ClientResponse response = webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE).post(ClientResponse.class, fdmp); String string = response.getEntity(String.class); logger.log(Level.INFO, "response: {0}", string); 

我从服务器得到400响应“客户端发送的请求在语法上是不正确的”

这是从记录器中吐出的消息,这个消息没有文件来保持输出简短:

 1 > POST http://localhost:8080/webapp/resources/ingredient 1 > Content-Type: multipart/form-data 1 > --Boundary_5_1545082086_1303666703655 Content-Type: text/plain Content-Disposition: form-data;name="name" Adam --Boundary_5_1545082086_1303666703655 Content-Type: text/plain Content-Disposition: form-data;name="description" Test --Boundary_5_1545082086_1303666703655-- 

我在客户端做错了什么才能使其正常工作?

如果要将字符串添加到FormDataMultiPart只需使用.field("name", "value")方法,就像它用于文件附件一样(queryParam不起作用)。

以下是工作样本:

首先,服务器部分将读取的文件的内容作为String返回:

 @Path("file") public class FileResource { @POST @Consumes(MediaType.MULTIPART_FORM_DATA) public Response handleUpload(@FormDataParam("file") InputStream stream) throws Exception { return Response.ok(IOUtils.toString(stream)).build(); } } 

二,发布文件的客户端方法:

 public void upload(String url, String fileName) { InputStream stream = getClass().getClassLoader().getResourceAsStream(fileName); FormDataMultiPart part = new FormDataMultiPart().field("file", stream, MediaType.TEXT_PLAIN_TYPE); WebResource resource = Client.create().resource(url); String response = resource.type(MediaType.MULTIPART_FORM_DATA_TYPE).post(String.class, part); assertEquals("Hello, World", response); } 

三,测试环境:

 Server server; @Before public void before() throws Exception { server = new Server(8080); server.addHandler(new WebAppContext(WEB_INF_DIRECTORY, "/")); server.start(); } @After public void after() throws Exception { server.stop(); } @Test public void upload() { upload("http://localhost:8080/file", "file.txt"); } 

最后,maven依赖:

   junit junit 4.8.2 test   com.sun.jersey jersey-server 1.6   com.sun.jersey jersey-client 1.6   com.sun.jersey.contribs jersey-multipart 1.6   org.mortbay.jetty jetty-embedded 6.1.26   commons-io commons-io 2.0.1   

file.txt位于类路径的根目录,包含Hello, World

Yves解决方案在客户端不适合我。 我环顾四周,发现:

不适用于我目前的jersey1.18(见下面的pom提取物)。 最麻烦的是客户端。 我会收到如下错误消息:

 com.sun.jersey.api.client.ClientHandlerException: javax.ws.rs.WebApplicationException: java.lang.IllegalArgumentException: Missing body part entity of type 'text/plain' at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:155) at com.sun.jersey.api.client.Client.handle(Client.java:652) at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682) 

服务器端使用此代码快速工作(它对上传的InputStream没有做任何有趣的事情 – 适合您的需求)

 @POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces("text/plain") public Response uploadFile( @FormDataParam("content") final InputStream uploadedInputStream, @FormDataParam("fileName") String fileName) throws IOException { String uploadContent=IOUtils.toString(uploadedInputStream); return Response.ok(uploadContent).build(); } 

客户端将使用此代码:

 import java.io.File; import java.io.FileInputStream; import java.io.IOException; import javax.ws.rs.core.MediaType; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.multipart.FormDataBodyPart; import com.sun.jersey.multipart.FormDataMultiPart; /** * upload the given file * * inspired by * http://neopatel.blogspot.de/2011/04/jersey-posting-multipart-data.html * * @param url * @param uploadFile * @return the result * @throws IOException */ public String upload(String url, File uploadFile) throws IOException { WebResource resource = Client.create().resource(url); FormDataMultiPart form = new FormDataMultiPart(); form.field("fileName", uploadFile.getName()); FormDataBodyPart fdp = new FormDataBodyPart("content", new FileInputStream(uploadFile), MediaType.APPLICATION_OCTET_STREAM_TYPE); form.bodyPart(fdp); String response = resource.type(MediaType.MULTIPART_FORM_DATA).post(String.class, form); return response; } 

pom.xml提取:

  1.18  
  com.sun.jersey jersey-server ${jersey.version}   com.sun.jersey jersey-client ${jersey.version}    com.sun.jersey.contribs jersey-multipart ${jersey.version}  

 public DssResponse callPut(String url, Map headers, FileDataBodyPart[] filePath, String boundary, String[] jsonString) throws IOException { Client client = ClientBuilder.newClient().register(MultiPartFeature.class); WebTarget webTarget = client.target(url); Builder builder = webTarget.request(MediaType.MULTIPART_FORM_DATA); FormDataMultiPart multiPart = new FormDataMultiPart(); for (int i = 0; i < filePath.length; i++) { if (!filePath[i].getFileEntity().exists()) { throw new IOException("Invalid Input File - " + filePath[i].getFileEntity().getAbsolutePath()); } multiPart.bodyPart(new FileDataBodyPart(filePath[i].getName(), filePath[i].getFileEntity())); } if (boundary != null) multiPart.type(Boundary.addBoundary(new MediaType("multipart", "form-data", Collections.singletonMap(Boundary.BOUNDARY_PARAMETER, boundary)))); for (String jstr : jsonString) { multiPart.field("Content-Type", jstr, MediaType.APPLICATION_JSON_TYPE); } if (headers != null) { for (Entry header : headers.entrySet()) { builder.header(header.getKey(), header.getValue()); System.out.println(header.getKey() + "===============>>" + header.getValue()); } } Response response = builder.accept(MediaType.APPLICATION_JSON).put(Entity.entity(multiPart, multiPart.getMediaType())); multiPart.close(); // Assert.assertNotNull(response); if (response == null ) throw new IOException ("Response is NULL"); int status = response.getStatus(); return dssResponse; } 

或者只是写一个新文件并上传它:

 Writer output = null; File file = null; try { String text = "Rajesh Kumar"; file = new File("write.txt"); output = new BufferedWriter(new FileWriter(file)); output.write(text); output.close(); } catch (IOException e) { System.out.println("IOException e"); e.printStackTrace(); } InputStream is = null; try { is = new FileInputStream(file); } catch (FileNotFoundException e) { System.out.println("FileNotFoundException e"); e.printStackTrace(); } catch (IOException e) { System.out.println("IOException e"); e.printStackTrace(); } FormDataMultiPart part = new FormDataMultiPart().field("file", is, MediaType.TEXT_PLAIN_TYPE); res = service.path("rest").path("tenant").path(tenant1.getTenantId()).path("file").type(MediaType.MULTIPART_FORM_DATA_TYPE).post(ClientResponse.class, part);