Бинарный файл Spring Donwload

Я пытаюсь написать контроллер для загрузки двоичного файла.

Исходный код:

  public @ResponseBody byte[] getOpenedEventsInPdf(HttpServletResponse response)
        throws IOException, URISyntaxException {

    ClassPathResource pdfFile = new ClassPathResource(SRC_FILE);
    HttpHeaders headers = new HttpHeaders();
    response.addHeader("Content-Type", "application/pdf");
    response.addHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT");
    response.addHeader("Access-Control-Allow-Headers", "Content-Type");
    response.addHeader("Content-Disposition", "filename = " + FILE_NAME);
    response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
    response.addHeader("Pragma", "no-cache");
    response.addHeader("Expires", "0");

    headers.setContentLength(pdfFile.contentLength());

    byte[] toRet = toByteArray(new DataInputStream(
            new FileInputStream(new File(this.getClass().getClassLoader().getResource(SRC_FILE).toURI()))));
    byte[] bte = { (byte) 128, 65, (byte) 129, 65, (byte) 130 };
    System.out.println(toRet[0] & 0xFF);
    System.out.println(toRet[0]);
    System.out.println(toRet.length);
//        return toRet ;
    return bte;
}

Но проблема в том, что если я верну bte, я получу ровно 5 байт Если я вернусь к Ret, я получу 509 байт. Но исходный FILE_NAME содержит 256 байтов, начиная с 0-255.

Я предполагаю, что следующая строка имеет какое-то отношение.

byte[] toRet = toByteArray(new DataInputStream(
        new FileInputStream(new File(this.getClass().getClassLoader().getResource(SRC_FILE).toURI()))));

Поскольку значения выше 127 были изменены. Что мне не хватает?

- запрошенный код из комментария -

private byte[] listToByteArray(List<byte[]> input) {
    if (input == null || input.size() == 0) {
        return new byte[] {};
    }
    byte[] toRet = {};
    for (byte[] b : input) {
        toRet = ArrayUtils.addAll(toRet, b);
    }
    return toRet;
}

private byte[] toByteArray(InputStream is) throws IOException {
    List<byte[]> byteArrayList = new ArrayList<byte[]>();
    while (true) {
        byte[] buff = new byte[READ_BYTE_LENGTH];
        int r = is.read(buff);
        if (r == -1) {
            break;
        } else if (r == READ_BYTE_LENGTH) {
            byteArrayList.add(buff);
        } else {
            byteArrayList.add(Arrays.copyOf(buff, r));
        }
    }
    return listToByteArray(byteArrayList);
}

Если вы будете блуждать, почему я сделал это безумие, когда guava или apache common lang предлагают все доступное? Это потому, что я схожу с ума от этого

Можете выложить код toByteArray()

Vasan 12.04.2018 06:27

@Vasan Я добавил код

Popeye 12.04.2018 06:51
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
609
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, что ваше чтение байтов намного сложнее, чем должно быть, и, вероятно, виновато в проблеме. Если вы используете java 9, вам просто нужно сделать

private byte[] toByteArray(InputStream is) throws IOException {
    return is.readAllBytes();
}

а если нет, используйте что-нибудь вроде:

private byte[] toByteArray(InputStream is) throws IOException {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    byte[] data = new byte[16384];

    while ((int nRead = is.read(data, 0, data.length)) != -1) {
       buffer.write(data, 0, nRead);
    }

    return buffer.toByteArray();
}

Большое спасибо за ответ «Нет», я использую Java 8, и причина, по которой я нашел, не имеет ничего общего с тем, как я это готовлю. Мне не нужно писать байтовое чтение, как я уже упоминал в своем вопросе. Я написал это из-за разочарования и для того, чтобы разобраться в деталях. Но причина, которую я нашел, интересна. Maven делает копию файлов ресурсов, и как мой PDF-файл, так и случайные двоичные файлы повреждаются в самом каталоге.

Popeye 12.04.2018 07:51

@Popeye Я думаю, вы столкнулись с проблемой фильтрации maven. Предлагаю закрыть вопрос, так как нигде в вопросе вы даже не упомянули maven.

eis 12.04.2018 07:56
Ответ принят как подходящий

Я понял, что мой InputStream или механизм чтения не имеют ничего общего с повреждением данных. Maven изменяет файлы PDF и мои тестовые двоичные файлы на UTF-8. Я ищу это решение. Спасибо всем, кто заинтересовался вопросом.

Я решил проблему с добавлением следующего кода в сборку проекта pom.xml <plugin> <groupId> org.apache.maven.plugins </groupId> <artifactId> maven-resources-plugin </artifactId> <configuration> <nonFilteredFileExtensions> <nonFilteredFileExtension> ico </ nonFilteredFileExtensio‌ n> <nonFilteredFileExtension> pdf </ nonFilteredFileExtensio‌ n> </nonFilteredFileExtensions> </configuration> </plugin>

Popeye 12.04.2018 08:16

Другие вопросы по теме