2015-03-24 2 views
1

Странная вещь произошла в Java Kingdom ...
Короче говоря: я использую Java API V3 для подключения к QuickBooks и выбор формы данных там (например, службы).
Все идет хорошо, за исключением случая, когда служба содержит русские символы (или, вероятно, нелатинские символы).
Вот Java код, который делает это (я знаю, что это далеко от совершенства)Маска кодирования файлов Java

package com.mde.test; 

import static com.intuit.ipp.query.GenerateQuery.$; 
import static com.intuit.ipp.query.GenerateQuery.select; 
import java.util.LinkedList; 
import java.util.List; 

import com.intuit.ipp.core.Context; 
import com.intuit.ipp.core.ServiceType; 
import com.intuit.ipp.data.Item; 
import com.intuit.ipp.exception.FMSException; 
import com.intuit.ipp.query.GenerateQuery; 
import com.intuit.ipp.security.OAuthAuthorizer; 
import com.intuit.ipp.services.DataService; 
import com.intuit.ipp.util.Config; 

public class TestEncoding { 

    public static final String QBO_BASE_URL_SANDBOX = "https://sandbox-quickbooks.api.intuit.com/v3/company"; 

    private static String consumerKey = "consumerkeycode"; 
    private static String consumerSecret = "consumersecretcode"; 
    private static String accessToken = "accesstokencode"; 
    private static String accessTokenSecret = "accesstokensecretcode"; 
    private static String appToken = "apptokencode"; 
    private static String companyId = "companyidcode"; 

    private static OAuthAuthorizer oauth = new OAuthAuthorizer(consumerKey, consumerSecret, accessToken, accessTokenSecret); 

    private static final int PAGING_STEP = 500; 


    public static void main(String[] args) throws FMSException { 
     List<Item> res = findAllServices(getDataService()); 
     System.out.println(res.get(1).getName()); 
    } 

    public static List<Item> findAllServices(DataService service) throws FMSException { 
     Item item = GenerateQuery.createQueryEntity(Item.class); 
     List<Item> res = new LinkedList<>(); 

     for (int skip = 0; ; skip += PAGING_STEP) { 
      String query = select($(item)).skip(skip).take(PAGING_STEP).generate(); 
      List<Item> items = (List<Item>)service.executeQuery(query).getEntities(); 
      if (items.size() > 0) 
       res.addAll(items); 
      else 
       break; 
     } 
     System.out.println("All services fetched"); 
     return res; 
    } 

    public static DataService getDataService() throws FMSException { 
     Context context = getContext(); 
     if (context == null) { 
      System.out.println("Context is null, something wrong, dataService also will null."); 
      return null; 
     } 
     return getDataService(context); 
    } 

    private static Context getContext() { 
     try { 
      return new Context(oauth, appToken, ServiceType.QBO, companyId); 
     } catch (FMSException e) { 
      System.out.println("Context is not loaded"); 
      return null; 
     } 
    } 

    protected static DataService getDataService(Context context) throws FMSException { 
     DataService service = new DataService(context); 
     Config.setProperty(Config.BASE_URL_QBO, QBO_BASE_URL_SANDBOX); 
     return new DataService(context); 
    } 
    } 

Этот файл будет сохранен в кодировке UTF-8. И он печатает что-то вроде

Все услуги принес
РЎСЌСЂРІС <СГ, РѕС,РЅСЋРґСЊ

Но! Когда я сохраняю этот файл в UTF-8 с помощью спецификации ... Я получаю правильные данные!

Все услуги принес
Сэрвыс, Отнюдь

ли кто-нибудь может объяснить, что происходит? :)
// Я использую Eclipse, чтобы запустить код

ответ

2

Вы забирающий данные из системы, которая не разделяет тот же порядок байтов, как вы, поэтому, когда вы сохраните файл с BOM, он добавляет достаточно информации файл, который будущие программы будут читать в байтовом порядке удаленной системы.

Когда вы сохраняете его без спецификации, он записывает файл в байтовом порядке удаленной системы без указания сохраненного порядка байтов, поэтому при его чтении вы читаете его с помощью порядка байтов локальной системы (другого). Это перемещает байты в многобайтовых символах, делая вывод таким же бессмысленным.

+0

Это звучит не так просто для меня :) Я не понял идею «удаленного байтового байта» и до сих пор не понимаю, как кодирование java-файла может влиять на кодирование DATA. Создает ли компилятор другой класс .class файлов в зависимости от кодировки .java-файла? Я не спорю, и я считаю, что это правильный ответ, но не могли бы вы предоставить какие-либо ссылки или «дальнейшее чтение», чтобы понять, как именно этот процесс работает? :) Или что-то еще :) – Zmiter

+0

@Zmiter думает об этом таким образом. Если вы нарисуете изображение на одной странице бумаги, то после того, как вы сохраните эту бумагу и извлечете ее, она все равно будет похожа на ту же картинку. Если вам нужно использовать два листа бумаги, потому что изображение велико, то человек, хранящий его, и человек, который его получает, должен координировать или у вас есть риск получить другое изображение, потому что страницы обращены. В UTF-8 для большинства символов требуется более одного байта, и вы извлекаете его в другом порядке, чем он был сохранен. BOM - это как примечание, в котором указывается, какой порядок для извлечения байтов. –

+0

Это довольно ясно :) Но в моем случае .java-файл соответствует изображению, которое вы описали, потому что BOM напрямую говорит, в каком порядке извлекать байты этого FILE, поэтому почему это влияет на DATA, который поступает из службы (данные это еще одна фотография)? /* Похоже, что если первый разработчик строит код, он будет работать нормально, а если второй разработчик строит код только с другой кодировкой, он не сработает, верно? */ – Zmiter

Смежные вопросы