Why i cannot display element of mine list? - java - java

i have problem with my list. My goal is to make a JTree from my json list. To do it i convert my json where i have my patients to list. But i cannot even display the name of mine patient. Maybe my code make my problem clearer. I would be grateful for any suggestion!
My patient class:
public class Patient {
private String name;
private String surname;
private String pesel;
public Patient(String name, String surname, String pesel) {
this.name = name;
this.surname = surname;
this.pesel = pesel;
}
public String getName(){return name;}
public void setName(String name){this.name = name;}
public String getSurname(){return surname;}
public void setSurname(String surname){this.surname = surname;}
public String getPesel(){return pesel;}
public void setPesel(String pesel){this.pesel = pesel;}
}
My patientList:
(This method works, when i am using it to convert medicine json to medicine list i have no problem)
public List<Patient> FromJsonToArray1() throws IOException {
String patientsJson = initArray("Patients.json").toString();
Gson gson = new Gson();
java.lang.reflect.Type patientsListType = new TypeToken<ArrayList<Patient>>() {}.getType();
List<Patient> patientArray = gson.fromJson(patientsJson, patientsListType);
return patientArray;
}
And this is my function to show name of mine patient.
public void jtreecreator() throws IOException {
List<Medicine> medicineList = FromJsonToArray();
List<Patient> patientList = FromJsonToArray1();
medicinesDataMethods medicinesdatamethods = new medicinesDataMethods();
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Patients");
Patient c = patientList.get(0);
Medicine d = medicineList.get(0);
DefaultTreeModel treeModel = new DefaultTreeModel(root);
JTree tree = new JTree(treeModel);
JScrollPane scrollPane = new JScrollPane(tree);
JOptionPane.showMessageDialog(null,c.getSurname());
JOptionPane.showMessageDialog(null, d.getName());
}
And after call this function it display d.getName(), but c.getSurname() didnt work.
Its my json where i store my patients:
[
{
"Pesel": "1111",
"Surname": "Walker",
"Name": "Johny "
},
{
"Pesel": "11111",
"Surname": "Walker1",
"Name": "Johny1 "
}
]
After debug, i find out that my list which is created in FromJsonToArray1() has objects of patients but values of name, surname and pesel are null. :C

Issue is attribute names in class and json do not match. You can modify Patient class like
class Patient {
#SerializedName("Name")
private String name;
#SerializedName("Surname")
private String surname;
#SerializedName("Pesel")
private String pesel;
// getters and setters, constructor, etc. here
}

Related

how to handle different type of value in single field of JSON payload

I have come across a situation where I have to support existing client, they are using below payload for rest api,
{
"firstName": "First name",
"secondName": "Second name",
"dateOfBirth": "01/12/2020",
"profession": "Software Developer",
"salary": 0,
**"value": "value1"**
}
but now as per requirement, they may send array for value field like below :
{
"firstName": "First name",
"secondName": "Second name",
"dateOfBirth": "01/12/2020",
"profession": "Software Developer",
"salary": 0,
**"value": ["Value1", "value2", "Value3"]**
}
Existing code uses #RequestBody to convert it to PersonDTO person, this class also contains a method called isMutliValue() & getMultiValueFor(), and these methods splits the string based on comma then decide and return values out of it. but now for this requirement, I have to made a modification to check if client is sending array in value or simple string. if it is a simple string then don't split it based on comma and simply process it but if it is an array, bring values out of it and send individual values.
public class PersonDTO {
private String firstName;
private String secondName;
// Formats output date when this DTO is passed through JSON
#JsonFormat(pattern = "dd/MM/yyyy")
// Allows dd/MM/yyyy date to be passed into GET request in JSON
#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date dateOfBirth;
private String profession;
private BigDecimal salary;
private String value;
public PersonDTO(
String firstName, String secondName, Date dateOfBirth, String profession, BigDecimal salary, String value) {
this.firstName = firstName;
this.secondName = secondName;
this.dateOfBirth = dateOfBirth;
this.profession = profession;
this.salary = salary;
this.value = value;
}
public PersonDTO() {}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public BigDecimal getSalary() {
return salary;
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public boolean isMultiValued() {
return value.split(",").length > 1;
}
public String[] getMultiValues() {
return value.split(",");
}
public String toString(){
return "FirstName : " + firstName +" SecondName : "+ secondName +", Value : "+ value.toString();
}
}
please help me out, how can we handle different type of values in single field of json payload.
In this case you can implement custom deserialization. so for this purpose you should define a PersonDTODeserializer that extends from JsonDeserializer and override deserialize method.
public class PersonDTODeserializer extends JsonDeserializer {
#Override
public Object deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
String name = node.get("firstName").textValue();
String secondName = node.get("secondName").textValue();
BigDecimal salary = node.get("salary").decimalValue();
String value = "";
JsonNode nodeValue = node.get("value");
if (nodeValue.isArray()) {
Iterator<JsonNode> nodeIterator = nodeValue.iterator();
List<String> values = new ArrayList<>();
while (nodeIterator.hasNext()) {
values.add( nodeIterator.next().textValue());
}
value = String.join(",",values);
} else if (nodeValue.isTextual()) {
value = nodeValue.textValue();
}
return new PersonDTO(name, secondName, salary, value);
}
}
and use it in PersonDTO class.
#JsonDeserialize(using = PersonDTODeserializer.class)
public class PersonDTO {
//other
}
Based on #Hadi J answer,
you can set the deserializer on this field only and not the whole class :
public class PersonDTO {
// ...
#JsonDeserialize(using = ValueDeserializer.class)
private String value;
// ...
}
and the Deserializer:
private static class ValueDeserializer extends JsonDeserializer<String> {
#Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if( p.isExpectedStartArrayToken() ) {
List<String> values = new ArrayList<String>( p.readValueAs(List.class) );
return String.join(",", values);
} else {
return p.getValueAsString();
}
}
}

Accessing JSON values when parsing

I have a file called persons.json:
[
{
"id": 1,
"name": "The Best",
"email": "thenextbigthing#gmail.com",
"birthDate": "1981-11-23"
},
{
"id": 2,
"name": "Andy Jr.",
"email": "usa#gmail.com",
"birthDate": "1982-12-01"
},
{
"id": 3,
"name": "JohnDoe",
"email": "gameover#gmail.com",
"birthDate": "1990-01-02"
},
{
"id": 4,
"name": "SomeOne",
"email": "rucksack#gmail.com",
"birthDate": "1988-01-22"
},
{
"id": 5,
"name": "Mr. Mxyzptlk",
"email": "bigman#hotmail.com",
"birthDate": "1977-08-12"
}
]
I'd like to parse this file into an ArrayList with FasterXML, possibly with it's ObjectMapper() function and then being able to access each value (id, name, etc.) individually as a String when iterating through the newly created ArrayList. How could I do that? I don't even know what kind of list I could/should use in order to get access to each value individually. I'm kind of stuck here. List<???>
First of all:
FasterXML uses Jackson underneath to parse/produce json.
Now: to use Jackson, first of all create a container object for the data of your json, which we will call Person
public class Person {
private int id;
private String name, email;
#JsonFormat
(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date birthDate;
//add here getters and setters ...
}
At this point, supposing you have pathToPersonsJsonFile as a string containing the path to your persons.json, you can use your file like this:
byte[] jsonData = Files.readAllBytes(Paths.get(pathToPersonsJsonFile));
ObjectMapper objectMapper = new ObjectMapper();
Person[] parsedAsArray = objectMapper.readValue(jsonData, Person[].class); //array
ArrayList<Persons> persons = new ArrayList<>(Arrays.asList(parsedAsArray)); //your list
Note: JsonFormat enables to declare which format that value has on your json.
First you should create POJO for storing info:
public class Person {
Long id;
String name;
String email;
#JsonFormat("yyyy-mm-dd")
Date birthDate;
...
}
next you should call:
List<Person> myObjects = new ObjectMapper().readValue(jsonInput, new TypeReference<List<Person>>(){});
This should be enough
ObjectMapper objectMapper = new ObjectMapper();
List<Person> list = objectMapper.readValue(new File("path_to_persons.json"), new TypeReference<List<Person>>(){});
public class Person {
private String id;
private String name;
private String email;
private String birthDate;
.....
}
1) First create class Person.java
2) Then read the persons.json file and create a JSONArray from it.
3) Then parse as given below:
class Person{
private int id;
private String name;
private String email;
private String birthDate;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getBirthDate() {
return birthDate;
}
public void setBirthDate(String birthDate) {
this.birthDate = birthDate;
}
}
public List<Person> getPersonList(JSONArray dataArray){
List<Person> personList = new ArrayList<>();
for(int i=0; i<dataArray.length(); i++){
try {
JSONObject personJsonObject = dataArray.getJSONObject(i);
Person person = new Person();
if(personJsonObject.has("id") && !personJsonObject.isNull("id")){
person.setId(personJsonObject.getInt("id"));
}
if(personJsonObject.has("name") && !personJsonObject.isNull("name")){
person.setName(personJsonObject.getString("name"));
}
if(personJsonObject.has("email") && !personJsonObject.isNull("email")){
person.setEmail(personJsonObject.getString("email"));
}
if(personJsonObject.has("birthDate") && !personJsonObject.isNull("birthDate")){
person.setBirthDate(personJsonObject.getString("birthDate"));
}
personList.add(person);
}catch (JSONException e){
}
}
return personList;
}
4) Then use this list wherever you want.

Gson transform a field into multiple fields

Say I have serialized the following object as json string:
class Person {
public final String name;
public Person(String name) { this.name = name; }
}
Person p = new Person("Bob Falaway");
JsonObject json = gson.toJsonTree(p, Person.class).getAsJsonObject();
Now I want to deserialize it, but I want to split split the name into two fields, firstName and lastName. How do I do this?
I want the end to result in a class similar to:
class RefinedPerson {
public final String firstName;
public final String lastName;
public String toString() { return String.format("%s %s", firstName, lastName); }
}
Is this at all possible with Gson?
Register your own JsonSerializer for the type (or TypeAdapter if you'd prefer)?
Something like:
#JsonAdapter(PersonSerializer.class)
class Person {
private final String name;
Person(final String name) {
// Some validation...
this.name = name;
}
String getName() {
return this.name;
}
}
Where your serialiser looks something like:
class PersonSerializer implements JsonSerializer<Person> {
#Override
public JsonObject serialise(final Person src,
final Type personType,
final JsonSerializationContext context) {
final JsonObject json = new JsonObject();
final String[] names = src.getName().split(" ");
// Some validation...
json.addProperty("firstName", names[0]);
json.addProperty("lastName", names[1]);
return json;
}
}

Adding and setting new object in ArrayList at specific index (JAVA)

I made some projects with ArrayList. They have same problem with adding new object. My goal is to add new Object at specific location. For instance, each index hold four strings.
index 0: New York Times, 1234, New York, NY
index 1: NBCPhiladelphia, X123, Philadelphia, PA
index 2: FOX News, 0987, Los Angeles, LA
Suppose I want to add new one: CNN, 1230, Atlanta, GA. The location will be at index 1. Then other object will move in other index and so on... like this one:
index 0: New York Times, 1234, New York, NY
index 1: CNN, 1230, Atlanta, GA
index 2: NBCPhiladelphia, X123, Philadelphia, PA
index 3: FOX News, 0987, Los Angeles, LA
So far, my code seems not work to insert new one. I don't know how to find a way to fix this error.
public static void main(String[] args) {
ArrayList<NewsTV> newsTVList = new ArrayList<NewsTV>();
String nameToAdd = "CNN";
String idToAdd = "1234-123X";
String cityToAdd = "Atlanta";
String stateToAdd = "GA";
int indexToAdd = 6;
...... //This part, I add objects so don't worry about them.
newsTVList.add(indexToAdd, null);
insertObject(newsTVList, indexToAdd, nameToAdd, idToAdd, cityToAdd, stateToAdd);
public static void insertObject(ArrayList<NewsTV> np, int index, String n, String id,
String c, String s) {
for(NewsTV news: np) {
if(np.indexOf(index)) {
news.setName(n);
news.setISSN(id);
news.setCity(c);
news.setState(s);
}
}
}
First create POJO Class, here is Company
package com.appkart.array;
public class Company {
private String name;
private String id;
private String city;
private String state;
public Company(String name, String id, String city, String state) {
this.name = name;
this.id = id;
this.city = city;
this.state = state;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
#Override
public String toString() {
return name + ", " + id + ", " + city + ", " + state;
}
}
Then now add company into Arraylist as
package com.appkart.array;
import java.util.ArrayList;
public class TestCompany {
ArrayList<Company> companies = new ArrayList<Company>();
public void addCompany() {
Company newYorkTimes = new Company("New York Times", "1234",
"New York", "NY");
Company nbc = new Company("NBCPhiladelphia", "X123", "Philadelphia",
"PA");
Company fox = new Company("FOX News", "0987", "Los Angeles", "LA");
companies.add(newYorkTimes);
companies.add(nbc);
companies.add(fox);
printCompanyInfo();
}
public void addCompanyAtIndex(int index, Company company) {
companies.add(index, company);
printCompanyInfo();
}
public void printCompanyInfo() {
for (Company company : companies) {
System.out.println(company.toString());
}
}
public static void main(String[] args) {
TestCompany testCompany = new TestCompany();
testCompany.addCompany();
Company company = new Company("CNN", "1230", "Atlanta", "GA");
testCompany.addCompanyAtIndex(1, company);
}
}
When you use newsTVList.add(indexToAdd, null); you are adding a null item to your arraylist and when you use for(NewsTV news: np) {if(np.indexOf(index)) one of the np will be null and the program will throw a null pointer exception.
Create a new NewsTV object and initialize it with its values
String nameToAdd = "CNN";
String idToAdd = "1234-123X";
String cityToAdd = "Atlanta";
String stateToAdd = "GA";
Then call newsTVList.add(indexToAdd, <Your new NewsTV object> );
If you need the detail of the ArrayList.add(int index, E element) method look at the docs for the JSE 7
http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

Accessing instances in GUI file while instances are declared in another file

I'm learning OOP in Java. I'll explain my problem first, code below.
I have 3 seperate file (User.java, UserGUI.java and UserStart.java).
User.java has the code containing the User class with the default getters and setters.
UserGUI.java only exists out of items creating the GUI. UserStart.java has the code containing the main to run the program.
Now I'm trying to select a UserID in the JList in UserGUI.java and I want to show the surname and name in the JTextField below the JList.
User instances are made in UserStart.java and I'm stumped how to access them in UserGUI.java...
Is there anyone wanting to help me with this? Thank you in advance!
Below is the class of User.java:
public class User {
private String userId;
private String surname;
private String name;
public User(String userId, String surname, String name) {
this.userId = userId;
this.surname = surname;
this.name = name;
}
public String getuserId() {
return userId;
}
public void setuserId(String userId) {
this.userId = userId;
}
public String getsurname() {
return surname;
}
public void setsurname(String surname) {
this.surname = surname;
}
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
}
Below is a piece of code from the userGUI.java:
final JList<?> userList= new JList<Object>(addresses);
userList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()) {
String userId = (String) userList.getSelectedValue();
System.out.println(userId);
}
}
});
JTextField userText = new JTextField(10);
userText.setEditable(false);
Below is the file UserStart.java:
public class UserStart {
public static void main(String[] args) {
String userId, surname, name;
String[] userIds = {"a206", "a207", "a208", "a209"};
User u1 = new User(userIds[0], "a", "w");
User u2 = new User(userIds[1], "b", "x");
User u3 = new User(userIds[2], "c", "y");
User u4 = new User(userIds[3], "d", "z");
}
}
the simple way (which will suffice) is to pass the 'data' to the GUI on construction
class UserGui
{
private User[] user;
public UserGui(User[] users)
{
this.user = user;
initializeComponents();
}
// ...
}
then in your main
public static void main(String[] args)
{
User[] user = new User[10];
// setup user array ...
UserGui gui = new UserGui(user);
}
for larger more complicated programs/applications you should look in to using MVC as an approach which allows you decouple UI from Data.
For example in the User.java class you can create a static verctor with all users created (add each user there in the constructor):
import java.util.Vector;
public class User {
private String userId;
private String surname;
private String name;
public static Vector<User> users=new Vector<User>();
public User(String userId, String surname, String name){
this.userId=userId;
this.surname=surname;
this.name=name;
User.users.add(this);
}
}
then you can access any created user in any class like this:
User.users.get(i).getname();
depending on your problem, you should note the index somehow. the first created user will be 0: users.get(0), second one will be 1, and so on
for example if you want to display all users, then in a loop like this:
String name=null, surname=null;
for(int i=0;i<User.users.size();i++){
name=User.users.get(i).getname();
surname=User.users.get(i).getsurname();
//do something with you data before moving to next user
}
First of all, your constructor should have the same name as the class. Something like this:
public User(String userId, String surname, String name) {
this.userId = userId;
this.surname = surname;
this.name = name;
}
If you want to add the text to a JTextBox
if you have 1 textbox:
textbox1.setText(""+userList.getSelectedValue().getName() + ""+userList.getSelectedValue().getSurname())
if you have 2:
textbox1.setText(""+userList.getSelectedValue().getName());
textbox2.setText(""+userList.getSelectedValue().getSurname());
I haven't tested it, but it should work.

Categories

Resources