我正在处理一些服务器代码,其中客户端以JSON形式发送请求。我的问题是,有许多可能的请求,每个请求的实现细节都不尽相同。因此,我想使用一个Request接口,它定义为:
public interface Request { Response process ( ); }
从那里,我在名为LoginRequest如下的类中实现了接口:
LoginRequest
public class LoginRequest implements Request { private String type = "LOGIN"; private String username; private String password; public LoginRequest(String username, String password) { this.username = username; this.password = password; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } /** * This method is what actually runs the login process, returning an * appropriate response depending on the outcome of the process. */ @Override public Response process() { // TODO: Authenticate the user - Does username/password combo exist // TODO: If the user details are ok, create the Player and add to list of available players // TODO: Return a response indicating success or failure of the authentication return null; } @Override public String toString() { return "LoginRequest [type=" + type + ", username=" + username + ", password=" + password + "]"; } }
为了使用JSON,我创建了一个GsonBuilder实例并注册了一个InstanceCreator,如下所示:
GsonBuilder
InstanceCreator
public class LoginRequestCreator implements InstanceCreator<LoginRequest> { @Override public LoginRequest createInstance(Type arg0) { return new LoginRequest("username", "password"); } }
然后,如下面的代码片段所示,我使用了它:
GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(LoginRequest.class, new LoginRequestCreator()); Gson parser = builder.create(); Request request = parser.fromJson(completeInput, LoginRequest.class); System.out.println(request);
我得到了预期的输出。
我希望做的是用Request request = parser.fromJson(completeInput, LoginRequest.class);类似于以下内容的内容替换该行,Request request = parser.fromJson(completeInput, Request.class);但是这样做是行不通的,因为这Request是一个接口。
Request request = parser.fromJson(completeInput, LoginRequest.class);
Request request = parser.fromJson(completeInput, Request.class);
Request
我希望我Gson根据收到的JSON返回适当的请求类型。
Gson
我传递给服务器的JSON示例如下所示:
{ "type":"LOGIN", "username":"someuser", "password":"somepass" }
重申一下,我正在寻找一种方法来解析来自客户端的请求(在JSON中)并返回实现该Request接口的类的对象
假设您可能拥有的不同的JSON请求彼此之间并没有太大不同,我建议采用一种不同的方法,我认为这种方法更为简单。
假设您有以下3个不同的JSON请求:
{ "type":"LOGIN", "username":"someuser", "password":"somepass" } //////////////////////////////// { "type":"SOMEREQUEST", "param1":"someValue", "param2":"someValue" } //////////////////////////////// { "type":"OTHERREQUEST", "param3":"someValue" }
Gson允许您使用一个类来 包装 所有可能的响应,如下所示:
public class Request { @SerializedName("type") private String type; @SerializedName("username") private String username; @SerializedName("password") private String password; @SerializedName("param1") private String param1; @SerializedName("param2") private String param2; @SerializedName("param3") private String param3; //getters & setters }
通过使用批注@SerializedName,当Gson尝试解析JSON请求时,它会针对该类中的每个命名属性查找JSON请求中是否存在同名字段。如果没有此类字段,则将类中的属性设置为null。
@SerializedName
null
这样,您可以仅使用您的Request类来解析许多不同的JSON响应,如下所示:
Gson gson = new Gson(); Request request = gson.fromJson(jsonString, Request.class);
将JSON请求解析到您的类之后,就可以将数据从 wrap 类传输到具体XxxxRequest对象,例如:
XxxxRequest
switch (request.getType()) { case "LOGIN": LoginRequest req = new LoginRequest(request.getUsername(), request.getPassword()); break; case "SOMEREQUEST": SomeRequest req = new SomeRequest(request.getParam1(), request.getParam2()); break; case "OTHERREQUEST": OtherRequest req = new OtherRequest(request.getParam3()); break; }
请注意,如果您有许多不同的JSON请求并且这些请求彼此之间非常不同,则此方法会变得更加乏味,但是即使如此,我仍然认为这是一种很好且非常简单的方法…