HTTP-Anforderungspfad-Parser

761
Jeremy Heiler

Ich habe ein Verfahren zum tokenize HTTP - Anforderungspfaden geschrieben, wie /employee/23/edit:

protected void compile(String path){
    int mark=0;
    for(int i=0; i<path.length(); ++i){
        if(path.charAt(i)==DELIM){
            if(mark!=i)
                tokens.add(path.substring(mark,i));
            mark=i+1;
        }
        else if(path.length()==i+1){
            tokens.add(path.substring(mark,i+1));
        }
    }
}

Und eine Methode, um den Konsumenten dieser Pfade zu kennzeichnen /employee/[id]/edit:

protected void compile(String path){
    int mark=0;
    boolean wild=false;
    for(int i=0; i<path.length(); ++i){
        if(!wild){
            if(path.charAt(i)==DELIM){
                if(mark!=i)
                    tokens.add(path.substring(mark,i));
                mark=i+1;
            }
            else if(path.length()==i+1){
                tokens.add(path.substring(mark,i+1));
            }
            else if(path.charAt(i)=='['){
                wild=true;
            }
        }
        else if(path.charAt(i)==']'){
            tokens.add("?");
            wild=false;
            mark=i+1;
        }
    }
}

Die Idee hier ist, dass es eine implizite Variable gibt, die idmit dem Wert aufgerufen wird 23. Das ist jedoch weder hier noch dort. Wie sieht mein Ansatz aus? Kann es verbessert werden? Auch: DELIM = '/'.

Dies ist mehr oder weniger eine Übung, um einen Parser zu schreiben, weshalb ich ihn nicht verwendet habe String#split().

Antworten
12
Funktioniert String.split () nicht besser für die Tokenisierung eines Strings (http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#split(java.lang.String )) Steven vor 9 Jahren 1
Es sieht so aus, als würde alles zwischen dem letzten `/` und einer öffnenden [] ignoriert. Ist das absichtlich? sepp2k vor 9 Jahren 1
@ shambleh: Dies war mehr oder weniger eine Übung, um einen einfachen Parser zu schreiben. Ich rechne damit, dass es im Laufe der Zeit immer komplizierter wird, wenn String # split () nicht ausreicht. Jeremy Heiler vor 9 Jahren 0
Es erscheint mir auch seltsam, dass Sie nur die Namen der Variablen wie diese verwerfen. Ohne zu wissen, wie Sie das Ergebnis der Kompilierungsmethode verwenden, ist es schwer zu sagen, ob es schlecht ist oder nicht. sepp2k vor 9 Jahren 0
@ sepp2k: Um weniger Code zu veröffentlichen, wird nicht mehr als der Parsing-Aspekt angezeigt. Ich habe den Teil herausgenommen, auf den Sie sich beziehen. Jeremy Heiler vor 9 Jahren 0

2 Antworten auf die Frage

11
sepp2k

Ihre erste compileMethode kann durch einen einzelnen Anruf an ersetzt werden String.split.

Angenommen, das beabsichtigte Verhalten für die zweite compileMethode ist so, dass "/ foo / b [a] r / baz" kompiliert {"foo", "?", "baz"}wird. Sie kann durch einen Aufruf an splitdas Ergebnis ersetzt werden, das dann durchläuft und alle Zeichenfolgen ersetzt, die die eckigen Klammern enthalten "?"

Wenn das gewünschte Verhalten ist eher, dass es zu kompilieren {"foo", "b", "?", "r", "baz"}, können Sie zunächst ersetzen [anything]durch /?/Verwendung String.replaceund dann verwenden String.split.

4
Mark Loeser

Als Übung, um den Code lesbarer zu machen, würde ich bessere Variablennamen empfehlen. Ich kann herausfinden, was "wild" und "mark" sind, aber es sollte mir sofort klar sein, so dass ich keine Zeit damit verbringen muss, herauszufinden, was sie sind.

Außerdem gehe ich davon aus, dass Sie URLs mit "?" Behandeln werden. und so in ihnen. Sie sollten in Erwägung ziehen, nach ungültigen Zeichen in der URL zu suchen, um zu erfahren, wann Sie am Ende des tatsächlichen Anforderungspfads angekommen sind.

Ich muss den Variablennamen nicht zustimmen, es sei denn, Sie können bessere vorschlagen. "mark" ist meiner Meinung nach perfekt, weil es einen Punkt in der Zeichenfolge markiert. Ich könnte "wild" in "isWild" ändern, denke ich. Was die Behandlung von Fragezeichen angeht, nein, der Zweck der Pfade mit Platzhaltern besteht darin, auf dem Server zu analysieren, wenn die Webanwendung gestartet wird. Ich beabsichtige, eine Methode wie folgt zu kommentieren: `@Get (" / employee / [id] ")`. Ich beschäftige mich nur mit Pfaden, nicht mit der Abfragezeichenfolge. Jeremy Heiler vor 9 Jahren 0
Nun, "Position" macht die Absicht vielleicht klarer als "Markierung" :) Was "Wild" angeht, ist ein Name mit "Wildcard" möglicherweise einfacher zu verstehen. Eric Bréchemier vor 9 Jahren 0