Это меня озадачило в течение многих часов, и кажется маловероятным, но, пожалуйста, несите меня; Я считаю, что у меня есть доказательства.Использование службы Java SOAP прерывает цитируемую почтовую инкапсуляцию javax.mail
Я упростил это до минимального тестового примера (ниже). Чтобы проверить код, вам нужно будет использовать EmailTest.java
(ниже), а затем импортировать SOAP-сервис. Для этого я использовал:
wsimport -d bin -s src -keep -extension 'http://www.webservicex.net/stockquote.asmx?wsdl'
Для удобства я также поставил код на GitHub here, так что вы можете просто клонировать и запустить его; это уже имеет wsimport
.
Что ниже код делает это следующим образом:
- звонков
testMime()
, что создаетquoted-printable
части, а затем отображает его правильно (с верхними битым набором символы отделались последовательности, начиная с=
); - вызывает
stockQuoteTest
, который просто получает новую точку входа в веб-службу - на самом деле ее не нужно называть веб-службой; - снова вызывает
testMime()
, который создает частьquoted-printable
, но отображает ее неправильно, не избегая символов;system.out.Println
затем (предположительно) заменяет их?
.
Я использовал несколько SOAP-библиотек, все из которых делают то же самое - я выбрал простой демонстрационный пример для демонстрации. В действительности нет необходимости называть конечную точку SOAP. Похоже, что вызов getPort
(здесь, в getStockQuoteSoap12
).
До сих пор моя отладка определила, что ни один из кодировок по умолчанию, о которых я знаю, не изменился, и проблема заключается в том, что при втором вызове кодер quoted-printable
никогда не вызывается. Это связано с тем, что part.dh.dataContentHandler
получает какое-то значение ObjectDataContentHandler
, когда он работает, и типа StringDataContentHandler
, когда он не работает.
Любые идеи о том, что здесь происходит или как это исправить?
Я использую javax.mail
1.5.2 (новейший, но зато старая версия была такой же) - и
$ java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
Вот EmailTest.java
package emailtest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
// use any SOAP service. This one was generated using
// wsimport -d bin -s src -keep -extension http://www.webservicex.net/stockquote.asmx?wsdl
import net.webservicex.StockQuote;
import net.webservicex.StockQuoteSoap;
public class Emailtest {
public static void stockQuoteTest() {
StockQuote stockService = new StockQuote();
StockQuoteSoap s = stockService.getStockQuoteSoap12();
// We don't actually need to call SOAP to demonstrate the problem
// System.out.println("quote is "+s.getQuote("GOOG"));
}
public static void testMime() throws MessagingException {
String msg = "\u0287x\u01DD\u0287 u\u028Dop \u01DDp\u1D09sdn";
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText("" + msg, "utf-8");
messageBodyPart.setHeader("Content-Type", "text/plain; charset=\"utf-8\"");
messageBodyPart.setHeader("Content-Transfer-Encoding", "quoted-printable");
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
messageBodyPart.writeTo(os);
String aString = new String(os.toByteArray(),"UTF-8");
System.out.println(aString);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("");
}
public static void main(String args[]) {
try {
System.out.println("Before call to SOAP:");
testMime();
stockQuoteTest();
System.out.println("After call to SOAP:");
testMime();
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
Вот результат:
Before call to SOAP:
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
=CA=87x=C7=9D=CA=87 u=CA=8Dop =C7=9Dp=E1=B4=89sdn
After call to SOAP:
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
?x?? u?op ?p?sdn
О, и в случае, если это имеет значение, кодированный текст:
ʇxǝʇ uʍop ǝpᴉsdn
Вы можете увидеть, где quoted-printable
не работает (второй звонок), что буквы «вверх ногой», которые создаются обычными буквами, отображаются. Исследование показывает, что он просто не делает quoted-printable
.
Update
Это, казалось бы, a bug in jax-ws и, возможно, ошибка в javax.mail для полагаться на text/plain
обработчик, который случается в ФСД, а самостоятельно. Любые идеи для работы? (использование Java 7, где, как утверждается, установлено в jax-ws, не является опцией)
ОК, почему нижний предел без объяснения причин? Это полностью реплицируемая проблема с минимальным примером. – abligh