如何使用 Spring 以编程方式使用来自 Rest API 的文件? [英] How to programmatically consume a file from a Rest API using Spring?

查看:35
本文介绍了如何使用 Spring 以编程方式使用来自 Rest API 的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下从数据库下载文件的 Rest 资源.它在浏览器中运行良好,但是,当我尝试从 Java 客户端执行此操作时,如下所示,我收到 406(未接受的错误).

I have the following Rest resource which downloads a file from DB. It works fine from the browser, however, when I try to do it from a Java client as below, I get 406 (Not accepted error).

...
 @RequestMapping(value="/download/{name}", method=RequestMethod.GET, 
        produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public @ResponseBody HttpEntity<byte[]> downloadActivityJar(@PathVariable String name) throws IOException
{
    logger.info("downloading : " + name + " ... ");
    byte[] file = IOUtils.toByteArray(artifactRepository.downloadJar(name));
    HttpHeaders header = new HttpHeaders();
    header.set("Content-Disposition", "attachment; filename="+ name + ".jar");
    header.setContentLength(file.length);

    return new HttpEntity<byte[]>(file, header);
}
...

客户端部署在不同端口的同一服务器上(消息给出了正确的名称):

The client is deployed on the same server with different port (message gives the correct name) :

    ...
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://localhost:8080/activities/download/" + message.getActivity().getName();
    File jar = restTemplate.getForObject(url, File.class);
    logger.info("File size: " + jar.length() + " Name: " + jar.getName());
    ...

我在这里遗漏了什么?

推荐答案

响应代码是 406 Not Accepted.您需要指定一个Accept"请求标头,该标头必须与 RequestMapping 的produces"字段匹配.

The response code is 406 Not Accepted. You need to specify an 'Accept' request header which must match the 'produces' field of your RequestMapping.

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter());    
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
HttpEntity<String> entity = new HttpEntity<String>(headers);

ResponseEntity<byte[]> response = restTemplate.exchange(URI, HttpMethod.GET, entity, byte[].class, "1");

if(response.getStatusCode().equals(HttpStatus.OK))
        {       
                FileOutputStream output = new FileOutputStream(new File("filename.jar"));
                IOUtils.write(response.getBody(), output);

        }

一个小警告:不要对大文件这样做.RestTemplate.exchange(...) 总是将整个响应加载到内存中,因此您可能会遇到 OutOfMemory 异常.为了避免这种情况,不要使用 Spring RestTemplate,而是直接使用 Java 标准 HttpUrlConnection 或 apache http-components.

A small warning: don't do this for large files. RestTemplate.exchange(...) always loads the entire response into memory, so you could get OutOfMemory exceptions. To avoid this, do not use Spring RestTemplate, but rather use the Java standard HttpUrlConnection directly or apache http-components.

这篇关于如何使用 Spring 以编程方式使用来自 Rest API 的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆