I have the class which has to details inside the data http://www.mocky.io/v2/5cacde192f000078003a93bb , i have written a class to get the data and next class to get the details
public class ApiObject {
#SerializedName("status")
#Expose
public String status;
#SerializedName("data")
#Expose
public List<MyData> data = null;
#SerializedName("products")
public List<Products> products = null;
public List<MyData> getData() {
return data;
}
public class MyData{
#SerializedName("details")
public Details details;
#SerializedName("product_count")
public Integer productCount;
public Details getDetails(){
return details;
}
#SerializedName("product_count")
#Expose
private String Product_count;
#SerializedName("products")
public List<Products> getProducts(){
return products;
}
//setter and getters
}
I have created a object of Apiobject in more class
and I'm trying to access the getDetails method
like
ApiObject apiObject ;
apiObject.getData().getDetails();
I'm getting an error cannot resolve a method
getDetails() is a private method. Therefore, can only be accessed from within the class MyData. Make it public for it to be accessible to instances of other classes.
There are two problems in your code:
getDetails() is a private method, make it public if you want to access it.
getData() return a list of MyData objects, not a single instance. So, you should iterate through the list if you want to call the getDetails().
for (MyData data : apiObject.getData()) {
data.getDetails();
}
Related
I have a Entity class something like this:
#Entity
public class Website {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String url;
public Website() {
//Constructor
//getters and setters
}
here is the DTO class:
public class WebsiteDto {
private Integer id;
private String name;
private String url;
public WebsiteVo() {
//Constructor
//getters and setters
}
I have the WebsiteMapper something like this:
#Component
public class WebsiteMapper {
public List<WebsiteDto> getWebsiteList() {
return repository.findAll().stream().map(w -> {
WebsiteDto dto = new WebsiteVo(w.getId(), w.getName(), w.getUrl());
return dto;
}).collect(Collectors.toList());
I also have Repository Interface:
public interface WebsiteRepository extends JpaRepository<Website, Integer> {
}
I want now to convert DTO to entity using my class WebsiteMapper. Because I did the conversion in this class. How I can do it?
How about using BeanUtils provided by spring org.springframework.beans.BeanUtils, something like this
public List<WebsiteDto> getWebsiteList() {
return repository.findAll().stream().map(w -> {
WebsiteDto dto = new WebsiteVo();
BeanUtils.copyProperties(w, dto); // copys all variables with same name and type
return dto;
})
.collect(Collectors.toList());
}
Hi I guess you wish to converting your entity to DTO. It's quite simple. Create static methods in your DTO class or any util class. The return type should be your DTO type.
e.g.
public class WebsiteDto {
private Integer id;
private String name;
private String url;
public static WebsiteDto export(Website website) {
// Return a new instance of your website DTO
return new WebsiteDto(
website.getId(),
website.getName(),
website.getUrl()
);
}
public static List<WebsiteDto> export(List<Website> websites) {
// Return a new instance of your website DTO list
return websites.stream().map(website -> {
return new WebsiteDto(
website.getName(),
website.getUrl()
}).collect(Collectors.toList());
}
}
NOTE You can also convert your DTO to entity using similar method.
I have MyEntity class:
#Entity
#Table("entities)
public class MyEntity {
#ID
private String name;
#Column(name="age")
private int age;
#Column(name="weight")
private int weight;
...getters and setters..
}
In #RestController there are 2 #GetMapping methods.
The first:
#GetMapping
public MyEntity get(){
...
return myEntity;
}
The second:
#GetMapping("url")
public List<MyEntity> getAll(){
...
return entities;
}
It's needed to provide:
1. #GetMapping returns entity as it's described in MyEntity class.
2. #GetMapping("url") returns entities like one of its fields is with #JsonIgnore.
UPDATE:
When I return myEntity, client will get, for example:
{
"name":"Alex",
"age":30,
"weight":70
}
I want in the same time using the same ENTITY have an opportunity depending on the URL send to client:
1.
{
"name":"Alex",
"age":30,
"weight":70
}
2.
{
"name":"Alex",
"age":30
}
You could also use JsonView Annotation which makes it a bit cleaner.
Define views
public class View {
static class Public { }
static class ExtendedPublic extends Public { }
static class Private extends ExtendedPublic { }
}
Entity
#Entity
#Table("entities)
public class MyEntity {
#ID
private String name;
#Column(name="age")
private int age;
#JsonView(View.Private.class)
#Column(name="weight")
private int weight;
...getters and setters..
}
And in your Rest Controller
#JsonView(View.Private.class)
#GetMapping
public MyEntity get(){
...
return myEntity;
}
#JsonView(View.Public.class)
#GetMapping("url")
public List<MyEntity> getAll(){
...
return entities;
}
Already explained here:
https://stackoverflow.com/a/49207551/3005093
You could create two DTO classes, convert your entity to the appropriate DTO class and return it.
public class MyEntity {
private String name;
private int age;
private int weight;
public PersonDetailedDTO toPersonDetailedDTO() {
PersonDetailedDTO person = PersonDetailedDTO();
//...
return person;
}
public PersonDTO toPersonDTO() {
PersonDTO person = PersonDTO();
//...
return person;
}
}
public class PersonDetailedDTO {
private String name;
private int age;
private int weight;
}
public class PersonDTO {
private String name;
private int age;
}
#GetMapping
public PersonDTO get() {
//...
return personService.getPerson().toPersonDTO();
}
#GetMapping("/my_url")
public PersonDetailedDTO get() {
//...
return personService.getPerson().toPersonDetailedDTO();
}
EDIT:
Instead of returning an Entity object, you could serialize it as a Map, where the map keys represent the attribute names. So you can add the values to your map based on the include parameter.
#ResponseBody
public Map<String, Object> getUser(#PathVariable("name") String name, String include) {
User user = service.loadUser(name);
// check the `include` parameter and create a map containing only the required attributes
Map<String, Object> userMap = service.convertUserToMap(user, include);
return userMap;
}
As an example, if you have a Map like this and want
All Details
userMap.put("name", user.getName());
userMap.put("age", user.getAge());
userMap.put("weight", user.getWeight());
Now if You do not want to display weight then you can put only two
parameters
userMap.put("name", user.getName());
userMap.put("age", user.getAge());
Useful Reference 1 2 3
I have a Mcq class associated to a MongoRepository, and I want to get an instance of my Mcq which apply several changes (Answers shuffle, Questions draw, etc). I declared my function "myMcq.getInstance()", but I can't do that because every time I want to send a Mcq in a ResponseEntity there is an error in the JSON output because Springboot thinks that there is a "instance" property in my class.
Here is my java class :
#Document(collection = "Mcqs")
public class Mcq {
#Id public String id;
#DBRef public User creator;
public String title;
public String categoryID;
public List<McqChapter> chapterList = new ArrayList<>();
public Difficulty difficulty;
public Mcq() {}
public Mcq(String title) {
this();
this.title = title;
}
public ArrayList<String> getQuestionsIDs() {
ArrayList<String> result = new ArrayList<>();
for (McqChapter chapter : chapterList) result.addAll(chapter.getQuestionIDs());
return result;
}
public McqInstance getInstance() {
return new McqInstance(this);
}
}
To prevent the error add #JsonIgnore to getInstance() method:
#JsonIgnore
public McqInstance getInstance() {
return new McqInstance(this);
}
Marker annotation that indicates that the annotated method or field is to be ignored by introspection-based serialization and deserialization functionality. That is, it should not be consider a "getter", "setter" or "creator".
I am struggling with unmarshalling an old xml file whose structure is different than my current object structure.
Previous structure
#xmlRootElement("configData")
public class configData{
private string name;
private string age;
private customObject obj;
}
My current data structure is
#xmlRootElement("configData")
public class configData{
List<SampleData> sampleDatas;;
}
public class SampleData{
private string name;
private string age;
private customObject obj;
}
How to make it work with old xml file. Please help.
Thanks
Your old structure suggest, that only one set of SampleData exists in the XML file.
So You should try something like this:
#XmlRootElement
public class ConfigData
{
// This will hide the list from JAXB
#XmlTransient
private final List<SampleData> sampleDatas = new ArrayList<>();
private SampleData getFirstSample()
{
if(sampleDatas.isEmpty())
sampleDatas.add(new SampleData());
return sampleDatas.get(0);
}
// Façade methods to delegate functionality to the list's first item...
// Only setters are required, if you just want to read in an old format.
// However this would not be optional, if you want to save to the new format...
public void setName(String name)
{
getFirstSample().setName(name);
}
public void seAge(String age)
{
getFirstSample().setAge(age);
}
public void setObj(CustomObject obj)
{
getFirstSample().setObj(obj);
}
}
public class SampleData
{
private String name;
private String age;
private CustomObject obj;
// Accessor methods...
}
The façade setter methods in ConfigData store thier values to the List's first item.
To provide the possibility to save, you should remove the #XmlTransient, and provide public getters to the fields you want to save...
I have below json string :-
{"name":"Test","sortlist":[],"filterlist":[{"fieldname":"regions_id","operator":"equals","value":{"id":1,"code":"HIGH","description":"HIGH Region","comment":"High Region","active":true}}]}
and Java class as below :-
#JsonSerialize
#JsonDeserialize
public class ItemFilter implements Serializable {
private String name;
private List<FieldFilter> filterlist = new ArrayList<FieldFilter>();
}
public class FieldFilter implements Serializable {
private static final long serialVersionUID = 1L;
private String fieldname;
private String operator;
private Object value;
}
and my convert method as below :-
public static ItemFilter convertItemFilter(String item) {
ObjectMapper mapper = new ObjectMapper();
try {
ItemFilter itemFilter = mapper.readValue(item, new TypeReference<ItemFilter>(){});
return itemFilter;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
ItemFilter domain is getting converted correctly but in private Object value; field i am getting LinkedHashMap i want to get an simple object and later i will type cast it.
Can someone please guide me how to escape LinkedHashMap and get an simple Java Object in variable?
i cant use hard coding Object type because its a generic pojo which can have any object type. hard coding will make this pojo very bigger and frontend also need to change for it. So that why i have used Object as data type.
The following class structure should return the JSON to "YourObject"
public class YourObject{
private String name;
private List<String> sortList;
private List<Filter> filterList;
public static class Filter{
private String fieldname;
private String operator;
private Value value;
}
public static class Value{
private Integer id;
private String code;
private String description;
private String comment;
private Boolean active;
}
}
Then use the following to read it into the object:
YourObject itemFilter = mapper.readValue(item, YourObject.class);