Недавно я изменил зависимость
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
к
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.0</version>
</dependency>
потому что Java 8 не поддерживает версию 1.4, так как использует TLS 1.0.
После изменения зависимости этот код начинает выдавать ошибку. Код ошибки:
if (p.getContentType().contains("image/")) {
File f = new File("image" + new Date().getTime() + ".jpg");
DataOutputStream output = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(f)));
com.sun.mail.util.BASE64DecoderStream test = (com.sun.mail.util.BASE64DecoderStream) p
.getContent();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = test.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
Ошибка предложения Eclipse:
Multiple markers at this line
- com.sun.mail.util.BASE64DecoderStream cannot be resolved to a type
- com.sun.mail.util.BASE64DecoderStream cannot be resolved to a type
Ошибка, с которой вы столкнулись, связана с тем, что класс com.sun.mail.util.BASE64DecoderStream недоступен в библиотеке javax.mail версии 1.6.0. Этот класс был частью библиотеки javax.mail версии 1.4, которую вы использовали ранее.
Чтобы решить эту проблему, у вас есть несколько вариантов:
Вернитесь к предыдущей версии (1.4) библиотеки javax.mail. Это можно сделать, отменив изменения, внесенные вами в зависимости Maven или Gradle.
xml
Copy code
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
Обновите свой код, чтобы использовать другой подход для декодирования данных Base64. Вместо использования com.sun.mail.util.BASE64DecoderStream можно использовать класс java.util.Base64, доступный в Java SE 8 и более поздних версиях.
Вот пример того, как вы можете изменить свой код:
java
Copy code
if (p.getContentType().contains("image/")) {
File f = new File("image" + new Date().getTime() + ".jpg");
try (OutputStream output = new BufferedOutputStream(new FileOutputStream(f))) {
String content = (String) p.getContent();
byte[] data = java.util.Base64.getDecoder().decode(content);
output.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
Обратите внимание, что этот подход предполагает, что содержимое объекта p представляет собой строку в кодировке Base64. Если это не так, вам может потребоваться изменить код соответствующим образом.
Если вам необходимо продолжить использование библиотеки javax.mail версии 1.6.0, вы можете найти в библиотеке альтернативный класс или метод, обеспечивающий функциональность декодирования Base64. Вы можете просмотреть документацию или выполнить поиск примеров или руководств, относящихся к конкретной версии, которую вы используете.
Класс com.sun.mail.util.BASE64DecoderStream
все еще существует в реализации JavaMail/JakartaMail 1.6.x. Проблема в том, что OP объявил неправильную зависимость, API, а не реализацию.
Тем не менее, я думаю, что код будет сильнее для использования java.util.Base64
, который также может работать в потоковом режиме.
Как сейчас написано, ваш ответ неясен. Пожалуйста, отредактируйте , чтобы добавить дополнительные сведения, которые помогут другим понять, как это отвечает на заданный вопрос. Вы можете найти больше информации о том, как писать хорошие ответы в справочном центре.
@ g00se Нет необходимости приводить к BASE64DecoderStream
, как это делается здесь. ОП мог бы просто использовать getInputStream
и использовать это вместо использования getContent()
и привести возвращенный объект. Тот факт, что он может (или не может) использовать BASE64DecoderStream
, является деталью реализации.
Да, это правда. Поток мог быть скопирован напрямую. Код требует доработки, в том числе замены устаревших классов API.
Вы используете неправильную зависимость. Вы добавили только JakartaMail API. Вы должны использовать реализацию JakartaMail 1.6.x:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.7</version>
</dependency>
Эта зависимость включает com.sun.mail.util.BASE64DecoderStream
.
Кстати, вместо того, что вы делаете сейчас (используя getContent()
и приводя к классу, специфичному для реализации), вы также можете использовать Part.getInputStream()
:
try (var in = p.getInputStream()) {
in.transferTo(output);
}
Кроме того, ваше использование DataOutputStream
вызывает подозрения, поскольку вы, похоже, не используете какие-либо конкретные методы DataOutputStream
, поэтому прямого использования BufferedOutputStream
должно быть достаточно.
спасибо, используя неправильную зависимость, это помогает
if (p.getContentType().contains("image/")) {
Path imageFile = Path.of("image" + Instant.now().toEpochMilli() + ".jpg");
try(OutputStream out = Files.newOutputStream(imageFile)) {
p.getInputStream().transferTo(out);
}
}
проиллюстрирует комментарии между мной и @Mark Rotteveel. По сути, то, что Марк уже опубликовал, с дальнейшими корректировками обработки даты и попытки использования ресурсов.
getContent()
возвращает Object
, поэтому тип значения необходимо проверить и привести, и в зависимости от поставщиков активации Jakarta в пути к классам getContent()
может вернуть что-то еще. Вместо этого я рекомендую использовать p.getInputStream()
.
Ах точно спасибо. Будет корректировать
FWIW: последние обновления Java 8 (и все 11 выше) по умолчанию не поддерживают TLS1.0, но вы можете снова включить его. Тем не менее, хорошая практика в настоящее время требует, чтобы серверы не позволяли вам подключаться с использованием этого (или SSL3), и хотя не все серверы быстро следуют хорошей практике, некоторые делают это сейчас, а со временем еще больше, поэтому обновление вашего клиента остается хорошей идеей.