我目前正在开发一个Android项目,我使用枚举来动态创建URL。
根据选择哪个RequestOperation
并传递给我的startRequest()
方法,将调用另一个API,因此对于映射,我的旧方法是通过switch case映射枚举值并将相应的url部分返回为字符串,如下所示:
public enum RequestOperation {
WORKERS,
ERRORS_COMPACT,
ERRORS_COMPLEX,
ERROR_TAKE_OVER,
SESSION_CHECK,
SESSION_LOGIN,
SESSION_LOGOUT;
public String parsingKey() {
switch (this) {
case WORKERS:
return "workers";
case ERRORS_COMPACT:
return "errors";
case ERRORS_COMPLEX:
return "errors";
case ERROR_TAKE_OVER:
return "take_over";
default:
return "";
}
}
public String apiURL(ArrayList<String> params) {
switch (this) {
case WORKERS:
return "schedule.m";
case ERRORS_COMPACT:
return "errors.m?mode=compact";
case ERRORS_COMPLEX:
return "errors.m?mode=complex";
case ERROR_TAKE_OVER:
return "assign_task.m?param0=" + params.get(0) + "¶m1=" + params.get(1);
case SESSION_CHECK:
return "desk.m?do=check¶m0=" + params.get(0);
case SESSION_LOGIN:
return "desk.m?do=login¶m0=" + params.get(0) + "¶m1=" + params.get(1) + "¶m2=" + params.get(2);
case SESSION_LOGOUT:
return "desk.m?do=logout¶m0=" + params.get(0);
default:
return "";
}
}
}
正如你所看到的,url字符串的编写是非常粗略的编码,我对此没有信心。要找到创建它的方法,我试图围绕枚举创建一个包装类:
public class RequestOperation {
public enum Type {
WORKERS("workers", "workers.m"),
ERRORS_COMPACT("errors", "errors.m?mode=compact"),
ERRORS_COMPLEX("errors", "errors.m?mode=complex"),
//here's where im stuck, cause the second string is not the complete url
ERROR_TAKE_OVER("take_over", "assign_task.m?param0="),
SESSION_CHECK("", "desk.m?do=check&dparam0="),
SESSION_LOGIN("", "desk.m?do=login¶m0="),
SESSION_LOGOUT("", "desk.m?do=logout¶m0=");
//maybe pass the params in here some how, and compose the url selectively
Type(String parsingKey, String applicationUrl) {
this.parsing_key = parsingKey;
this.application_url = applicationUrl;
}
//maybe move them out of the enum
private String parsing_key;
private String application_url;
//private ArrayList<String> url_params = new ArrayList<>();
}
private Type type;
//expect parameters from the creator here maybe
public RequestOperation(Type type) {
this.type = type;
}
public String parsingKey() {
return type.parsing_key;
}
public String application_url() {
return type.application_url;
}
}
现在我的问题是,我没有任何想法,如何通过params到RequestOperation
对象,以便application_url
正确组成。我的第一个想法是,重载Type
的构造函数,所以我可以传递多达3个字符串,这些字符串将填充在第一个展览中的间隙中。有没有办法做到这一点,这是一个好的做法吗?
我不会在枚举声明中使用像?param0=
这样的参数,而是在你的枚举中保留原始网址。
例如这个枚举常量:
ERROR_TAKE_OVER("take_over", "assign_task.m?param0=")
改成:
ERROR_TAKE_OVER("take_over", "assign_task.m")
而你的apiURL(String...)
看起来像这样:
public String apiURL(String... params) {
if(params.length == 0) return type.application_url;
return type.application_url
+ "?"
+ IntStream.range(0, params.length)
.mapToObj(i -> String.format("param%d=%s", i, params[i]))
.collect(Collectors.joining("&"));
}
并让webservlet处理可能的参数缺失。
例:
RequestOperation request = new RequestOperation(RequestOperation.Type.ERROR_TAKE_OVER);
System.out.println(request.apiURL()); //"assign_task.m"
System.out.println(request.apiURL("a")); //"assign_task.m?param0=a"
System.out.println(request.apiURL("a", "b", "c")); //"assign_task.m?param0=a¶m1=b¶m2=c"
这可能不是最好的解决方案,而只是一种解决方法。理想情况下,enum
应该存储常量值而不是动态值。在您的情况下,解决方法是使用MessageFormat#format()
。 application_url
中的enum
值将包含带占位符的字符串:
SESSION_LOGIN("", "desk.m?do=login¶m0={0}¶m1={1}")
注意使用{}
作为占位符。
现在创建一个方法,根据传递的参数形成URL:
public String getApiUrl(String... params) {
return MessageFormat.format(this.application_url, params);
}
请注意,这是一种非常粗暴的方式来执行您尝试实现的目标,因为它没有检查可以传递的参数是什么或有多少。