I have written a method to tokenize HTTP request paths such as /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));
}
}
}
And a method to tokenize the consumer of these paths such as /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;
}
}
}
The idea here is that there will be an implicit variable called id
with the value 23
. However, that isn't here nor there. How does my approach look? Can it be improved? Also: DELIM = '/'
.
This is more-or-less an exercise in writing a parser, which is why I didn't use String#split()
.
2 Answers 2
Your first compile
method can be replaced by a single call to String.split
.
Assuming the intended behavior for the second compile
method is such that "/foo/b[a]r/baz" will compile to {"foo", "?", "baz"}
, it can be replaced by a call to split
and then iterating over the result and replacing any string the includes square brackets with "?".
If the intended behavior is rather that it will compile to {"foo", "b", "?", "r", "baz"}
, you can first replace [anything]
by /?/
using String.replace
and then use String.split
.
Just as an exercise in making the code easier to read, I'd recommend better variable names. I can figure out what "wild" and "mark" are, but it should be immediately apparent to me so I don't have to spend time trying to figure out what they are.
Also, I'm assuming you are going to eventually handle URLs with "?" and such in them. You may want to consider checking for invalid characters in the URL so you know when you hit the end of the actual request path.
-
\$\begingroup\$ I have to disagree about the variable names, unless you can suggest better ones?
mark
is a perfectly valid in my opinion because it is marking a point in the string. I could changewild
toisWild
I suppose. As for handling question marks, no, the purpose for the paths with wildcards is to be parsed on the server when the web application starts up. I intend to annotate a method like this:@Get("/employees/[id]")
. I am just dealing with paths, not the query string. \$\endgroup\$Jeremy– Jeremy2011年01月20日 19:59:53 +00:00Commented Jan 20, 2011 at 19:59 -
\$\begingroup\$ Well, 'position' might make the intent clearer than 'mark' :) As for 'wild', a name including 'wildcard' might be easier to understand. \$\endgroup\$user185– user1852011年01月22日 17:20:46 +00:00Commented Jan 22, 2011 at 17:20
/
and an opening[
will be ignored. Is that intentional? \$\endgroup\$String#split()
wont suffice. \$\endgroup\$