Трябва да има отговор 404 на GET заявка, но е получил 200. Restlet

Имам RESTlet сървър, работещ на моето Android устройство. Конфигуриран е добре. Сега го тествам jUnit и този конкретен тест се проваля без причина.

Имам този URL:

http://10.17.1.72:8080/contacts?order=ASC&limit=10&offset=1 което е правилно, получавам отговор 200 според очакванията.

Но тогава, ако напиша грешно параметрите в URL адреса, трябва да получа отговор 404. Използване на разширение пощальон за Chrome, ако натисна http://10.17.1.72:8080/contacts?oooooooorder=ASC&limit=10&offset=1 (имайте предвид, че „ поръчка" е изписан неправилно) Получавам 404, както трябва. До тук всичко е наред.

Проблемът идва, когато създам RESTlet клиент, за да направя това GET request на моя jUnit тест, той получава отговор 200.

Ето моят метод за тестване на jUnit:

public void testGoodRequest() // Success, receives a 200 code.
{
    // Create the client resource
    ClientResource resource = new ClientResource("http://10.17.1.72:8080/contacts?order=ASC&limit=10&offset=1");
    Response response = resource.getResponse();

    Log.d(TAG, "Good: " + response.getStatus().getCode());

    assertTrue(response.getStatus().getCode() == 200);      
}

И този трябва да получи 404, но получи 200, ако същата заявка за получаване, използвайки пощальона на Chrome, получи 404:

public void testBadRequestWithOrderMisspelled()
{
    // Create the client resource
    ClientResource resource = new ClientResource("http://10.17.1.72:8080/contacts?oofdgrder=ASC&limit=10&offset=1");
    Response response = resource.getResponse();

    Log.d(TAG, "BadRequestWithOrderMisspelled: " + response.getStatus().getCode());

    assertTrue(response.getStatus().getCode() == 404); // Assert fails, receives 200 instead of 404     
}

И ето моят метод за обработка на Restlet:

@Override
public void handle(Request request, Response response) {

    //final ContactList contactList = new ContactList(mContext);
    String type = request.getMethod().getName();

    String order = request.getResourceRef().getQueryAsForm().getFirstValue("order");
    String limit = request.getResourceRef().getQueryAsForm().getFirstValue("limit");
    String offset = request.getResourceRef().getQueryAsForm().getFirstValue("offset");
    String query = request.getResourceRef().getQueryAsForm().getFirstValue("query");

    if(!"order".equals(order) || !"limit".equals(limit) || !"offset".equals(offset) || !"query".equals(query))
    {
        // Show error
        response.setStatus(new Status(Status.CLIENT_ERROR_NOT_FOUND, "Badly formatted URL."));
        return;
    } 
(...)
}

person dazito    schedule 09.04.2014    source източник
comment
Не е точно отговор на въпроса ви, но аз лично не смятам, че е добра идея да давате 404 за лоши/невалидни параметри. Бих ви препоръчал да коригирате протокола за изпращане на съобщение за грешка (в Json или Xml) до клиента и клиентът трябва да обработи грешката по съответния начин.   -  person wns349    schedule 09.04.2014
comment
Правя това, защото ще изпълнявам SQL заявки на устройството и искам да предотвратя ненужни заявки към него или последващо претоварване на устройството.   -  person dazito    schedule 09.04.2014


Отговори (3)


404 е за ресурс http://10.17.1.72:8080/contacts не е намерен

УИКИПЕДИЯ: 404 Не е намерен Исканият ресурс не може да бъде намерен, но може да бъде отново достъпен в бъдеще. Допустими са последващи заявки от клиента.

ако има ресурс и не е даден правилен вход за процеса

няма да даде 404! Прочетете повече

плюс според следния код има 2 неща

  1. сбъркал си limite
  2. вие сравнявате получените стойности с низове като order offset amd limit

Не мисля, че това е, което искате да постигнете, по-скоро трябва да го сравнявате с някои променливи

if(!"order".equals(order) || !"limite".equals(limit) || !"offset".equals(offset) || !"query".equals(query))
    {
        // Show error
        response.setStatus(new Status(Status.CLIENT_ERROR_NOT_FOUND, "Badly formatted URL."));
        return;
    } 
person dev2d    schedule 09.04.2014
comment
Но изрично връщам отговор 404 на моя манипулатор, ако има грешен вход. Ако натисна този url в браузъра си, ще получа и заявка 404. - person dazito; 09.04.2014
comment
добре според мен не трябва да правите това, играейки със стандартни HTTP кодове. второто нещо, което правите е, че "order".equals(order) ще сравни стойността на атрибута на поръчката с String "order", това ли искате да постигнете? - person dev2d; 09.04.2014
comment
Точно така, искам да се уверя, че променливата order всъщност държи реда на стойността. Да, междувременно разбрах, че и това ограничение е неправилно изписано, поправих го. Все още получавам код за отговор 200. Правя това, защото ще изпълнявам SQL заявки в устройството и искам да предотвратя ненужни заявки към него или последващо претоварване на устройството. - person dazito; 09.04.2014
comment
надявам се, че знаете разликата между getFirst() и getFirstValue() в това request.getResourceRef().getQueryAsForm().getFirstValue("order") - person dev2d; 09.04.2014
comment
прочетете тук restlet.org/learn/javadocs/2.1/jee/api/org/restlet/util/ - person dev2d; 09.04.2014
comment
Да, забравих тази малка подробност, която също помагаше за неочаквани резултати. +1 добавен. В крайна сметка се преместих на android async http и работи добре. Благодаря за вашата помощ! - person dazito; 09.04.2014

По някаква причина, която не знам, клиентът RESTlet вероятно е причината за моя проблем.

Преминах към http://loopj.com/android-async-http/ клиент и нещата вървят гладко.

Ето моят код, използващ async http клиент:

    SyncHttpClient client = new SyncHttpClient();

    // Should be success
    client.get("http://10.17.1.72:8080/contacts", new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(String response) {
            Log.d(TAG, "GET - ID: 1 - Success expected -> Got success");
            auxArray.add("1");
        }

        @Override
        public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) {
            super.onFailure(arg0, arg1, arg2, arg3);
            Log.d(TAG, "GET - ID: 1 - Success expected -> Got failure");
        }
    });
person dazito    schedule 09.04.2014
comment
Коя версия на клиента Restlet използвахте? Препоръчвам най-новата ни стабилна версия на Restlet 2.2.0, която директно разчита на HttpURLConnection. Винаги можете да го стартирате в Android AsyncTask. developer.android.com/reference/android/os/AsyncTask.html - person Jerome Louvel; 16.04.2014
comment
@JeromeLouvel Използвам Restlet 2.1. Видях нова стабилна версия (2.2) на Restlet за Android, но все още не съм направил превключването. - person dazito; 16.04.2014

Проследихте ли HTTP заявката с помощта на инструменти и дали заявката достига до вашия манипулатор, преди да изведе грешката?

person prstk    schedule 09.04.2014