Friday, May 16, 2008

OpenAds и русские буквы

Уже достаточно долго для показа баннеров я использую баннеровертелку OpenX (раньше называлась OpenAds, http://www.openx.org/). Для интеграции с сайтами, которые не используют PHP (а большинство у меня на Java), в OpenX используется XML-RPC.

Ну почему софт на PHP всегда такой глючный!

XML-RPC сервер в OpenX всегда возвращает ответ в кодировке UTF-8. Однако среди поддерживаемых OpenX кодировок нет UTF-8. Для русских символом есть koi8r и windows-1251. И когда в описании баннера присутствуют русские символы (в моем случае - в windows-1251), они не преобразовываются в UTF-8. В результате мой XML-RPC клиент от Apache выдает сообщение:
org.apache.xmlrpc.client.XmlRpcClientException: Failed to read servers response: Invalid byte 2 of 2-byte UTF-8 sequence.
at org.apache.xmlrpc.client.XmlRpcStreamTransport.readResponse(XmlRpcStreamTransport.java:179)
at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:145)
at org.apache.xmlrpc.client.XmlRpcHttpTransport.sendRequest(XmlRpcHttpTransport.java:94)
      ...
В списке рассылки Apache XML-RPC пользователи жалуются на похожую проблему, на что разработчики XML-RPC резонно отвечают, что это проблема сервера, и решать ее они в принципе не будут. Но баннеры нужно показать. Поэтому правим немного XML-RPC клиент. В метод
org.apache.xmlrpc.client.XmlRpcStreamTransport.readResponse
ставим первую строку
InputSource isource = new InputSource(ResponseFilter.filter(pStream));
и сам клас ResponseFilter
public class ResponseFilter {
  public static InputStream filter(InputStream input) {
      StringWriter s = new StringWriter();
    
      try {
          InputStreamReader r = new InputStreamReader(input, "windows-1251");
        
          int ch;
          while ((ch = r.read()) != -1) {
              s.write(ch);
          }
        
          input.close();
      } catch (IOException e) {
          throw new RuntimeException(e);
      }
    
      return new ByteArrayInputStream(s.toString().getBytes());
  }
}
Теперь работает.

No comments: