I'm working on a small Java RESTful API and a client has asked for a certain object to have two different return options.
When a request is made to (as an example) /api/v1/products they want it to return just the "id" and "title" as opposed to the full object below.
When a request is then made to /api/v1/products/[productId] they want it to return the full object as well as any nested objects.
public class Product {
private int id;
private String title;
private String description;
private int weight;
private List<Price> prices;
}
Is it possible to dynamically create an object with only certain variables? They want it so that the other variables are never returned (for example in a JSON response they wouldn't want to see null values).
Am I right in thinking that the full object should be returned in the collection of products (/api/v1/products)?
Related
Is it possible to rename JSON output fields in an object an arbitrary number of times when outputting with Jackson?
I can use a one-time JsonProperty as shown here,
How to map JSON field names to different object field names?
But suppose I have a single class which is used in multiple outputs. In each output, I want to have the flexibility of defining which name(s) to change.
public class Study implements Serializable {
// Can vary as "id" / "studyId" depending on call
private int id;
// Can vary as "description" / "studyDescription" / "studyDesc" depending on call
private String description;
}
Or do I need to create new objects for each case?
Do refer: https://www.baeldung.com/json-multiple-fields-single-java-field
It's as simple as using #JsonAlias in combination with #JsonProperty annotation as below:
public class Study implements Serializable {
// Can vary as "id" / "studyId" depending on call
#JsonProperty("id")
#JsonAlias("studyId")
private int id;
// Can vary as "description" / "studyDescription" / "studyDesc" depending on call
private String description;
}
PS: Using #JsonProperty twice didn't work :D
I want to write a generic function that accepts two objects of same entity class and compares the fields that are different and returns List of all the changes made to particular fields along with time.
One among the many entity classes would be say Member as follows
public class Member {
String firstName;
String lastName;
String driverLicenseNumber;
Integer age;
LocalDateTime timestamp;
}
In the DB, I have a table called member_audit that gets populated with old data whenever there is a change in member table using triggers (Similarly for other entities).
The List of resource for each of the entity I would be returning is something like
public class MemberAuditsResource {
private String field;
private LocalDateTime on;
private String changeType;
private String oldValue;
private String newValue;
}
I can only think of writing a function for each entity separately like this
private List<MembeAuditsResource> memberCompare(Member obj1, Member obj2) {
//Compare every field in both the objects using if else and populate the resource.
}
And then calling the above function to compare every pair of record in the entity_audit table.
The code would be very large to compare every field and multiplied by different entities.
Is there a better and efficient way?
If you extend the ideas to compare the object graph , it is not a trivial problem. So, the efficient way is not to re-inventing the wheel but use an existing library such as JaVers :
Member oldMember = new Member("foo" ,"chan" ,"AB12" , 21 ,LocalDateTime.now());
Member newMember = new Member("bar" ,"chan" ,"AB12" , 22 ,LocalDateTime.now());
Diff diff = javers.compare(oldMember, newMember);
for(Change change: diff.getChanges()) {
System.out.println(change);
}
Then , you can get something like:
ValueChange{ 'firstName' changed from 'foo' to 'bar' }
ValueChange{ 'age' changed from '21' to '22' }
Convert both object to a Map using JSON objectMapper.convertValue method. Then you can easily compare the keys/values of the two maps and create a list of differences.
This topic is a little bit more complicated then in a title.
Let's assume that we want to model an entity. This is something like KYC informations (name,surname, address etc). I could model this in simple way in one class like:
public class KYCInfo {
private KYCInfoType type;
private String firstName;
private String lastName;
private Address personalAddress;
private Address buisnessAddress;
private String country;
private String state;
private LocalDate dateOfBirth;
private String personalIdNumber;
}
As you see in code above, this KYC can be of different type. Actually two values can be in that type - buisness and individual. For business, buisnessAddress field is required, for individual personalIdNumber is required. Additionaly some of this fields will be required depending on country field. State field is for US but not for European countries. Placing all of this fields in one class seems to be inappropriate - every instance, depending on field would have a lot of null values. I could create separate classes for BuisnessKYCInfo and IndividualKYCInfo for example. But then I would have some duplications in fields (lets say that firstName,lastName and some other fields are the same for both classes). I could create some abstraction with common fields. Like :
public abstract class KYCInfo {
private String firstName;
private String lastName;
}
Now imagine that this is a simple DTO class and in some moment i process it somehow in a method processKYCInfo(). When I have two classes BuisnessKYCInfoandIndividualKYCInfothen I would need to have two methods
``processKYCInfo(BuisnessKYCInfo kycInfo) and processKYCInfo(IndividualKYCInfo kycInfo). This method will do the same operation, but will collect info from different fields. Now imagine, that you have more type than individual or buissness. Or as i wrote before, additional 'type' comes in like country. Now I would need to have 25 countries, some of them have fields specific only for that country. With the same approach like before I would have 25 methods doing almost the same. This also seems to be inappropriate. What other option do I have to model this ? Maybe some data structure, maybe some Map ? What is best approach of doing this ? How can I do it in more generic way ?
Here is my approach:
Following is the data structure I'll use:-
public class KYCInfo {
private KYCInfoType type;
private Map<String, String> name;
private Map<String, String> address;
private String country;
private String state;
private LocalDate dateOfBirth;
private String personalIdNumber;
public KYCInfo(){
name = new HashMap<>();
address = new HashMap<>();
}
So what is the advantage of this approach:-
Instead of creating multiple same type of attributes, create a family. e.g. name will be the family for 'firstName', 'middleName', 'lastName'. The pair will be like <'firstName','Bob'> ,<'lastName','Marley'> etc. In this way you can have either of them or all of them.
Similarly for other attributes like address. The pair can be like <'personalAddress','some value'> , <'buisnessAddress','some value'>
Each record can have their own categories for a family.
I'm a java beginner and have a question concerning how to best structure a cooking program.
I have a class called Ingredient, this class currently looks like this:
public class Ingredient {
private String identifier;
private double ingredientFactor;
private String titleInterface;
public Ingredient(String identifier, double ingredientFactor,String titleInterface) {
this.identifier = identifier;
this.ingredientFactor = ingredientFactor;
this.titleInterface = titleInterface;
}
I want to initialize several objects (about 40) with certain values as instance variables and save them in a Map, for example
Map<String, Ingredient> allIngredients = new HashMap<String, Ingredient>();
allIngredients.put("Almonds (ground)", new Ingredient("Almonds (ground)", 0.7185, "Almonds (ground)");
Later on I want to retrieve all these objects in the form of a Map/HashMap in a different class.
I'm not sure how to proceed best, initialize all these objects in the Ingredient class itself or provide a method that initializes it or would it be better to create an super class (AllIngredients or something like that?) that has a Map with Ingredients as instance variables?
Happy for any suggestions, thanks in advance :)
Please do not initialize all these objects in the Ingredient class itself. That would be a bad practice for oops.
Just think your class is a template from which you create copies(objects) with different values for attributes. In real world if your class represent model for a toy plane which you would use to create multiple toy planes but each bearing different name and color then think how such a system would be designed. You will have a model(class). Then a system(another class) for getting required color and name from different selection of colors and names present(like in database,files,property file ) etc.
Regarding your situation .
If predetermined values store the values in a text file,properties file,database,constants in class etc depending on the sensitivity of the data.
Create Ingredient class with constructors
Create a class which will have methods to initialize Ingredient class using predetermined values,update the values if required,save the values to text file -database etc and in your case return as map .
Also check the links below
http://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm
http://www.oracle.com/technetwork/java/dataaccessobject-138824.html
Sounds to me like you are looking for a static Map.
public class Ingredient {
private String identifier;
private double ingredientFactor;
private String titleInterface;
public Ingredient(String identifier, double ingredientFactor, String titleInterface) {
this.identifier = identifier;
this.ingredientFactor = ingredientFactor;
this.titleInterface = titleInterface;
}
static Map<String, Ingredient> allIngredients = new HashMap<String, Ingredient>();
static {
// Build my main set.
allIngredients.put("Almonds (ground)", new Ingredient("Almonds (ground)", 0.7185, "Almonds (ground)"));
}
}
Hope you don't mind I'm asking a newbie question about the use of iterator for a arrayList / List.
I have a Building Class with a few data members:
public Building() {
private String buildingName;
private String buildingType;
private double width;
private double length;
private String managerName;
....
}
I've already set toString() as follow to access the name String and I'm NOT allowed to change toString to return a different data member.
public String toString() {
return buildingName;
}
I've created a bunch of building objects in the Building class by loading a building.xml file, and I've used iterator to create an array/list of buildingNames to be viewed in a swing ComboBox (but let's ignore those swing component below and focus on the just the logics):
// Create building combo box model.
buildingComboBoxModel = new DefaultComboBoxModel<Building>();
buildingsCache = new ArrayList<Building>(buildings);
Iterator<Building> i = buildingsCache.iterator();
while (i.hasNext()) buildingComboBoxModel.addElement(i.next());
// Create building list.
buildingComboBox = new JComboBoxMW<Building>(buildingComboBoxModel);
buildingComboBox.addActionListener(this);
buildingComboBox.setMaximumRowCount(10);
buildingSelectPanel.add(buildingComboBox);
How many ways do can you think of and how in putting together an list of buildingType using iterator without significant code changes?
If I need to modify some of the buildingType Strings in some situations by adding a String to it,
say in one building,
String buildingName = "Adam's Place";
String buildingType = "Greenhouse";
[post edit]
e.g. I need to change buildingType to "Greenhouse Type 1" for "Adam's Place" and change another building's buildingType to "Greenhouse Type 2"
Can it be done using iterator and how?
If not, other ways are welcome
Thanks in advance!
There is no special way for handling objects read from an iterator. If the only changes needed are just setting different values to the members of the Building class, this can be done the standard way, i.e. by adding member setter functions.
For example, to modify the buildingType at any time, a setBuildingType() method is needed:
public class Building {
private String buildingName;
private String buildingType;
private double width;
private double length;
private String managerName;
....
public void setBuildingType(String buildingType) {
this.buildingType = buildingType;
}
}
Given the above, the iterator-based code can be modified as follows:
Iterator<Building> i = buildingsCache.iterator();
while (i.hasNext()) {
Building b = i.next();
b.setBuildingType("Whatever type");
buildingComboBoxModel.addElement(b);
}