Клиент Джерси не работает на Android при публикации параметров формы

На самом деле это не вопрос, а решение проблемы, о которой сообщалось на этом сайте в нескольких сообщениях. Так как я боролся с этим и нашел решение, я думал, что кто-то другой может сэкономить время. Приведенный ниже код прекрасно работает при запуске из eclipse, но завершается с ошибкой "com.sun.jersey.api.client.ClientHandlerException: средство записи тела сообщения для типа Java...."

MultivaluedMap<String, String> formData = new MultivaluedMapImpl();
    formData.add("username", "demo");
    formData.add("password", "1234qwer");
    WebResource webResource = client.getResource("https://dev.example.com:8443/authenticate/login");
    ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED).post(ClientResponse.class,formData);

Я нашел ответ из поста и ссылку, приведенную в ответе.

По сути, идея состоит в том, чтобы сообщить Джерси о доступных средствах чтения / записи сообщений через шаблон поиска сервисов. Пример показан ниже

открытый класс AndroidServiceIteratorProvider расширяет ServiceIteratorProvider {

private static final String TAG = AndroidServiceIteratorProvider.class.getSimpleName();
private static final String MESSAGE = "Unable to load provider";

private static final HashMap<String, String[]> SERVICES = new HashMap<String, String[]>();

private static final String[] com_sun_jersey_spi_HeaderDelegateProvider = {
        "com.sun.jersey.core.impl.provider.header.MediaTypeProvider",
        "com.sun.jersey.core.impl.provider.header.StringProvider"
};

private static final String[] com_sun_jersey_spi_inject_InjectableProvider = { 
};

private static final String[] javax_ws_rs_ext_MessageBodyReader = {
        "com.sun.jersey.core.impl.provider.entity.StringProvider",
        "com.sun.jersey.core.impl.provider.entity.FormMultivaluedMapProvider",
        "com.sun.jersey.core.impl.provider.entity.ReaderProvider"
};

private static final String[] javax_ws_rs_ext_MessageBodyWriter = {
        "com.sun.jersey.core.impl.provider.entity.StringProvider",
        "com.sun.jersey.core.impl.provider.entity.FormMultivaluedMapProvider",
        "com.sun.jersey.core.impl.provider.entity.ReaderProvider"
};

static {
    SERVICES.put("com.sun.jersey.spi.HeaderDelegateProvider",
            com_sun_jersey_spi_HeaderDelegateProvider);
    SERVICES.put("com.sun.jersey.spi.inject.InjectableProvider",
            com_sun_jersey_spi_inject_InjectableProvider);
    SERVICES.put("javax.ws.rs.ext.MessageBodyReader",
            javax_ws_rs_ext_MessageBodyReader);
    SERVICES.put("javax.ws.rs.ext.MessageBodyWriter",
            javax_ws_rs_ext_MessageBodyWriter);
    SERVICES.put("jersey-client-components", new String[]{});
    SERVICES.put("com.sun.jersey.client.proxy.ViewProxyProvider", new String[]{});
}

@SuppressWarnings("unchecked")
@Override
public Iterator<Class<T>> createClassIterator(Class<T> service,
        String serviceName, ClassLoader loader,
        boolean ignoreOnClassNotFound) {

    String[] classesNames = SERVICES.get(serviceName);
    int length = classesNames.length;
    ArrayList<Class<T>> classes = new ArrayList<Class<T>>(length);
    for (int i = 0; i < length; i++) {
        try {
            classes.add((Class<T>) Class.forName(classesNames[i]));
        } catch (ClassNotFoundException e) {
            Log.v(TAG, MESSAGE,e);
        }
    }
    return classes.iterator();
}

@Override
public Iterator<T> createIterator(Class<T> service, String serviceName,
        ClassLoader loader, boolean ignoreOnClassNotFound) {

    String[] classesNames = SERVICES.get(serviceName);
    int length = classesNames.length;
    ArrayList<T> classes = new ArrayList<T>(length);
        for (int i = 0; i <length; i++) {
        try {
            classes.add(service.cast(Class.forName(classesNames[i])
                    .newInstance()));
        } catch (IllegalAccessException e) {
            Log.v(TAG, MESSAGE,e);
        } catch (InstantiationException e) {
            Log.v(TAG, MESSAGE,e);
        } catch (ClassNotFoundException e) {
            Log.v(TAG, MESSAGE,e);
        }
    }

    return classes.iterator();
}

}

Обратите внимание на строковые параметры, объявленные в javax_ws_rs_ext_MessageBodyReader и javax_ws_rs_ext_MessageBodyWriter. Вы захотите добавить соответствующее устройство чтения / записи в массив строк, а затем подключить этого провайдера к Джерси с помощью вызова API, как показано ниже.

 ServiceFinder.setIteratorProvider(new AndroidServiceIteratorProvider()); 

Список читателей и писателей сообщений можно найти здесь

0 ответов

Другие вопросы по тегам