2016-11-29 9 views
3

Я получаю исключение, похороненный путь внутри 3-сторонней библиотеки, с сообщением вроде этого:Есть ли способ, чтобы добавить псевдонимы для имен Charset Явы

java.io.UnsupportedEncodingException: BIG-5

Я думаю, что это происходит потому, что Java не определяет это имя для java.nio.charset.Charset. Charset.forName("big5") в порядке, но Charset.forName("big-5") выбрасывает исключение. (Все эти имена выглядят нечувствительными к регистру.)

Это отличается от «utf-8», в котором некоторые псевдонимы являются более прощающими. Например, как Charset.forName("utf8"), так и Charset.forName("utf-8") работают нормально.

Вопрос: есть ли способ добавить псевдоним, чтобы «большой-5» отображался на «big5»?

+0

является библиотекой третьей стороной JavaMail случайно? – dnault

+0

Сделать константу где-нибудь с 'private static final Charset BIG5_CHARSET = Charset.forName (" big5 ")'? У вас больше нет проблем. Или вы говорите, что это внутри кода, который вы не контролируете? – Tunaki

+0

Откуда берутся названия набора символов? Можете ли вы перехватить и канонизировать их? – dnault

ответ

2

Вы можете попробовать свойство mail.mime.contenttypehandler системы:

В некоторых случаях JavaMail не может обрабатывать сообщения с недействительным заголовка Content-Type. Заголовок может иметь неправильный синтаксис или другие проблемы. Это свойство указывает имя класса, который будет использоваться для очистки значения заголовка Content-Type до использования JavaMail. Класс должен иметь метод с этой сигнатурой: public static String cleanContentType (MimePart mp, String contentType) Всякий раз, когда JavaMail обращается к заголовку Content-Type сообщения, он передает значение этому методу и вместо этого использует возвращаемое значение.

Примером этого является:

import java.util.Arrays; 
import javax.mail.Session; 
import javax.mail.internet.ContentType; 
import javax.mail.internet.MimeMessage; 
import javax.mail.internet.MimePart; 

public class FixEncodingName { 

    public static void main(String[] args) throws Exception { 
     MimeMessage msg = new MimeMessage((Session) null); 
     msg.setText("test", "big-5"); 
     msg.saveChanges(); 
     System.out.println(msg.getContentType()); 
     System.out.println(Arrays.toString(msg.getHeader("Content-Type"))); 
    } 

    public static String cleanContentType(MimePart p, String mimeType) { 
     if (mimeType != null) { 
      String newContentType = mimeType; 
      try { 
       ContentType ct = new ContentType(mimeType); 
       String cs = ct.getParameter("charset"); 
       if ("big-5".equalsIgnoreCase(cs)) { 
        ct.setParameter("charset", "big5"); 
        newContentType = ct.toString(); 
       } 
      } catch (Exception ignore) { 
       newContentType = newContentType.replace("big-5", "big5"); 
      } 

      /*try { //Fix the header in the message. 
       p.setContent(p.getContent(), newContentType); 
       if (p instanceof Message) { 
        ((Message) p).saveChanges(); 
       } 
      } catch (Exception ignore) { 
      }*/ 
      return newContentType; 
     } 
     return mimeType; 
    } 
} 

При запуске с выходом -Dmail.mime.contenttypehandler=FixEncodingName будет:

text/plain; charset=big5 
[text/plain; charset=big-5]