我目前正在处理一个android项目,在这里我使用一个枚举来动态创建URL。
根据选择了哪个RequestOperation
并将其传递给我的startRequest()
方法,将调用另一个API,因此对于映射,我的旧方法是通过切换用例来映射枚举值,并返回相应的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;
}
}
现在我的问题是,我不知道如何将参数传递给RequestOperation
对象,以便application_url
正确地组成。我的第一个想法是,重载Type
的构造函数,因此我最多可以传递3个字符串,这些字符串将像第一个展览中那样填补空白。有什么方法可以解决这个问题吗?
答案 0 :(得分:2)
我不会在枚举声明中使用诸如?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"
答案 1 :(得分:0)
这可能不是最佳解决方案,而只是解决方法。理想情况下,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);
}
请注意,这是您尝试实现的非常粗略的方法,因为它无法检查可以传递哪些参数或传递多少参数。