使用Gson和接口类型 [英] Using Gson with Interface Types

查看:75
本文介绍了使用Gson和接口类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一些服务器代码,客户端以JSON的形式发送请求。我的问题是,有很多可能的请求,所有请求都有所不同,这些请求在小的实现细节上有所不同
因此我认为要使用一个Request接口,定义如下:

  public interface Request {
响应过程();
}

从那里开始,我在一个名为 LoginRequest 如下所示:

  public class LoginRequest implements Request {
private String type = 登录;
私人字符串用户名;
私人字符串密码;

public LoginRequest(String username,String password){
this.username = username;
this.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;
}

/ **
*此方法实际上运行登录过程,根据过程的结果返回
*适当的响应。
* /
@Override
public response(){
// TODO:验证用户 - 是否存在用户名/密码组合
// TODO:如果用户的详细信息是可以的,创建播放器并添加到可用播放器的列表
// TODO:返回一个响应,指示认证成功或失败
返回null;
}

@Override
public String toString(){
returnLoginRequest [type =+ type +,username =+ username
+,密码=+密码+];




$ b

为了使用JSON,我创建了一个 GsonBuilder 实例并注册一个 InstanceCreator ,如下所示:

  public class LoginRequestCreator实现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();
请求请求= parser.fromJson(completeInput,LoginRequest.class);
System.out.println(request);

,我可以得到预期的输出。

我想要做的事情是用类似于的请求替换 Request request = parser.fromJson(completeInput,LoginRequest.class); 请求请求= parser.fromJson(completeInput,Request.class); 但这样做不起作用,因为 Request 是一个接口。



我希望我的 Gson 根据收到的JSON返回适当类型的请求。



传递给服务器的JSON示例如下所示:

  {
type :LOGIN,
username:someuser,
password:somepass
}
Request
interface

解决方案

假设可能有不同的JSON请求sts你可能没有太大的不同,我建议一个不同的方法,在我看来更简单。



假设你有这3个不同的JSON请求: / p>

  {
type:LOGIN,
username:someuser,
密码:somepass
}
////////////////////////////////
{
type:SOMEREQUEST,
param1:someValue,
param2:someValue
}
/ ///////////////////////////////
{
type:OTHERREQUEST,
param3:someValue
}

Gson允许你有一个单一的class to wrap 所有可能的响应,如下所示:

  public class Request {
@SerializedName(type)
private String类型;
@SerializedName(用户名)
私人字符串用户名;
@SerializedName(password)
私人字符串密码;
@SerializedName(param1)
private String param1;
@SerializedName(param2)
private String param2;
@SerializedName(param3)
private String param3;
// getters& setters
}

通过使用注释 @SerializedName ,当Gson尝试解析JSON请求时,只要查看该类中的每个指定属性(如果JSON请求中有一个字段具有相同的名称)。如果不存在这样的字段,那么该类中的属性设置为 null



这样,您可以仅使用 Request 类来解析许多不同的JSON响应,如下所示:

  Gson gson = new Gson(); 
请求请求= gson.fromJson(jsonString,Request.class);

一旦将您的JSON请求解析到您的类中,您就可以从 wrap 类添加到具体的 XxxxRequest 对象中,如下所示:

  caseLOGIN:
LoginRequest req = new LoginRequest(request.getUsername(),request.getPassword());
休息;
caseSOMEREQUEST:
SomeRequest req = new SomeRequest(request.getParam1(),request.getParam2());
休息;
caseOTHERREQUEST:
OtherRequest req = new OtherRequest(request.getParam3());
休息;
}

请注意,如果您有许多不同的JSON请求,这种方法会变得更乏味而这些请求是彼此非常不同的,但即使如此,我认为这是一种很好且非常简单的方法......


I am working on some server code, where the client sends requests in form of JSON. My problem is, there are a number of possible requests, all varying in small implementation details. I therefore thought to use a Request interface, defined as:

public interface Request {
    Response process ( );
}

From there, I implemented the interface in a class named LoginRequest as shown:

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 + "]";
    }
}

To work with JSON, I created a GsonBuilder instance and registered an InstanceCreator as shown:

public class LoginRequestCreator implements InstanceCreator<LoginRequest> {
    @Override
    public LoginRequest createInstance(Type arg0) {
        return new LoginRequest("username", "password");
    }
}

which I then used as shown in the snippet below:

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);

and I get the expected output.

The thing I wish to do is replace the line Request request = parser.fromJson(completeInput, LoginRequest.class); with something similar to Request request = parser.fromJson(completeInput, Request.class); but doing that will not work, since Request is an interface.

I want my Gson to return the appropriate type of request depending on the received JSON.

An example of the JSON I passed to the server is shown below:

{
    "type":"LOGIN",
    "username":"someuser",
    "password":"somepass"
}

To reiterate, I am looking for a way to parse requests (In JSON) from clients and return objects of classes implementing the Request interface

解决方案

Assuming that the different possible JSON requests you may have are not extremely different to each other, I suggest a different approach, simpler in my opinion.

Let's say that you have these 3 different JSON requests:

{
    "type":"LOGIN",
    "username":"someuser",
    "password":"somepass"
}
////////////////////////////////
{
    "type":"SOMEREQUEST",
    "param1":"someValue",
    "param2":"someValue"
}
////////////////////////////////
{
    "type":"OTHERREQUEST",
    "param3":"someValue"
}

Gson allows you to have a single class to wrap all the possible responses, like this:

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
}

By using the annotation @SerializedName, when Gson try to parse the JSON request, it just look, for each named attribute in the class, if there's a field in the JSON request with the same name. If there's no such field, the attribute in the class is just set to null.

This way you can parse many different JSON responses using only your Request class, like this:

Gson gson = new Gson();
Request request = gson.fromJson(jsonString, Request.class);

Once you have your JSON request parsed into your class, you can transfer the data from the wrap class to a concrete XxxxRequest object, something like:

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;
}

Note that this approach gets a bit more tedious if you have many different JSON requests and those requests are very different to each other, but even so I think is a good and very simple approach...

这篇关于使用Gson和接口类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆