I never faced a requirement like that and I am pretty confused how can I implement that.
Lets consider the following Beans:
Company{
String companyName;
String companyId;
Person person;
//getter and setters
}
Person{
String id;
String name;
String lastName;
List<Address> address;
//getter and setters
}
Address{
String id;
String name;
String description;
//getter and setters
}
So the hierarchy would be like this:
Company has Person has Address
What I have to do is, replace all String fields with other String, for instance
Company.companyName = "Hi there #xyz"
Address.name = "St. Example #xyz"
I need to replace the char #xyx with #abcd, for instance.
The object is much more complex than that and has a huge hierarchy.
I tried to find some API that would help me to do that, however I couldn't find anyone (I don't know if look correctly).
A solution that I have is in each getter method replace the char, however I don't think that is the best way to solve that.
I appreciate your help.
Thanks in advance.
I could solve that using reflection. I did not find any API.
Related
I have a model class like following:
#Data
public class Customer {
String customerName;
List<Address> addresses;
// the rest of the field
}
For the Address class
#Data
#NoArgsConstructor
public class Address {
private String address1;
private String address2;
private String addressType;
private int addressTypeId;
private String city;
private String houseNumber;
private String state;
private String streetName;
private String zipCode;
private String zipPlus4;
}
In my controller I need to validate the Customer Object, the valid customer object need to have two addresses, one is the physical and one is billing. And also for each address, it also need to validate the houseNumber, streetName, state, city, zipCode, those fields cannot be empty..
Like if user provide the physical address but missing one of the fields I want to return the message said "Physical address is missing either one of fields: houseNumber, streetName, city, state, zipCode"
What should be the correct way to write the validation?
I would use Bean Validation annotations on both classes.
For Customer use the #Min and #NotNull in the addresses field.
For Address use either #NotBlank or #NotEmpty.
Spring has an integration for bean validation so it should work out-of-the-box. You can also customize the message response in the annotations.
However I would suggest using separate fields for billing and physical address in case that there are always two of them. Otherwise you'll have to iterate and find out which address is billing and which one is physical every time.
I would like to generate different Json output for the same complex Java object depending on the use case.
For example check the following code:
class Employee {
private Long id;
private String name;
private EmployeeDetail detail;
private Department department;
...
}
class Department {
private Long id;
private String name;
private String address;
...
}
class EmployeeDetail {
private Long id;
private int salary;
private Date birthDate;
...
}
If I convert Employee to Json all of the fields from Employee, EmployeeDetail and Department will be present. And it is good for one use case.
However in the second use case I would like to skip Department details except the id field but keep the complete EmployeeDetail.
I know that I can add something similar #JsonView(EmployeeView.Basic.class) to the id field in the Department class and use Json views. However for cleaner code I would like to solve it inside the Employee class something like this:
class Employee {
private Long id;
private String name;
#JsonAllFields
private EmployeeDetail detail;
#JsonIdOnly
private Department department;
...
}
At the moment I use the Jackson library but can switch if required.
i think you can use com.fasterxml.jackson.annotation.
#JsonIgnore is used to ignore the logical property used in serialization and deserialization. #JsonIgnore can be used at setter, getter or field. You can use it in the fields in Department class except on ID. There are so many ways to do it. Either you can allow the only getter in serialization etc.
Example:
#JsonIgnore(false)
private String id;
OR
#JsonIgnoreProperties({ "bookName", "bookCategory" })
public class Book {
#JsonProperty("bookId")
private String id;
#JsonProperty("bookName")
private String name;
#JsonProperty("bookCategory")
private String category;
}
To know more about it, please refer: https://www.concretepage.com/jackson-api/jackson-jsonignore-jsonignoreproperties-and-jsonignoretype
I hope this helps.
Just found a solution using #JsonFilter
Now the Employee class looks like this:
class Employee {
private Long id;
private String name;
private EmployeeDetail detail;
#JsonFilter("departmentFilter")
private Department department;
...
}
And the code to generate the limited json looks like this:
ObjectMapper mapper = new ObjectMapper();
SimpleFilterProvider filterProvider = new SimpleFilterProvider();
filterProvider.addFilter("departmentFilter", SimpleBeanPropertyFilter.filterOutAllExcept("id"));
mapper.setFilterProvider(filterProvider);
One small cons is that now I also need to define the filter to generate the full, detailed json like this:
filterProvider.addFilter("departmentFilter", SimpleBeanPropertyFilter.serializeAll());
I have two entities Merchant and Customer:
public class Merchant{
private UUID id;
private String name;
//... other fields and getters/setters
}
public class Customer{
private UUID id;
private String name;
//... other fields and getters/setters
}
These two entities are sightly different from each-other.
What I'am trying to to do is when I search with the term "John" I want to get both a merchant named "John Market" and a customer called "John Smith".
To achieve this I indexed these entities to a single index.
#Document(indexName = "merchant_customer_index", type = "merchantorcustomer")
public class MerchantOrCustomer {
#Id
private UUID id;
private String name;
private int type;
//...
My query can return both Merchant and Customer:
List<MerchantOrCustomer> result = elasticsearchTemplate.queryForList(nativeSearchQuery, MerchantOrCustomer.class);
I distinguish them programmatic(if(result.get(i).getType() == 0 we received Merchant else Customer)
Then use their id to extract actual object from relational db.
I searched a lot, but couldn't find anything that can help to estimate if it is a good practice. Is it a good practice?
Please, give me a hint if there is a better way.
There doesn't seem to be anything wrong with what you did unless there is some collusion as mentioned by #Ivan in comments.
Here is another possible way to do if you were using elasticTemplate- Spring Data Elasticsearch: Multiple Index with same Document or if you are using queryBuilder - https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-search.html
I am making a simple CRUD application using Spring boot and MongoDB, the problem that I am facing is that I don't know how to define the model classes.
My application should be like this:
A site has some characteristics such as an ID, region, city, ... and contains 4 parts (cellulars) that each has its own characteristics. Any help would be appreciated.
This is what I have so far:
public class Site {
#Id
String siteId;
String projectPhase;
String region;
String city;
String siteName;
String newSiteName;
String clusterName ;
String longitude ;
String lattitude ;
#OneToMany(mappedBy = "siteId")
List L;
What I want to know is how do I associate another class inside this one.
Annotations like #OneToMany are typically used within JPA-context, and are unnecessary when using Spring Data MongoDB. This is also mentioned by the documentation:
There’s no need to use something like #OneToMany because the mapping framework sees that you want a one-to-many relationship because there is a List of objects.
You have a few options when you want to define one-to-many relations when using MongoDB. The first of them is to define them as embedded objects within the same document:
#Document
public class Site {
#Id
private String id;
private String city;
private String region;
private List<Part> cellulars;
}
public class Part {
private String characteristic1;
private String characteristic2;
}
This means that the parts do not exist on their own, so they don't need their own ID either.
Another possibility is to reference to another document:
#Document
public class Site {
#Id
private String id;
private String city;
private String region;
#DBRef
private List<Part> cellulars;
}
#Document
public class Part {
#Id
private String id;
private String characteristic1;
private String characteristic2;
}
In this case, parts are also separate documents, and a site simply contains a reference to the part.
I already searched for this particular issue, the closest thread i found was this one: Java/JAXB: Unmarshall XML elements with same name but different attribute values to different class members But it's still not exactly what i need, so i hope someone can help me with this.
I am doing a SOAP request on a Zimbra Collaboration Suite 7 Server to get a contact. The response is something like this:
<cn fileAsStr="Arthur, Spooner" f="" id="280" rev="1973" d="1338524233000" t="" md="1338524233" ms="1973" l="7"><meta/><a n="homePostalCode">93849</a><a n="lastName">Spooner</a><a n="birthday">1980-05-24</a><a n="homeStreet">Berkleystreet 99</a><a n="firstName">Arthur</a></cn>
I want to map this to a Java object, something like this:
public class Contact {
Integer id;
Integer rev;
String namePrefix;
String firstName;
String middleName;
String lastName;
String jobTitle;
ArrayList<Adress> adresses;
Date birthday;
String department;
Integer mobilePhone;
String email;
String company;
String notes;
...
I usually do this using JAXB, but as all the elements are called a and all the attributes n, I don't know how to map this. I really would appreciate a code snippet or any kind of help. Thanks in advance.
You could try doing something like this:
#XmlAccessorType(XmlAccessType.FIELD)
public class ContactAttribute {
#XmlAttribute(name="n")
private String attribute;
#XmlValue
private String value;
}
#XmlRootElement(name = "cn")
#XmlAccessorType(XmlAccessType.FIELD)
public class Contact {
#XmlAttribute
Integer id;
#XmlAttribute
Integer rev;
//...
#XmlElements(#XmlElement(name = "a"))
List<ContactAttribute> attributes;
//...
}
Use the Castor Mapping
it will help you to Marshall and Unmarshall the data.