Read a resource from URL and return directly those bytes as response of REST request, with no memory storing with Java 7 and spring MVC 3.2

huangapple go评论125阅读模式
英文:

Read a resource from URL and return directly those bytes as response of REST request, with no memory storing with Java 7 and spring MVC 3.2

问题

我有一个REST端点,需要访问以检索资源(图像、文档...)。

  1. @RequestMapping(value = "/attachement", method = RequestMethod.GET)
  2. @ResponseBody
  3. public Object getTrademarkAttachement(HttpServletResponse response, HttpServletRequest request) {
  4. //TODO : 从微服务URL检索字节
  5. //TODO : 将字节发送到前端页面
  6. }

为了检索此文档,我希望通过流式传输来实现。我不想在内存中存储信息。我希望在获取信息的同时,将字节作为响应发送。我的Spring MVC版本是Spring MVC 3.2,我的Java版本是Java 7。能否实现这一点?你能给一些开始调查的线索吗?我知道我在提供有关实现的细节很少,但我从这一点开始,希望能从你那里得到一些想法。

编辑1:

我已经解决了问题的一半。检索URL的不同块。我使用了以下代码:

  1. @Override
  2. public byte[] getTrademarkAttachement() {
  3. String urlSample = "http://testUrl.com";
  4. HttpURLConnection httpConn = null;
  5. String line = null;
  6. try {
  7. httpConn = (HttpURLConnection) new URL(urlSample).openConnection();
  8. InputStream ins = httpConn.getInputStream();
  9. BufferedReader is = new BufferedReader(new InputStreamReader(ins));
  10. while ((line = is.readLine()) != null) {
  11. System.out.println(line);
  12. }
  13. } catch (MalformedURLException e) {
  14. e.printStackTrace();
  15. } catch (IOException e) {
  16. e.printStackTrace();
  17. } finally {
  18. httpConn.disconnect();
  19. }
  20. return null;
  21. }

能够访问输入流后,剩下的部分是返回我正在读取的每一行,以便我可以流式传输响应。我必须寻找Spring MVC中提供部分响应的方法。

英文:

I have a REST endpoint that has to be accessed to retrieve a resource (image, document, ...).

  1. @RequestMapping(value = "/attachement", method = RequestMethod.GET)
  2. @ResponseBody
  3. public Object getTrademarkAttachement(HttpServletResponse response, HttpServletRequest request) {
  4. //TODO : Retrieve bytes from microservice url
  5. //TODO : Send bytes to frontend page
  6. }

For retrieving this document, I want to do it via streaming . I don't want to store in memory the info . I want to , as I get the info, send the bytes as a response . My version of spring MVC is Spring MVC 3.2 and my version of java is java 7 . Is it possible to achieve this ? could you give any clue to start investigating ? . I know I'm giving little details about implementation but I'm starting with this point and I would want to get some ideas from you .

EDIT 1 :

I have achieved half of the problem . Retrieving different blocks of the url . I have used the following code

  1. @Override
  2. public byte[] getTrademarkAttachement() {
  3. String urlSample = "http://testUrl.com";
  4. HttpURLConnection httpConn = null;
  5. String line = null;
  6. try {
  7. httpConn = (HttpURLConnection) new URL(urlSample).openConnection();
  8. InputStream ins = httpConn.getInputStream();
  9. BufferedReader is = new BufferedReader(new InputStreamReader(ins));
  10. while ((line = is.readLine()) != null) {
  11. System.out.println(line);
  12. }
  13. } catch (MalformedURLException e) {
  14. e.printStackTrace();
  15. } catch (IOException e) {
  16. e.printStackTrace();
  17. } finally {
  18. httpConn.disconnect();
  19. }
  20. return null;
  21. }

Being able to have access to the inputstream , the part that is left is returning each of this lines that I'm reading , so I can stream the response . I have to look for a method in spring MVC that gives a partial response .

答案1

得分: 1

因为您可以获得InputStream,所以您应该能够将OutputStream作为对请求的响应返回。请查看这个链接(https://stackoverflow.com/a/27742486/):

  1. @RequestMapping(value = "/attachement", method = RequestMethod.GET)
  2. @ResponseBody
  3. public void getAttachment(OutputStream out) {
  4. InputStream in = ; // 从HTTP获取的InputStream,根据您提供的示例设置这个
  5. byte[] buffer = new byte[1024]; // 您将需要一个小的缓冲区
  6. int len;
  7. while ((len = in.read(buffer)) != -1) {
  8. out.write(buffer, 0, len);
  9. }
  10. in.close();
  11. out.flush();
  12. }
英文:

Since you can get the InputStream, you should be able to return an OutputStream as a response to the request. Take a look at this (https://stackoverflow.com/a/27742486/):

  1. @RequestMapping(value = "/attachement", method = RequestMethod.GET)
  2. @ResponseBody
  3. public void getAttachment(OutputStream out) {
  4. InputStream in = ; // Set this to the InputStream from HTTP as your provided example
  5. byte[] buffer = new byte[1024]; // You will need a small buffer mem though
  6. int len;
  7. while ((len = in.read(buffer)) != -1) {
  8. out.write(buffer, 0, len);
  9. }
  10. in.close();
  11. out.flush();
  12. }

答案2

得分: 0

好的,这是翻译后的内容:

好的,我已经解决了我的问题。我附上了解决方案。也许对任何人都有用。

Controller

  1. @RequestMapping(value="/eutm/{trademarkId}/snapshots/{historyId}/attachements/{attachementId}", method = RequestMethod.GET)
  2. @ResponseBody
  3. public void getTrademarkAttachement(HttpServletResponse response, @PathVariable String trademarkId, @PathVariable String historyId, @PathVariable String attachementId) {
  4. try {
  5. registerService.getTrademarkAttachement(trademarkId, historyId, attachementId, LanguageController.getLocale(), response.getOutputStream());
  6. } catch (IOException e) {
  7. e.printStackTrace();
  8. }
  9. }

Service

  1. @Override
  2. public void getTrademarkAttachement(String trademarkId, String historyId, String attachementId, Locale locale, ServletOutputStream outputStream) {
  3. URI uri = loadHistoryUri(generateUri(REGISTER_BASE_MS_URL, REGISTER_HISTORY_ENTRY_TM_ATTACHEMENT_WS_URL, trademarkId, historyId, attachementId), locale.getLanguage());
  4. HttpURLConnection httpConn = null;
  5. String line = null;
  6. InputStream ins = null;
  7. try {
  8. httpConn = (HttpURLConnection) new URL(uri.toString()).openConnection();
  9. ins = httpConn.getInputStream();
  10. BufferedReader is = new BufferedReader(new InputStreamReader(ins));
  11. while ((line = is.readLine()) != null) {
  12. outputStream.write(line.getBytes());
  13. }
  14. outputStream.flush();
  15. } catch (MalformedURLException e) {
  16. e.printStackTrace();
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. } finally {
  20. httpConn.disconnect();
  21. if(ins != null){
  22. try {
  23. ins.close();
  24. } catch (IOException e) {
  25. logger.error("关闭 inputStream ins 时出现问题");
  26. }
  27. }
  28. }
  29. }

这样,在从输入流(通过GET连接检索的URL)中读取行时,它会直接通过输出流将其写入响应。它不会像响应式模式中一样逐位发送,因此用户不会直接获取信息,但我认为使用Spring MVC 3.2和Java 7是避免内存中元素的最接近方法。

英文:

Ok , I have solved my problem . I attach the solution . Maybe it's useful to anybody.

<b>Controller</b>

  1. @RequestMapping(value=&quot;/eutm/{trademarkId}/snapshots/{historyId}/attachements/{attachementId}&quot;, method = RequestMethod.GET)
  2. @ResponseBody
  3. public void getTrademarkAttachement(HttpServletResponse response, @PathVariable String trademarkId, @PathVariable String historyId, @PathVariable String attachementId) {
  4. try {
  5. registerService.getTrademarkAttachement(trademarkId, historyId, attachementId, LanguageController.getLocale(), response.getOutputStream());
  6. } catch (IOException e) {
  7. e.printStackTrace();
  8. }
  9. }

<b>Service</b>

  1. @Override
  2. public void getTrademarkAttachement(String trademarkId, String historyId, String attachementId, Locale locale, ServletOutputStream outputStream) {
  3. URI uri = loadHistoryUri(generateUri(REGISTER_BASE_MS_URL, REGISTER_HISTORY_ENTRY_TM_ATTACHEMENT_WS_URL, trademarkId, historyId, attachementId), locale.getLanguage());
  4. HttpURLConnection httpConn = null;
  5. String line = null;
  6. InputStream ins = null;
  7. try {
  8. httpConn = (HttpURLConnection) new URL(uri.toString()).openConnection();
  9. ins = httpConn.getInputStream();
  10. BufferedReader is = new BufferedReader(new InputStreamReader(ins));
  11. while ((line = is.readLine()) != null) {
  12. outputStream.write(line.getBytes());
  13. }
  14. outputStream.flush();
  15. } catch (MalformedURLException e) {
  16. e.printStackTrace();
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. } finally {
  20. httpConn.disconnect();
  21. if(ins != null){
  22. try {
  23. ins.close();
  24. } catch (IOException e) {
  25. logger.error(&quot;Bad close of inputStream ins&quot;);
  26. }
  27. }
  28. }
  29. }

This way, as it reads lines from inputStream ( url to retrieve via GET connection ), it writes it directly to the response via outputStream . It doesn't send bit to bit as in reactive mode , so the user is not getting the info directly, but I think that with Spring MVC 3.2 and Java 7 is the most approximate way to avoid elements in memory .

huangapple
  • 本文由 发表于 2020年1月30日 19:10:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/59984666.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定