Retrofit2: HTTP 404 не найден

У меня есть эта простая служба на моем сервере по адресу http://192.168.1.12:8080/api/hooray:

router.route('/hooray/')
    .get(function (req, res) {
        res.status(200).send({ result: true, message: "hooray" })
    })

Это работает из Postman, но из моего приложения для Android я не могу получить доступ к этому URL-адресу, и я не знаю, почему.

Это (упрощенный) код:

Интерфейс сервиса

public interface HoorayAPI {
    @GET("hooray/")
    Observable<HoorayResponse> hooray();
}

Мой пользовательский класс ответа: HoorayResponse

public class HoorayResponse{
    @SerializedName("result")
    @Expose
    private boolean result;

    @SerializedName("message")
    @Expose
    private String message;

    public HoorayResponse(boolean result, String message) {
        this.result = result;
        this.message = message;
    }

    // Getter and setter ...
}

Звонящий

public void foo(){
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://192.168.1.12:8080/api/")
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    HoorayAPI service = retrofit.create(HoorayAPI.class);

    Observable<HoorayResponse> hoorayObservable = service.hooray();

    hoorayObservable
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<HoorayResponse>() {
                @Override
                public void onCompleted() {}

                @Override
                public void onError(Throwable e) { e.printStackTrace(); }

                @Override
                public void onNext(HoorayResponse response) {
                    System.out.println("Hooray!!!");
                }
            });
}

Когда я вызываю метод foo(), я получаю эту ошибку:

retrofit2.adapter.rxjava.HttpException: HTTP 404 Not Found 
    at retrofit2.adapter.rxjava.OperatorMapResponseToBodyOrError$1.onNext(OperatorMapResponseToBodyOrError.java:43)
    at retrofit2.adapter.rxjava.OperatorMapResponseToBodyOrError$1.onNext(OperatorMapResponseToBodyOrError.java:38)
    at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$RequestArbiter.request(RxJavaCallAdapterFactory.java:173)
    at rx.internal.operators.OperatorSubscribeOn$1$1$1.request(OperatorSubscribeOn.java:80)
    at rx.Subscriber.setProducer(Subscriber.java:211)
    at rx.internal.operators.OperatorSubscribeOn$1$1.setProducer(OperatorSubscribeOn.java:76)
    at rx.Subscriber.setProducer(Subscriber.java:205)
    at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:152)
    at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:138)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
    at rx.Observable.unsafeSubscribe(Observable.java:8460)
    at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:776)

Я не могу понять, потому что ошибка: HTTP 404 Not Found. Этот сервис доступен и работает. Я написал сервисный API для логин, очень похожий на HoorayAPI, с методом POST, и он работает. Почему здесь не работает? Я имею в виду, что код кажется правильным.


person s.dallapalma    schedule 07.09.2017    source источник


Ответы (3)


Хорошо, я нашел ответ. Проблема была в .baseUrl(getResources().getString(R.string.url)). URL-адрес был сохранен в файле ресурсов values/string.xml как

<string name="url">http://192.168.1.12:8080/api/</string>

Однако в другом файле ресурсов values-it/string.xml было следующее:

<string name="url">https://myapp-api.mydomain.io/api</string>

Поскольку язык моего смартфона был установлен на итальянский, использовался файл ресурсов values-it/string.xml, поэтому программа распознала https://myapp-api.mydomain.io/api вместо http://192.168.

Не забывайте правильно обновлять все URL-адреса в файлах ресурсов, чтобы избежать этой проблемы.

person s.dallapalma    schedule 07.09.2017

Вы уверены, что мобильный телефон подключен к той же локальной сети?

В противном случае вы можете попробовать удалить косую черту на интерфейсе, но это не должно быть проблемой.

public interface HoorayAPI {
    @GET("hooray")
    Observable<HoorayResponse> hooray();
}
person Andrea Vassallo    schedule 07.09.2017
comment
Да, мобильный телефон подключен к той же локальной сети, и нет, проблема не в косой черте :/. Как я уже сказал, с другой службой (логин) это работает, поэтому такое поведение странно. - person s.dallapalma; 07.09.2017
comment
Могу ли я попробовать услугу? Если вы используете ngrok, чтобы поделиться своим локальным WS, я могу попробовать отладить с вами. - person Andrea Vassallo; 07.09.2017
comment
Просто любопытство! У вас такая же ошибка, если вы используете URL-адрес ngrok? - person Andrea Vassallo; 07.09.2017
comment
Поэтому я не могу его отладить. Очень странно, попробуйте перезагрузить WS! Если у меня появится идея, я напишу вам! Если сможешь решить, напиши ответ пожалуйста :) - person Andrea Vassallo; 07.09.2017
comment
Спасибо. Я очень ценю это. По крайней мере, на данный момент это работает на ngrok ;P - person s.dallapalma; 07.09.2017
comment
Я отправляю ответ, я не знаю, почему такое поведение. Спасибо, если бы я не попробовал это с ngrok, я бы не смог решить проблему - person s.dallapalma; 07.09.2017
comment
Это было приятно. Однако я использую это, чтобы помочь себе в отладке: stackoverflow.com/a/33256827/5650222 Попробуйте :) - person Andrea Vassallo; 07.09.2017

Вы должны изменить тип вашего subscribeOn(Schedulers.newThread()) на этот .subscribeOn(Schedulers.single()) Мне это помогает =)

person Sasha Balyas    schedule 24.03.2018
comment
На самом деле это должна быть подписка на Schedulers.io(), так как это блокирующая операция. - person William Reed; 06.02.2019