Reputation: 9842
I am using gson to produce json of a collection of objects in Java (Some objects have other collections too). This json will be used to populate the web page for users with different clearance levels. Therefore the detail which users can see differs. Web page only shows what it needs to show however if I use the same json for two different pages then html source code will have more data than it should have. Is there a way to inform gson which variables in which class should be added to the json? As far as I search I could not find an easy way. Either I will produce json myself or clear extra data from the json which gson produced.
Upvotes: 0
Views: 545
Reputation: 48804
I need to use same classes for different clearance levels and get different json.
You are trying to use Gson to generate multiple different JSON outputs of the same objects in the same JVM, which is going to be difficult, both in Gson and any good serialization library, because their express goal is essentially the opposite of what you're looking for.
The right thing to do would be to instead represent these different clearance levels with different classes, and simply serialize those different classes with Gson as normal. This way you separate the security model from the serialization, letting you safely pass this information around.
/**
* Core data class, contains all information the application needs.
* Should never be serialized for display to any end user, no matter their level.
*/
public class GlobalData {
private final String username;
private final String private_data;
private final String secure_data;
}
/** Interface for all data display operations */
public interface DisplayData {
/** Returns a JSON representation of the data to be displayed */
public String toJson();
}
/**
* Class for safe display to an untrusted user, only holds onto public
* data anyone should see.
*/
public class UserDisplayData implements DisplayData {
private final String username;
public UserDisplayData(GlobalData gd) {
username = gd.username;
}
public String toJson() {
return gson.toJson(this);
}
}
/**
* Class for safe display to a trusted user, holds private information but
* does not display secure content (passwords, credit cards, etc.) that even
* admins should not see.
*/
public class AdminDisplayData implements DisplayData {
private final String username;
private final String private_data;
public AdminDisplayData(GlobalData gd) {
username = gd.username;
private_data = gd.private_data;
}
public String toJson() {
// these could be different Gson instances, for instance
// admin might want to see nulls, while users might not.
return gson.toJson(this);
}
}
Now you can sanitize and serialize your data as two separate steps, and use type safety to ensure your GlobalData
is never displayed.
public void getDisplayData(GlobalData gd, User user) {
if(user.isAdmin()) {
return new AdminDisplayData(gd);
} else {
return new UserDisplayData(gd);
}
}
public void showData(DisplayData data) {
String json = data.toJson();
// display json however you want
}
If you erroneously tried to call showData(gd)
you'd get a clear compilation error that you've done something wrong, and it's a quick fix to get the correct result by calling showData(getDisplayData(gd, user))
which safely and clearly does exactly what you want.
Upvotes: 1
Reputation: 1922
you can add a Expose annotations like this on the filed you don't want:
@Expose(serialize = false, deserialize = false)
private String address;
some more information here:
https://sites.google.com/site/gson/gson-user-guide#TOC-Gson-s-Expose
Upvotes: 0