This question already has answers here:
How to serialize object to CSV file?
(8 answers)
Closed 9 years ago.
what would be the best way to have information in a JavaBean be put into a CSV file? I am making a registration page and have set all the parameters of my User JavaBean through a JSP page using I need to store this information into a csv from a servlet everytime someone registers so I can retrieve this information when they use the login JSP page.
Here is my JavaBean
package bean.user;
public class User_profile {
private String First_Name;
private String Last_Name;
private String ssn;
private String birthday;
private String home_phone;
private String password;
private String gender;
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirst_Name() {
return First_Name;
}
public void setFirst_Name(String first_Name) {
First_Name = first_Name;
}
public String getLast_Name() {
return Last_Name;
}
public void setLast_Name(String last_Name) {
Last_Name = last_Name;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getHome_phone() {
return home_phone;
}
public void setHome_phone(String home_phone) {
this.home_phone = home_phone;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
You can use introspection to retrieve all the properties of your bean with their corresponding read/write method then call them by reflection.
Here is an example with this simple class:
public class User {
private String login;
private String name;
private String surname;
private Integer age;
//Getters and setters
}
Now, I create a user and dump its properties in a String with comma separated values :
User u = new User();
u.setAge(18);
u.setLogin("myLogin");
u.setName("myName");
u.setSurname("mySurname");
for(PropertyDescriptor pd : Introspector.getBeanInfo(User.class).getPropertyDescriptors()){
//I don't want to get the "class" property
if(!pd.getName().equals("class")){
Method readMethod = pd.getReadMethod();
System.out.print(readMethod.invoke(u)+",");
}
}
Output :
18,myLogin,myName,mySurname,
Note: For the simplicity of this example, I did not suppress the ',' at the end of the output and did not handle case when properties contain character ','.
Use jsefa if you really really want CSV but this is better suited to store the details in some sort or repository/DB.
You can use this library http://jexcelapi.sourceforge.net/ or any such library which can help you convert your java objects in CSV form. One more for you http://kasparov.skife.org/csv/
Related
I converted UUID to string (String id) and put the conversion inside a method.
I also declared other String variables such as FirstName etc and put in on an ArrayList:
Code
The code does work. But I'm confused why the string email was showing second on the list.
public class StudentController {
#Autowired
StudentService studentService = new StudentService();
#GetMapping
public List<Student> displayStudent(){
return studentService.getStudent();
}
}
public class StudentService {
Student student = new Student();
private List<Student> studentList = Arrays.asList(
new Student(student.genID(),"Elvis" , "Presley" ,"Elvis#gmail.com")
);
public List<Student> getStudent(){
return studentList;
}
}
public class Student {
UUID uuid = UUID.randomUUID();
private String id;
private String FirstName;
private String LastName;
private String email;
public Student() {}
//Method Converting UUID into string
public String genID(){
id = uuid.toString();
return id;
}
public Student(String id) {
this.id = id;
}
public Student(String id, String firstName, String lastName, String email) {
this.id = id;
FirstName = firstName;
LastName = lastName;
this.email = email;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Expected
I expected data to be in this order
ID , FirstName , LastName , email
Actual Output JSON
JSON is an unordered collection, as specified on https://www.json.org/json-en.html , so you don't have to worry about it. It might depend on library though.
Specify the serialized order of properties
The order of properties during serialization can be defined in Jackson.
Either at class-level specifically using annotation #JsonPropertyOrder.
Or globally for your ObjectMapper using a feature:
objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
Example
In your case you can achieve expected order using the annotation on your class:
#JsonPropertyOrder({'id', 'firstName', 'lastName', 'email'})
public class Student {
// body of your class
}
Or separately with an index on your fields:
public class Student {
#JsonProperty(index=10)
private String id;
// not ordered specifically
private String firstName;
private String lastName;
#JsonProperty(index=20)
private String email;
// remainder of your class
}
See also
Jackson ObjectMapper - specify serialization order of object properties
Order of JSON objects using Jackson's ObjectMapper
Jackson JSON - Using #JsonPropertyOrder annotation to define serialized properties ordering
I have a User class which saves some extra data on the user. This data is stored in/coming from Firestore. I have a couple of fields which are working(name, surname, lastLogin) but a couple of them are not working(blocked).
When I make the field public they work, but when I try to use a setter, it doesn't. I tried cleaning the build and rebuilding it. I know it is not saving the field due to #Exclude, that is intended.
What am I doing wrong? The field type doesn't matter, I've added a new String field which gave the same warning, while name and surname work.
The database:
**userid**
{
"name" : "John",
"surname" : "Doe",
"lastLogin" : **timestamp**,
"blocked" : true
}
The class:
#Keep
public class User
{
private String name;
private String surname;
private Date lastLogin;
private boolean blocked = false;
public User()
{
}
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 Date getLastLogin()
{
return lastLogin;
}
public void setLastLogin(Date lastLogin)
{
this.lastLogin = lastLogin;
}
#Exclude
public boolean isBlocked()
{
return blocked;
}
public void setBlocked(boolean blocked)
{
this.blocked = blocked;
}
The problem in your code is that the constructor in the User class is private. That's not the correct way in which you should create a new instance of the class. JavaBeans require a no-argument constructor to be present.
When Cloud Firestore SDK deserializes objects that are coming from the database, it requires that any objects in use, to have this public no-argument constructor, so it can use it to instantiate the object. Fields in the objects are set by using public setter methods or direct access to public members, as you already tried.
Because your constructor is private, the SDK doesn't really know how to create an instance of it. So it is mandatory to change it as public. A correct way to create that class should be:
class User {
private String name;
private String surname;
private long lastLogin;
private boolean blocked = false;
public User() {} //Needed for Cloud Firestore
public User(String name, String surname, long lastLogin, boolean blocked) {
this.name = name;
this.surname = surname;
this.lastLogin = lastLogin;
this.blocked = blocked;
}
//Getters and setters are not mandatory
}
Also please note that the setters and the getters are not required. Setters are always optional because if there is no setter for a JSON property, the Firebase client will set the value directly onto the field.
Edit:
According to your comment:
but it does not explain why some fields are working and others aren't. It should not work at all, right?
Yes, that's right, all should work. The reason why some of them are not working is that the blocked property in your User class is of type boolean while in your database is of type String and this is not correct. Both types must match.
And the private constructor is due to the singleton instance, as far as I know, the constructor should be private to avoid creating new instances of the class.
No, the constructor must be public. I think there is a misunderstanding. Every time you use FirebaseDatabase.getInstance(), a single socket connection between your application and the Firebase servers is opened. From that moment on, all traffic between the application and the database goes over the same socket. So it doesn't matter how many times you create an instance, it will always be a single connection. Regarding your POJO class, there is no need for such a Singleton because Firebase always needs to know how to create an instance of that class, using the public no-argument constructor.
Try to create a constructor with parameters for all class attributes along with a non-parameter constructor and then in the java class where you store in firebase, create object from user and pass it.
for example:
package com.example.spacing.Model;
public class User {
private String username;
private String phone;
private String id;
private String imageURL;
private String email;
public User(String username, String email ,String phone, String id, String imageURL) {
this.username = username;
this.email=email;
this.phone = phone;
this.id = id;
this.imageURL = imageURL;
}
public String getImageURL() {
return imageURL;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public User() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
and
FirebaseDatabase.getInstance().getReference("Users")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user);
You can try to add #field:JvmField to your boolean variable inside your User class.
Consider the following class.
public class UserDTO {
private String email;
private String password;
private String country;
private String fName;
private String lName;
private String type;
private String profPicPath;
public UserDTO(String fNme, String lNme, String profPic) {
this.setfName(fNme);
this.setlName(lNme);
this.setProfPicPath(profPic);
}
public String getEmail() {
return email;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getfName() {
return fName;
}
public void setfName(String fName) {
this.fName = fName;
}
public String getlName() {
return lName;
}
public void setlName(String lName) {
this.lName = lName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getProfPicPath() {
return profPicPath;
}
public void setProfPicPath(String profPicPath) {
this.profPicPath = profPicPath;
}
I want to create an object only contains the fName, Lname and profPicPath. I have created a constructor to initialize only these three fields. But when I create an object using this constructor it contains the other properties as well with null values. Is there any approach in Java to create an object only with a selected properties ?
I think you are confused between the domain/model object and DTO object. The domain/model class represents the full set of attributes while you specific DTOs representing subsets of attributes in the domain/model class e.g. the User class is your domain/model class representing the full set of attributes (email, password, country, fName, lName, type, gender, country, profPicPath etc.) and then you can have DTOs like, UserLoginCredentialDTO (with email and password attributes), UserDemographyDTO (with attributes like gender, country etc.).
You can also check https://softwareengineering.stackexchange.com/questions/155768/what-oo-design-to-use-is-there-a-design-pattern for another example.
Apart from this, the comments of JB Nizet and Abra are quite valid and will help you understand this concept better in terms of Java.
yes. the approach is called inheritance. You need to create a BaseUserDTO that contains the subset of properties that is shared between the two entities. (they need to be declared as protected to be accessible to the subclass) UserDTO will extend the base class so it contains all its properties plus its own. the constructor with three properties must call the matching super constructor in order to initialize the shared properties
So in the app I'm creating I have a user class defined as the following
public class User implements Serializable{
private int id;
private String username;
private String firstName;
private String lastName;
private String email;
private String password;
private String picture;
private ArrayList<String> tags;
private double rating;
private Category favorite;
private boolean star;
private Location homeLocation;
public User(int id, String username, String firstName,String lastName,String picture, ArrayList<String> tags,double rating, Category favorite, boolean star,Location homeLocation,String email,String password) {
this.id = id;
this.username = username;
this.firstName = firstName;
this.lastName = lastName;
this.picture = picture;
this.tags = tags;
this.rating = rating;
this.favorite = favorite;
this.star = star;
this.homeLocation = homeLocation;
this.email = email;
this.password = password;
}
public int getId() {
return id;
}
public String getUsername() {
return username;
}
public String getFirstName() {
return firstName;
}
public String getLastName(){ return lastName;}
public String getPicture(){ return picture;}
public ArrayList<String> getTags() {
return tags;
}
public double getRating(){ return rating;}
public Category getFavorite(){ return favorite;}
public Boolean getStar(){ return star;}
public Location getHomeLocation(){return homeLocation;}
public String getEmail(){return email;}
public String getPassword(){return password;}
public void setId(int id){
this.id = id;
}
Now, when I create a User object I pass an ArrayList<String> tags which, when logged, shows just as intended.
List<String> listTags = Arrays.asList(DummyTags.tagsNewUser);
ArrayList<String> tags = new ArrayList<>();
tags.addAll(listTags);
Log.d("Tags",tags.toString());
user = new User(0,userName,firstName,lastName,picturePlaceHolder,tags,4,category,true,loc,email,password);
However, when I use this user object in, say a profile page, and retrieve the users tags through the getter in the class it always returns null.
user = (User) getArguments().getSerializable("User");
tags = user.getTags();
Doing this always has tags be null, no matter what ArrayList I pass when creating the user object.
I also get a warning in android studio saying that invoking user.getTags() may produce a npe. Every other part of the user model works just fine. I have tried to solve this for a while now and have not been able to find anything relating to my problem so any help would be appreciated!
Try:
Bundle bundle=new Bundle();
bundle.putStringArrayList("tags",tags);
bundle.putSerializable("User",user);
and then retrieve as:
tags = getArguments().getStringArrayList("tags");
The reason that your solution does not work is that ArrayList is not implementing Serializable interface
I need to delete certain lines from a file, the file is a list of contacts that I read in from a file into my GUI. When I get to the contact I want to delete, my program should delete the contact from the file. I've tried to do this, but it is not working.
Here is the code I'm currently using:
String temp=txtname.getText();
for (Contact Contact:contacts)
{
if (temp.equals(Contact.getname()));
{
txtname.setText("");
txtsurname.setText("");
txtphone.setText("");
txtmobile.setText("");
txtaddress.setText("");
txtpostcode.setText("");
contacts.remove(Contact);
contacts.remove(Contact);
contacts.remove(Contact);
contacts.remove(Contact);
contacts.remove(Contact);
contacts.remove(Contact);
}
}
My contact class is:
public class Contact {
static void add(String text) {
}
public String name;
public String surname;
public String phone;
public String mobile;
public String address;
public String postcode;
public Contact(){}
public Contact(String name, String surname, String phone,
String mobile, String address, String postcode)
{
this.name = name;
this.surname = surname;
this.phone = phone;
this.mobile = mobile;
this.address = address;
this.postcode = postcode;
}
public String getname()
{
return this.name;
}
public String getsurname()
{
return this.surname;
}
public String getphone()
{
return this.phone;
}
public String getmobile()
{
return this.mobile;
}
public String getaddress()
{
return this.address;
}
public String getpostcode()
{
return this.postcode;
}
public void setname(String name)
{
this.name = name;
}
public void setsurname(String surname)
{
this.surname = surname;
}
public void setphone(String phone)
{
this.phone = phone;
}
public void setmobile(String mobile)
{
this.mobile = mobile;
}
public void setaddress(String address)
{
this.address = address;
}
public void setpostcode(String postcode)
{
this.postcode = postcode;
}
}
I'm guessing it deletes it from the arraylist, but I'm not sure how the program knows what to delete from the file.
Thanks.
Modifying the internal list doesn't change the file. There is no automatic way to synchronize the two. You have to save the array back to the file to update it.
There is no way to delete anything from the middle of the file.
The only way is to rewrite the file every time something should be changed.
you can use a random access file but it seems like an over kill for this task.
the best way to do it is to have the remove function write the whole file back to the disk.
If you have no specific format for the file, then I suggest you to use the default serialization and serialize the contacts list. Like this,
//To serialize
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("D:/newfile.txt")));
out.writeObject(contacts);
//To deserialize
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("d:/newFile.txt")));
contacts = (ArrayList<Contact>)in.readObject();
You first have to implement the Serializable interface in your Contact class.
Or if you need more control over the file format use the standard XML classes or JSON libraries.
Files can be rewrited, or appended to. In you case you'll have to rewrite it. There are other ways, but they would be an overkill here.
String temp = txtname.getText();
for (Contact contact : contacts) {
if (temp.equals(contact.getname())) {
contacts.remove(contact);
break;
}
}
Fixed a lot of general problems with your code
public class Contact {
private String name;
private String surname;
private String phone;
private String mobile;
private String address;
private String postcode;
public Contact(String name, String surname, String phone, String mobile, String address, String postcode) {
this.name = name;
this.surname = surname;
this.phone = phone;
this.mobile = mobile;
this.address = address;
this.postcode = postcode;
}
public String getName() {
return this.name;
}
public String getSurname() {
return this.surname;
}
public String getPhone() {
return this.phone;
}
public String getMobile() {
return this.mobile;
}
public String getAddress() {
return this.address;
}
public String getPostcode() {
return this.postcode;
}
}