2017-09-23 96 views
1

我正在编写一个Java应用程序,它将内容发布到wordpress Rest Api。然而,我用Java SpringBoot编程POST一个“.png”文件时遇到了问题,因为我不知道如何将表单数据主体添加到HttpEntity <>(body,headers);如何使用Java邮件将post image.png用Postman形式发布 - 数据

我已经完成了这个使用邮差 - >车身 - >表单数据 - > “文件”: “myFile.png” 见截图: headers in Postman here Body in Postman here

我已经写了这个代码在Java中春:

private MediaResponse uploadMedia (File graphicsFile) { 
    String uploadUrl = baseUrl + mediaUrl; 
    HttpHeaders headers = getHttpHeader(); 

    headers.add(headerKeyAuthorization, User.getInstance().getUsertoken()); 
    headers.add("Content-Disposition", "attachment;filename=image.png"); 
    headers.add("Content-Type", "image/png"); 

    ... 

我想过做这样的事情:

Map<String, File> body = new HashMap<>(); 
parameters.put("file", new File("image.png")); 

HttpEntity requestEntity = new HttpEntity<>(body, headers); 

//not interesting in this case 
//excecuteMediaRequest(uploadUrl, HttpMethod.POST, requestEntity); 

将文件添加到正文。

现在我的问题是:哪个“key”:“value”对我必须在头文件中设置(HttpHeaders),以及如何将文件添加到body中以实现Postman中相同的POST?

我的课程的实际解决方案产生一个错误:

Exception in thread "main" org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [java.util.HashMap] and content type [image/png] 

解决方法:

我已经让它一点点的解决方法和@Ajit苏芒的工作有所帮助。这是适用于我的方案的代码。请注意,方法generateBytArray(),executeMediaRequest()和类MediaResponse是自写的。

/** 
* Uploads media to a rest resource. 
* 
* @param graphicsFile the media file which should be uploaded 
* @return a MediaResponse which has access to resource urls and media information. 
*/ 
private MediaResponse uploadMedia (File graphicsFile) { 
    String uploadUrl = baseUrl + mediaUrl; 
    final String filename = graphicsFile.getName(); 
    //create headers for form data 
    HttpHeaders header = getHttpHeader(); 
    header.set(headerKeyAuthorization, User.getInstance().getUsertoken()); 
    header.set("Content-Disposition", "form-data;"); 

    //produces a byte array resource 
    ByteArrayResource contentAsResource = new ByteArrayResource(generateBytArray(graphicsFile)){ 
     @Override 
     public String getFilename(){ 
      return filename; 
     } 
    }; 

    MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>(); 
    formData.add("file", contentAsResource); 
    //create request entity with header and body 
    HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(formData, header); 
    //executes request with in custom method. 
    MediaResponse respondingObject = executeMediaRequest(uploadUrl, HttpMethod.POST, requestEntity); 
    return respondingObject; 
} 

正如你所看到的,我们没有设置“的Content-Type”选项,但“内容处置”设置为“表单数据”代替“附件“。关键部分是将媒体文件,即.png,转换为字节[]。之后,我们产生一个像this post中提到的ByteArrayResource。至少我们只是将字节数组设置到主体中,并对给定的URL端点执行请求。

这里的方法将文件转换成的byte []

/** 
* generates a byte Array of a file. 
* 
* @param file the file to generate a byte array of. 
* @return byte array of the given file. 
*/ 
private byte[] generateBytArray(File file) { 
    byte[] res = new byte[0]; 
    try { 
     //File file = fileResource.getFile(); 
     BufferedImage image = ImageIO.read(file); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     ImageIO.write(image, "png", baos); 
     res = baos.toByteArray(); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return res; 
} 

而且excecuting方法:

/** 
* Method to execute a Request to a Rest Api where we want to upload media to. 
* 
* @param url the url endpoint of the resource, where we upload the media file. 
* @param method the http request method, which ist POST in this case. 
* @param entity the http entity where header and body are stored. 
* @return a MediaResponse which has access to resource urls and media information. 
*/ 
private MediaResponse executeMediaRequest(String url, HttpMethod method, HttpEntity entity) { 
    ParameterizedTypeReference<MediaResponse> responseType = new ParameterizedTypeReference<MediaResponse>() {}; 
    ResponseEntity<MediaResponse> response = template.exchange(url, method, entity, 
      responseType, MediaResponse.class); 

    MediaResponse responseObject = response.getBody(); 
    logger.info("\n ******** POST MEDIA from response with param: \n " + 
        "Post id: '{}' \n " + 
        "Post REST resource endpoint: '{}' \n" + 
        "Post Permalink '{}'\n *********", 
      responseObject.getMediaID(), responseObject.getRestSelfUrl(), responseObject.getPermalink()); 

    return responseObject; 
} 

感谢@Ajit索曼

+0

你能试着上传您的PNG图片不设置'内容类型:image/png'在邮递员 –

+0

@AjitSoman是啊,这样的作品,太。如果我在你的回答中提到的Java和Spring就像你提到的那样,我得到一个“线程异常”主“org.springframework.web.client.HttpServerErrorException:500内部服务器错误”。如果我编程设置“Content-Type”为“image/png”,我得到一个'无法写入请求:找不到适合请求类型[org.springframework.util.LinkedMultiValueMap]和内容类型[image/png]的HttpMessageConverter'错误。任何想法如何解决这个问题? – HasBert

回答

0

使用LinkedMultiValueMap而不是Map也使用FileSystemResource而不是File。文件上传代码可能是这样的:

LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>(); 
    map.add("file", new FileSystemResource("FILE_LOCATION")); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.set("Content-Type", "image/png"); 
    .. other headers... 
    HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(
         map, headers); 
    RestTemplate template = new RestTemplate(); 
    String result = template.postForObject("FILE_UPLOAD_URL",requestEntity, String.class); 
    System.out.println(result); 
    return result; 
+0

我测试了这个,并得到了一个'在线程中的异常“主要”org.springframework.web.client.RestClientException:无法写请求:找不到合适的HttpMessageConverter为请求类型[org.springframework.util.LinkedMultiValueMap]和内容类型[图像/ png]'例外,如果我将'Content-Type'设置为'application/json'。如果我不添加'headers.set(“Content-Type”,“image/png”);'我有一个'500内部服务器错误'。我已经添加了MessageConverters'FormHttpMessageConverter'' MappingJackson2HttpMessageConverter'甚至达到了500错误。有任何想法吗? – HasBert

+0

删除此行:'headers.set(“Content-Type”,“image/png”);'然后再试一次 –

+0

我做到了,帮助,谢谢。我用解决方案编辑了我的帖子,这对我很有用。 – HasBert

相关问题