Читайте ресурс из URL и возвращайте эти байты напрямую в ответ на запрос REST, без сохранения памяти с Java 7 и пружиной MVC 3.2. - PullRequest
0 голосов
/ 30 января 2020

У меня есть конечная точка REST, к которой нужно получить доступ, чтобы получить ресурс (изображение, документ, ...).

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

Для получения этого документа я хочу сделать это через потоковую передачу. Я не хочу хранить в памяти информацию. Я хочу, когда я получаю информацию, отправлять байты в ответ. Моя версия spring MVC - это Spring MVC 3.2, а моя версия java - java 7. Возможно ли этого добиться? Не могли бы вы дать какой-нибудь ключ, чтобы начать расследование? , Я знаю, что даю мало подробностей о реализации, но я начинаю с этого, и я хотел бы получить некоторые идеи от вас.

РЕДАКТИРОВАТЬ 1:

Я достиг половины проблемы. Извлечение разных блоков URL. Я использовал следующий код

 @Override
public byte[] getTrademarkAttachement() {
    String urlSample = "http://testUrl.com";
    HttpURLConnection httpConn = null;
    String line = null;
    try {
        httpConn = (HttpURLConnection) new URL(urlSample).openConnection();
        InputStream ins = httpConn.getInputStream();
        BufferedReader is = new BufferedReader(new InputStreamReader(ins));
        while ((line = is.readLine()) != null) {
            System.out.println(line);
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        httpConn.disconnect();
    }
    return null;
}

Будучи в состоянии иметь доступ к входному потоку, оставшаяся часть возвращает каждую из строк, которые я читаю, поэтому я могу передать ответ. Я должен искать метод весной MVC, который дает частичный ответ.

Ответы [ 3 ]

1 голос
/ 30 января 2020

Поскольку вы можете получить InputStream, вы должны иметь возможность возвращать OutputStream в качестве ответа на запрос. Взгляните на это ({ ссылка }):

@RequestMapping(value = "/attachement", method = RequestMethod.GET)
@ResponseBody
public void getAttachment(OutputStream out) {

    InputStream in = ; // Set this to the InputStream from HTTP as your provided example
    byte[] buffer = new byte[1024]; // You will need a small buffer mem though
    int len;
    while ((len = in.read(buffer)) != -1) {
        out.write(buffer, 0, len);
    }
    in.close();
    out.flush();
}
0 голосов
/ 30 января 2020

Хорошо, я решил свою проблему. Я прилагаю решение. Может быть, это полезно для всех.

Контроллер

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

Служба

 @Override
 public void getTrademarkAttachement(String trademarkId, String historyId, String attachementId, Locale locale, ServletOutputStream outputStream) {
    URI uri = loadHistoryUri(generateUri(REGISTER_BASE_MS_URL, REGISTER_HISTORY_ENTRY_TM_ATTACHEMENT_WS_URL, trademarkId, historyId, attachementId), locale.getLanguage());
    HttpURLConnection httpConn = null;
    String line = null;
    InputStream ins = null;
    try {
        httpConn = (HttpURLConnection) new URL(uri.toString()).openConnection();
        ins = httpConn.getInputStream();
        BufferedReader is = new BufferedReader(new InputStreamReader(ins));

        while ((line = is.readLine()) != null) {
            outputStream.write(line.getBytes());
        }
     outputStream.flush();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        httpConn.disconnect();

        if(ins != null){
        try {
            ins.close();
        } catch (IOException e) {
            logger.error("Bad close of inputStream ins");
        }
        }
    }
}

Таким образом, поскольку он читает строки из inputStream (url для получить через соединение GET), он записывает его непосредственно в ответ через outputStream. Он не посылает бит за битом, как в реактивном режиме, поэтому пользователь не получает информацию напрямую, но я думаю, что с Spring MVC 3.2 и Java 7 - это наиболее приблизительный способ избежать элементов в памяти.

0 голосов
/ 30 января 2020
@RequestMapping(value = "/test/", method = RequestMethod.GET)
    public Response getFileTest(@RequestParam(value="path", defaultValue="/home") String path){
        RestTemplate restTemplate = new RestTemplate();
        Response response = restTemplate.getForObject("http://localhost:8086/ATS/client/file/?path={path}", Response.class, path);
        if (response.isStatus() && response.isSuccess()){
            try {
                byte[] parseBase64Binary = DatatypeConverter.parseBase64Binary((String)response.getResult());
                Files.write(Paths.get("test.txt"),parseBase64Binary );
            } catch (IOException e) {
            }
        }
        return response;
    }

Так что код должен быть примерно таким

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...