I want to map the Abc class to AbcDTO using "org.mapstruct.Mapping"
class Abc {
private List<Xyz> xyz = null;
private String uvw;
private String cde;
}
class AbcDTO{
private List<XyzDTO> xyz = null;
private String uvw;
private String cde;
}
class Xyz{
private String type;
private String value;
private String docId;
}
class XyzDTO{
private String type;
private String value;
private DocDTO document;
}
I tried to map the classes by using the annotation:
#Mappings({
#Mapping(source = "xyz.docId", target = "xyz.doc")
})
abcDTO abcToabcDTO(abc abc)
Can someone please help with how do i iterate through the nested beans and map the docId to doc?
If the names are same they map automatically but I want to map from docId to doc.
when you want map list you can define it :
#Mapping(source="docId", target="doc")
XyzDTO xyzToXyzDTO(XyZ xyz);
#Mapping(source="xyz", target="xyz") //useless if two lists got same name, but good for comprehention
AbcDTO abcToAbcDTA(Abc abc);
It should be as below (
you can give it a try):
#Mappings({
#Mapping(target="doc", source="abc.docId")
})
AbcDTO abcToabcDTO(Abc abc);```
Related
I have a service which is returning a List in JSON format.
Please find below code :
public List<SampleList> getValues() {
List<SampleList> sample = null;
sample= DAOFactory.sampleDAO.findByCriteria().add(Restrictions.isNull("endDate")).list();
return sample;
}
Class SampleList.java
public class SampleList {
private Integer categoryId;
private String categoryName;
//getter setter
}
Now my service is returning the JSON like below
{
categoryId : 1,
categoryName : "Test"
}
But I need anotherlist to be encapsulated here. Iw ant below output
{
categoryId : 1,
categoryName : "Test"
subCategory:
{
name: ""
}
}
For subCategory attribute I have another class similar to SampleList.java. I can get the sub categories corresponding to each category. Can anyone help me out to get expected response?
I dont want to touch my SampleList class.
You have to extend your class SampleList
Class SampleList.java
public class SampleList {
private Integer categoryId;
private String categoryName;
private SubCategory subCategory;
//getter setter
And before you return your list of course you have to set the correct subCategory in your SampleList item.
If you don't want to spoil your SampleList class of course you could add a layer of DTO objects and map between them or manipulate the response directly e.g. with ResponseBodyAdvice
Approach : 1
public class SampleList
{
private Integer categoryId;
private String categoryName;
// Getter and Setter
}
public class SampleList2
{
private String name;
// Getter and Setter
}
// Logic to get the JSON value without mapping two different classes
private void getJsonValue() throws JsonProcessingException, JSONException
{
SampleList sampleList = new SampleList();
sampleList.setCategoryId(1);
sampleList.setCategoryName("cat 1");
String sampleListJson = new ObjectMapper().writeValueAsString(sampleList);
SampleList2 sampleList2 = new SampleList2();
sampleList2.setName("Sub category");
String valueOfSample2 = new ObjectMapper().writeValueAsString(sampleList2);
JSONObject sampleListJsonObj = new JSONObject(sampleListJson); // for class SampleList
JSONObject sampleList2JsonObj = new JSONObject(valueOfSample2); // for class SampleList2
sampleListJsonObj.put("subCategory", sampleList2JsonObj);
System.out.println(sampleListJsonObj.toString());
}
Approach : 2
public class SampleList
{
private Integer categoryId;
private String categoryName;
private SampleList2 subCategory;
// Getter and Setter
}
public class SampleList2
{
private String name;
// Getter and Setter
}
// Logic to get with mapping two classes as mentioned above
private static void getJsonValue() throws JsonProcessingException
{
SampleList sampleList = new SampleList();
sampleList.setCategoryId(1);
sampleList.setCategoryName("cat 1");
SampleList2 sampleList2 = new SampleList2();
sampleList2.setName("Sub category");
sampleList.setSubCategory(sampleList2);
String jsonString = new ObjectMapper().writeValueAsString(sampleList);
System.out.println(jsonString.toString());
}
Please let me know if you have any questions on the same.
Thank you.
New to MapStrut; Object to String Error:
[ERROR] /util/LicenseMapper.java:[11,23] Can't map property "java.lang.Object license.customFields[].value" to "java.lang.String license.customFields[].value". Consider to declare/implement a mapping method: "java.lang.String map(java.lang.Object value)".
Code:
#Mapper
public interface LicenseMapper {
List<License> jsonToDao(List<com.integrator.vo.license.License> source);
}
The vo.license contains List of CustomFields having property as
#SerializedName("Value")
#Expose
private Object value;
The Json has input for one field as object as it might come boolean or string or anything so i have mapped it into object. Whereas in dao layer has same field in String. (In custom mapper i just String.valueof but not sure how to achieve it using Mapstrut)
Can anyone tell me what settings are required in LicenseMapper to convert Object to String?
License Structure - Source and destination:
.
.
private String notes;
private Boolean isIncomplete;
private List<CustomField> customFields = null;
private List<Allocation> allocations = null;
Custom Field Structure in Source (removed gson annotations):
.
.
private String name;
private Object dataType;
private Object value;
Custom FIeld Structure in Destination
private String name;
private String datatype;
private String value;
You can try to use annotation #Mapping with expression
#Mapping(expression = "java( String.valueOf(source.getValue()) )", target = "value")
List<License> jsonToDao(List<com.integrator.vo.license.License> source);
UPDATE
#Mapper
public interface LicenseMapper {
LicenseMapper MAPPING = Mappers.getMapper(LicenseMapper.class);
List<License> entityListToDaoList(List<com.integrator.vo.license.License> source);
License entityToDao(com.integrator.vo.license.License source);
List<CustomField> customFieldListToCustomFieldList(List<*your custom field path*CustomField> source);
#Mapping(expression = "java( String.valueOf(source.getValue()) )", target = "value")
CustomField customFieldToCustomField(*your custom field path*CustomField source);
}
IN YOUR CODE
import static ***.LicenseMapper.MAPPING;
***
List<License> myList = MAPPING.jsonToDao(mySource);
U can do this :
#Mapping(target = "yourTarget", source = "yourClass.custField.value")
enter image description here
Here is the code :
I have a entity named ClassA which consists of following attribute
#JsonProperty("rowDeleted")
private Boolean rowDeleted;
#JsonProperty("start")
private List<Start> start = null;
#JsonProperty("end")
private List<End> end = null;
#JsonProperty("rows")
private List<Row> rows = null;
And Row is another entity which consists of attributes:
#JsonProperty("cells")
private List<Cell> cells = null;
#JsonProperty("clusteringKey")
private String clusteringKey;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
And Cell is another entity:
#JsonProperty("deleted")
private Boolean deleted;
#JsonProperty("name")
private String name;
#JsonProperty("value")
private String value;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
I am getting an object of ClassA and want to convert it into another entity which is ClassB contains fields:
private String end;
private String key;
private String keyspacename;
private String partitiondeleted;
private String rowdeleted;
private String rows;
private String start;
private String tablename;
private String triggerdate;
private String triggertime;
So basically i want to convert List rows of ClassA to String rows of ClassB.
Can anyone please suggest a way to do this.
Thanks in advance
suppose you have a list of class A.
List<A> list= . . . ;
List<B> newList=list
.stream()
.map(obj-> new B()
.setKey(obj.getKey())
.setKeyspacename(//set which field of class A will be saved)
.setPartitiondeleted()
// set more fields
)
.collect(Collecters.toList());
and then serialize this newlist into String by using jakson.
I wanted a string which could represent json format so modified my toString() as per my requirement and it solved my purpose.
Have searched in different sites but couldn't find correct answer, hence posting this request though it could possible duplicates.sorry for that.
I am sending the below json request to my back-end service and converting to java object for processing. I can see the request body passed to my service but when i convert from json to java object , values are not populating
{
"data":{
"username":"martin",
"customerId":1234567890,
"firstName":"john",
"lastName":"smith",
"password":"p#ssrr0rd##12",
"email":"john.smith#gmail.com",
"contactNumber":"0342323443",
"department":"sports",
"location":"texas",
"status":"unlocked",
"OrderConfigs":[
{
"vpnId":"N4234554R",
"serviceId":"connectNow",
"serviceType":"WRLIP",
"ipAddress":"10.101.10.3",
"fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
"timeout":1800,
"mapId":"test_map"
}
]
}
}
My Parser class have something like,
JSONObject requestJSON = new JSONObject(requestBody).getJSONObject("data");
ObjectMapper mapper = new ObjectMapper();
final String jsonData = requestJSON.toString();
OrderDTO mappedObject= mapper.readValue(jsonData , OrderDTO .class);
// I can see value coming from front-end but not populating in the mappedObject
My OrderDTO.java
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true,value = {"hibernateLazyInitializer", "handler", "created"})
public class OrderDTO {
private String username;
private long customerId;
private String source;
private String firstName;
private String lastName;
private String email;
private String contactNumber;
private String password;
private String department;
private String location;
private String status;
private List<OrderConfig> OrderConfigs;
#JsonInclude(value = Include.NON_NULL)
public class OrderConfig {
private String vpnId;
private String serviceId;
private String serviceType;
private String ipAddress;
private String mapId;
private String[] fRoutes;
private Map<String, Object> attributes;
private SubConfig subConfig;
private String routeFlag;
getter/setters
.....
}
all setter/getter
}
Not sure what I'm missing here. Is this right way to do?
If your are trying to use inner class, correct way to use is to declare it static for Jackson to work with inner classes.
For reference check this
code changes made are
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
static class OrderConfig {
Make sure that your json tag names match with variable names of java object
Ex : "fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
private String[] fRoutes;
OrderConfigs fields will not be initialized, just modify your bean as
#JsonProperty("OrderConfigs")
private List<OrderConfig> orderConfigs;
// setter and getter as setOrderConfigs / getOrderConfigs
See my answer here. (same issue)
I have use case where i need to map or fill data for particular fields
for example : I Have a user Model which i need to convert to UserDTO with only
particular fields like username and accountId.
MODEL :
public class UserCore{
private String accountId;
private String username;
private String workEmail;
private String firstName;
private String password;
private String hashedPassword;
}
UserDTO :
public class UserCoreDTO{
private String accountId;
private String username;
private String workEmail;
private String firstName;
private String password;
private String hashedPassword;
}
is there any way in map-struct so that i can map only particular fields from source to destination
for example :
UserMapper mapper = Mappers.getMapper( UserMapper.class );
mapper.map(fieldsToFetch,source,destination);
Here's an example form the docs:
#Mapper
public interface FishTankMapper {
#Mappings({
#Mapping(target = "fish.kind", source = "fish.type"),
#Mapping(target = "fish.name", ignore = true),
#Mapping(target = "ornament", source = "interior.ornament"),
#Mapping(target = "material.materialType", source = "material"),
#Mapping(target = "quality.report.organisation.name", source = "quality.report.organisationName")
})
FishTankDto map( FishTank source );
}
ignore = true will probably work for all fields, not just nested fields as in the example.