0

I have a client (java) that send some json data to my server (c++). After this my server respond with some informations depending the operation made my java client. For now its works.

Example body request:
{
   "userEmail": "email@email.com",
   "userPassword": "12345678"
}

And the server, receive the email and password and do the operations and send back a response.

But now i need to change my java client to send the request like this:

{
  "userInformation":{
        "userEmail": "email@email.com",
        "userPassword": "12345678"
  }

}

This request can be use to do the login. This is a very complex architecture so i cannot copy all code, but in login class i used the gson (Note i only work in c++ server, i dont work in client and its impossible to contact the guy that made the java client to ask him about this doubts)

Java client - login class

public final String userEmail;
public final String userPassword;


public LoginRequestArgs( String userEmail, String userPassword)
{
    this.userEmail = userEmail;
    this.userPassword = userPassword;       
}

public static LoginRequestArgs fromStringJson(String data)
{
    try
    {
        Gson gson = new Gson();
        return gson.fromJson(data, LoginRequestArgs.class);
    }
    catch(Exception e)
    {
        return null;
    }
}

public static LoginRequestArgs fromBytesJson(byte[] data)
{
    if (data == null) return null;
    try 
    {
        String str = new String(data, "utf-8");
        return fromStringJson(str); 
    }
    catch (Exception e) 
    {
        return null;
    }
}


@Override
public String toJsonString()
{
    try
    {
        Gson gson = new Gson();
        return gson.toJson(this);
    }
    catch(Exception e)
    {
        return null;
    }
}

@Override
public byte[] toJsonBytes()
{
    try 
    {
        return this.toJsonString().getBytes("utf-8");
    }
    catch (Exception e)
    {
        return null;
    }
}

I have other class that connect to my server and send the request. This class call the login function (the request is a SerializableJSON variable) and place this request to my server request = LoginRequestArgs.fromStringJson(args.httpEntity);

(for tests i use one rest client chrome extension)

I know that can be some hard to understand but its not easy to explain all things. I try to explain the essencial.

real problem: i cannot adapt the java client to send the email and password that are inside "userInformation". Someone can help me please? Thanks

EDIT (OTHER BODY REQUEST EXAMPLE):

{
    "userInformation": {
        "otherSection": {
            "key1": "value1",
            "key2": "value2"
        }
    }
}

EDIT 2 (authentication method):

{
    "authenticationMethod": {
        "sessionId": {
            "email": "email@email.com",
            "password": "pass123"
        }
    },
    "userInformation": {
        "userId": "user",
        "userPassword": "user123"
    }
}

EDIT 3 (TOKEN):

{
    "authenticationMethod": {
        "token": {
            "token": "HDI393UDDNDMAY4758SAD"
        }
    },
    "userInformation": {
        "userId": "user",
        "userPassword": "user123"
    }
}

EDIT 4:

{
  "sessionId":{
    "email":"email@email.com",
    "password":"dasdas"

  },
  "userInformation":{
        "userId": "userId1",
        "userPassword": "12345678"
  }

}

I already send this json to my c++ server and its work and my decode session id working too, its not problem for me work on c++. But i need to send sessionId (or token) but inside "AuthenticationMethod", its only the thing i need to implement now. Note the "userInformation" its like and example it can be for example "bookInformation", "carInformation" , depending the request type, i send different data with different keys/values inside.. but the authentication method (session id or token) it is always mandatory to use in all request.

To work like i show to you i implement this:

public class SessionId {

    public String email;
    public String password;

    public SessionId(String email, String password)
    {
        this.email = email;
        this.password = password;
    }

}

And inside the construct of my class (can be for example one class like LoginRequestArgs, the login cass) i call the super:

public UserInfo userInformation;
public SessionId sessionId;

public LoginRequestArgs(String email, String password,String userEmail, String userPassword)
    {   
        super(email,password);
        userInformation = new UserInfo(userEmail, userPassword);
    }


static class UserInfo {
        public String userId;
        public String userPassword;

        public UserInfo(String userEmail, String userPassword) {
            this.userId = userEmail;
            this.userPassword = userPassword;
        }
    }

So for now, i only need to add "authenticationMethod" before session id or token (i believe the way to do this its the same for both)

**** EDIT 5 ********

login.java

public class LoginRequestArgs implements SerializableJSON  {

    public UserInfo userInformation;
    public AuthenticationMethod authenticationMethod;

    public LoginRequestArgs(String email, String password,String userId, String userPassword)
    {   
        AuthenticationMethod auth = new SessionId(email, password);
        setAuth(auth);
        userInformation = new UserInfo(userId, userPassword);
    }

    public void setAuth(AuthenticationMethod authenticationMethod){
            this.authenticationMethod = authenticationMethod;
    }

    static class UserInfo {
        public String userId;
        public String userPassword;

        public UserInfo(String userEmail, String userPassword) {
            this.userId = userEmail;
            this.userPassword = userPassword;
        }
    }

SessionId.java

public class SessionId extends AuthenticationMethod {

    Session sessionId;

     public SessionId(String email, String password)
     {
         this.sessionId = new Session(email,password);

     }

     static class Session{
         String email;
         String password;

         public Session(String email, String password)
         {
             this.email = email;
             this.password = password;
         }

     }
}

AuthenticationMethod.java

public class AuthenticationMethod {


}
Pik93
  • 49
  • 1
  • 2
  • 12

1 Answers1

1

You'll need to change the LoginRequestArgs class to look something like this:

public class LoginRequestArgs {

    public UserInfo userInformation;

    public LoginRequestArgs(String userEmail, String userPassword) {
        userInformation = new UserInfo(userEmail, userPassword);
    }

    static class UserInfo {
        public String userEmail;
        public String userPassword;

        public UserInfo(String userEmail, String userPassword) {
            this.userEmail = userEmail;
            this.userPassword = userPassword;
        }
    }

    public static LoginRequestArgs fromStringJson(String data) {
        try {
            Gson gson = new Gson();
            return gson.fromJson(data, LoginRequestArgs.class);
        } catch (Exception e) {
            return null;
        }
    }

    public static LoginRequestArgs fromBytesJson(byte[] data) {
        if (data == null)
            return null;
        try {
            String str = new String(data, "utf-8");
            return fromStringJson(str);
        } catch (Exception e) {
            return null;
        }
    }

}

and here is how you can access the email and password:

loginRequestArgsInstance.userInformation.userEmail;
loginRequestArgsInstance.userInformation.userPassword;

You should probably add some getters and setters to this class or at least make sure that userInformation is not null.

There are multiple ways of including the session details into the JSON. One way will be to modify your java classes. Something like this:

Req.java

public class Req{
    String data1;
    String data2;
    Auth authenticationMethod;
    ....
    public void setAuth(Auth authenticationMethod){
        this.authenticationMethod = authenticationMethod;
    }
}

Auth.java

public class Auth{
   ....
}

AuthToken.java

public class AuthToken extends Auth {

    Token token;

    public AuthToken(String token) {
        this.token = new Token(token);
    }

    static class Token {
        String token;

        public Token(String token) {
            this.token = token;
        }

    }
}

AuthUserInfo.java

public class AuthUserInfo extends Auth {

    UserInfo sessionId;

    public AuthUserInfo(String email, String password) {
        this.sessionId = new UserInfo(email, password);
    }

    static class UserInfo {
        String email;
        String password;

        public UserInfo(String email, String password) {
            this.email = email;
            this.password = password;
        }
    }
}

And here is how you can use these class':

Req req = new Req(...);
Auth auth = new AuthToken(...);// OR: new AuthUserInfo(...);
req.setAuth(auth);
String json = new Gson().toJson(req);

Another way will be to add new properties to the JSON after you create it. You can see an example of how you could do that here

Community
  • 1
  • 1
Titus
  • 22,031
  • 1
  • 23
  • 33
  • Thanks a lot for the help. Its a good starting point for me. Probably its not work because i need to study more my java client because it's have a lot of class. But thanks a lot for the answer, because i'm searching a starting point ;) – Pik93 Apr 05 '17 at 10:55
  • I try you solution and its works :) Thanks a lot :) after your solution i ony need to adapt my json parse on c++ to get content inside userInformation but its easy for me hehe – Pik93 Apr 05 '17 at 12:35
  • @Pik93 I'm glad I could help. Good luck. – Titus Apr 05 '17 at 15:18
  • Hi again.. If i have now my body like this, how to implement in java? More static class? { "userInformation": { "otherSection": { "key1": "value1", "key2": "value2" } } } – Pik93 Apr 06 '17 at 07:59
  • @Pik93 Yes, you'll have to create a new class that has the fields `key1` and `key2` and add a variable of that type to the `LoginRequestArgs` class. Is not necessary to define the `class` as a `static class` inside `LoginRequestArgs` you can create a separate file for it. – Titus Apr 06 '17 at 09:27
  • Ok, i understand i think. Thanks again ;) – Pik93 Apr 06 '17 at 10:01
  • Hi, sorry to ask you again. But i'm not a specialist in java, i work more with c++. So in every body request i need to use some authentication method (sessionId or token) (see the original post to see the example for the session id) My doubt is.. how to implement a class struct to the authentication method, because we are the same for all request, in some request i use session id, in other i use token..so i think its better to design some class struct to sessionId and token and call this struct class on my request class, login for example and others) – Pik93 Apr 06 '17 at 10:43
  • @Pik93 I'm not sure I understand exactly what you're trying to do but if you want to add the same JSON structure to every JSON you could create a class `SessionInfo` with a couple of fields `String token;...` and make all other classes extend this one `class LoginRequestArgs extends SessionInfo{ public LoginRequestArgs(String token ....){super(token);}}` or an easier way will be to fallow this example http://stackoverflow.com/a/13025252/1552587 – Titus Apr 06 '17 at 11:25
  • Thanks again. I try you solution and its works :) But now i have 2 problem: because i send "sessionId" and "userInformation", but i want by sessionId inside the "authenticationMethod" (like i post on examples).. the other problem is: it's possible one java class extends from two class? because i have 2 different authentication method, (sessionId or token) and some request can only use sessionId or token but others requests can be use one of two and in this cases, what is the best solution? THANKS A LOT FOR THE HELP, you are the best! :D – Pik93 Apr 06 '17 at 12:44
  • @Pik93 I've edited my answer to address all that. This will work only for serializing objects, if you want to deserialize this kind of object, that is a bit more complicated. – Titus Apr 06 '17 at 12:57
  • thanks. See my Edit 4, i believe now you can understand what i need :) – Pik93 Apr 06 '17 at 13:18
  • @Pik93 The example I've provided should work. All you need to do is to add a variable of type `Auth` to all the classes that you create JSONs from and then set this variable to a `AuthToken` or `AuthUserInfo` instance. In my example `Req` can be any class. – Titus Apr 06 '17 at 15:18
  • @Pik93 What I've tried to illustrate in my example is that you can abstract the concept of authentication. I've did that by creating a class `Auth` which can be added to any class that needs authentication and then created other classes which extend `Auth` so that I can account for multiple types of authentication. I'm not that good at explaining all this, you should try to learn more about how OOP works in Java. – Titus Apr 06 '17 at 15:22
  • Thanks ;) I try to implement you example buts its not work. I have some doubts. The auth.java -> What things this class must have inside? Constructor, parameters, etc The req.java -> What is the paper of this class? Only to set the "authenticationMethod" to java? I dont understand what you mean wen put string data 1, string data 2.. and about the req constructor? – Pik93 Apr 06 '17 at 15:27
  • @Pik93 The `Auth` class can be empty, you can declare it as `public abstract class Auth`. `Req` is just an example is a replacement for you classes, `Req` can be "bookInformation", "carInformation", etc. – Titus Apr 06 '17 at 15:29
  • @Pik93 The idea is to add a `Auth authenticationMethod` variable to all the classes that need a `authenticationMethod:{...}` structure and to set this variable to a `AuthToken` or `AuthUserInfo` instance depending on the method that should be used. – Titus Apr 06 '17 at 15:31
  • I put an edit 5, with my new code following your example. My c++ server receive the "authenticationMethod" but the "SessionId" its arrive to my c++ serve null – Pik93 Apr 06 '17 at 15:48
  • @Pik93 The JSON won't have a `Session` property but it should have a `{authenticationMethod:{sessionId:{email:...,password:....}}}` structure. – Titus Apr 06 '17 at 15:55
  • Yes its true, but what is the problem in my java code? In my c++ server i go to the "authenticationMethod", get the "sessionId" and inside "sessionId" i'm trying to get the email and password (i think that is the best way to do.. i think i cannot get email and password directly without passing by "authenticationMethod" and "sessionId" – Pik93 Apr 06 '17 at 16:01
  • Hi again. Do you remember this question? I think i need your help again about the same question @Titus – Pik93 Jun 26 '17 at 10:23
  • @Pik93 Yes I remember it and I'm not sure I was that helpful. You should probably create a new question, that will increase you chances of solving your problem and solving it sooner. You can add a comment here with the link to the new question, I will take a look and if I know the solution I will add an answer. – Titus Jun 26 '17 at 14:01
  • I have the following json to send by my java client: { "nodes": { "1317055040393017962": { "userAuthentication": { "userEmail": "rr@rr.com", "userPassword": "rr123" }, "objects": { "object": "objectValue" } } } } – Pik93 Jun 26 '17 at 15:52
  • But i hav a problem, i never know oh many elements i have inside my nodes json object. In this case i only have one ( the 1317055040393017962), but i can have a lot of more (the 1317055040393017962, 999984238824842824, 6914748489484184, etc, etc). I try to find a solution to send this in json format but i cannot found anything – Pik93 Jun 26 '17 at 15:54
  • You can copy the json and past here ( https://jsonlint.com/ ) to see better the json – Pik93 Jun 26 '17 at 15:55
  • Inside each nodes the authenticationMethod can be diferent and inside object i can have a lot of object, 1,2,3,50,60, etc... Its a JSON fully dynamic – Pik93 Jun 26 '17 at 15:58
  • @Pik93 You can construct multiple, separated JSONs and merge them into a root JSON. [THIS](https://stackoverflow.com/a/36688699/1552587) should give you an idea of what I'm talking about – Titus Jun 26 '17 at 19:03
  • Yes, i think i understand the idea. Thanks :) – Pik93 Jun 27 '17 at 07:21
  • Its not possible to convert all body json regardless of the json fields? I'm loocking for this and i never know the content of my json body. The nodes object can have a dynamic number of items, and inside each item the authentication method can be different (user authentication, token authentication etc) and the objects fields its dynamic too. We have a lots of objects and i never now the content, i only now that have a key/value strings and the name of key it can be dynamic too because it is a name of different objects. – Pik93 Jun 27 '17 at 08:36
  • The validation of json i do in my c++ server (parse json, check if exits the nodes objects, inside node objects i loop the childs, i for each child i get the authentication and the objects, and inside objects i get each key/value.. this part in my c++ server its working because i test with json string in c++ very similar to final json body). – Pik93 Jun 27 '17 at 08:38
  • But in my java client i need to do something to send all body, because if i dont do anything in my java cliente like i do for the others commands (with static class to put userInformation for example, but in this cases i already know the expected content of json).. if i dont do this i send the request body my c++ receive and empty json.. If you dont understand please said to me.. i'm a little crazy because i dont found any solution and i dont understand how to do hehe :D thanks – Pik93 Jun 27 '17 at 08:40