Java 如何围绕带有动态字段的枚举创建包装类

Java 如何围绕带有动态字段的枚举创建包装类,java,android,enums,constructor,wrapper,Java,Android,Enums,Constructor,Wrapper,我目前正在从事一个android项目,在这个项目中,我使用枚举来动态创建URL 根据选择的RequestOperation并将其传递给我的startRequest()方法,将调用另一个API,因此对于映射,我的旧方法是通过开关大小写映射枚举值,并以字符串形式返回相应的url部分,如下所示: public enum RequestOperation { WORKERS, ERRORS_COMPACT, ERRORS_COMPLEX, ERROR_TAKE_OVER

我目前正在从事一个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) + "&param1=" + params.get(1);
            case SESSION_CHECK:
                return "desk.m?do=check&param0=" + params.get(0);
            case SESSION_LOGIN:
                return "desk.m?do=login&param0=" + params.get(0) + "&param1=" + params.get(1) + "&param2=" + params.get(2);
            case SESSION_LOGOUT:
                return "desk.m?do=logout&param0=" + params.get(0);
            default:
                return "";
        }
    }

}
公共枚举请求操作{
工人,
错误与紧凑,
错误与复杂,
错误(接管),,
会话检查,
会话\u登录,
会话退出;
公共字符串parsingKey(){
开关(本){
个案工作者:
返回“工人”;
案例错误\u紧凑:
返回“错误”;
案例错误与复杂性:
返回“错误”;
案例错误\u接管\u:
返回“接管”;
违约:
返回“”;
}
}
公共字符串APIRL(ArrayList参数){
开关(本){
个案工作者:
返回“schedule.m”;
案例错误\u紧凑:
返回“errors.m?mode=compact”;
案例错误与复杂性:
返回“errors.m?mode=complex”;
案例错误\u接管\u:
返回“assign_task.m?param0=“+params.get(0)+”和param1=“+params.get(1);
案例会话检查:
return“desk.m?do=check¶m0=“+params.get(0)”;
案例会话\u登录:
return“desk.m?do=login¶m0=“+params.get(0)+”¶m1=“+params.get(1)+”¶m2=“+params.get(2);
案例会话\u注销:
return“desk.m?do=logout¶m0=“+params.get(0)”;
违约:
返回“”;
}
}
}
正如您所看到的,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&param0="),
        SESSION_LOGOUT("", "desk.m?do=logout&param0=");

        //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;
    }
}
公共类请求操作{
公共枚举类型{
工人(“工人”、“工人m”),
错误压缩(“错误”,“错误.m?模式=压缩”),
错误复杂(“错误”,“错误.m?模式=复杂”),
//这里是我卡住的地方,因为第二个字符串不是完整的url
错误接管(“接管”,“分配任务.m?param0=”),
会话检查(“,”desk.m?do=CHECK&dparam0=“),
SESSION_LOGIN(“,”desk.m?do=LOGIN¶m0=“),
会话_注销(“,”desk.m?do=LOGOUT¶m0=“);
//也许在这里传递一些参数,然后有选择地组合url
类型(字符串parsingKey、字符串应用程序URL){
this.parsing_key=parsingKey;
this.application\u url=applicationUrl;
}
//也许把它们移出枚举
私钥;
私有字符串应用程序的url;
//私有ArrayList url_params=新ArrayList();
}
私有类型;
//这里可能需要创建者提供的参数
公共请求操作(类型){
this.type=type;
}
公共字符串parsingKey(){
返回type.u键;
}
公共字符串应用程序_url(){
返回type.application\u url;
}
}

现在我的问题是,我不知道如何将这些参数传递给
RequestOperation
对象,以便
应用程序url
正确组合。我的第一个想法是,重载
类型的构造函数
,这样我就可以传递最多3个字符串来填补空白,如第一个展示中所示。有什么方法可以做到这一点吗?

这可能不是最好的解决方案,但只是一种解决办法。理想情况下,
enum
应该存储常量值,而不是动态值。在您的情况下,解决方法是使用
MessageFormat#format()
enum
中的
应用程序url
值将包含带有占位符的字符串,如下所示:

SESSION_LOGIN("", "desk.m?do=login&param0={0}&param1={1}")
请注意使用
{}
作为占位符

现在创建一个基于传递的参数形成URL的方法,如下所示:

public String getApiUrl(String... params) {
    return MessageFormat.format(this.application_url, params);
}

请注意,这是一种非常粗糙的方法,无法检查可以传递哪些参数或多少参数。我不会在枚举声明中使用
?param0=
之类的参数,而是将原始URL保留在枚举中

例如,此枚举常量:

 ERROR_TAKE_OVER("take_over", "assign_task.m?param0=")
改为:

ERROR_TAKE_OVER("take_over", "assign_task.m")
您的
apirl(字符串…
可能如下所示:

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&param1=b&param2=c"

将字段添加到枚举中不需要包装器,您可以将这些字段添加到枚举本身。此处没有动态字段。好的,我如何才能正确传递所需的参数,以便正确组合url?-将编辑我的帖子,使问题更详细clear@procra您不应该编辑或动态设置枚举的值。这就是重点。它们是(应该是)预定义的是的,这就是为什么我从纯枚举转移到包装器,它可能会保存属性,这些属性部分由枚举类型预设,在可能的情况下。这听起来像是一种结构良好的方法,我会尝试一下