s.dallapalma
s.dallapalma

Reputation: 1315

Retrofit2: HTTP 404 Not Found

I have this simple service on my server at http://192.168.1.12:8080/api/hooray:

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

It does work from Postman, but from my Android application I unable to reach that url, and I don't know why.

That's the (simplified) code:

Service's Interface

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

My custom Response class: 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 ...
}

Caller

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!!!");
                }
            });
}

When I call the foo() method, I get this error:

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)

I can't figure out because the error: HTTP 404 Not Found. That service is reachable and it works. I wrote a service API for login in a very similar way to HoorayAPI, with a POST method, and it works. Why it doesn't work here? I mean, the code seems to be correct.

Upvotes: 3

Views: 18132

Answers (3)

s.dallapalma
s.dallapalma

Reputation: 1315

Ok, I've found the answer. The problem was in .baseUrl(getResources().getString(R.string.url)). The url was stored in the resource file values/string.xml as

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

However, in another resource file values-it/string.xml there was the following:

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

Because of the language of my smartphone was set to italian, the resource file values-it/string.xml was used, so the program recognized https://myapp-api.mydomain.io/api as url instead of http://192.168.1.12:8080/api/.

Be aware to correctly update all the url in the resource files to avoid this problem.

Upvotes: 3

Sasha Balyas
Sasha Balyas

Reputation: 440

You should change the type of your subscribeOn(Schedulers.newThread()) to this .subscribeOn(Schedulers.single()) It helps for me =)

Upvotes: 0

Andrea Vassallo
Andrea Vassallo

Reputation: 150

Are you sure that the mobile phone is connected to the same LAN ?

Otherwise you can try removing the end slash on the interface but this should not be the problem

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

Upvotes: 0

Related Questions