I defined an object "User" in server and client end. The "User" in server end only has a constructor and getter and setter, but the one in client end has some other method.
My project structure is following:
Project structure
The code is following:
The server:
class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String password;
private String role;
User(String name, String password, String role) {
this.setName(name);
this.setPassword(password);
this.setRole(role);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String toString() {
return this.name + this.password + this.role;
}
}
The client:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String password;
private String role;
User(String name, String password, String role) {
this.name = name;
this.password = password;
this.role = role;
}
/*=====================getter and setter========================*/
public void set(String name, String password, String role) {
this.name = name;
this.password = password;
this.role = role;
}
public String get() {
return this.name + " " + this.password + " " + this.role;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return this.password;
}
public void setRole(String role) {
this.role = role;
}
public String getRole() {
return this.role;
}
/*==================Method===================*/
public void showMenu(String title) {
}
}
And I want to send a User object from client to server. But an ClassNotFoundException is thrown.
java.lang.ClassNotFoundException: pers.yangxujie.RecordMangerServer.main.User
Why? Do I have to user the same "User" object?(But I have to define them in both ends, because it is c/s model)
Based on what you have shown us, I think that the problem is that there is no class called pers.yangxujie.RecordMangerServer.main.User on the classpath on the server side.
If the problem was due to differences in the versions of the class on the client and server side, then I would expect to see different exceptions. It is (IMO) generally a bad idea to use different versions of a class when serializing and deserializing, because the differences can cause all sorts of problems (if you are not careful). However, sometimes this is unavoidable.
The class should be the same on both ends. Not different classes with the same name. Here 'same' means same name, same package, same serialVersionUID.
If you really know what you're doing, the classes can have minor disagreements about their fields, subject to the provisions of the Versioning chapter of the Object Serialization Specification: this can be handy as a solution to a deployment problem where you can't update server and client at the same time.
However it doesn't make sense to set out from the beginning to have two different classes called User in the same system. In this case it strongly appears that they are in different packages, which makes them different classes. This will not work for Serialization purposes.
Is the server class in its own separate file? Make sure neither one of them is an inner class
Related
This question already has answers here:
Java default constructor
(13 answers)
Closed 2 years ago.
I know that a similar question has been answered before in other questions but all the ones i found does not apply to my situation so i decided that i ask it.
This line gives an error:
User users = new User();
Error message:
constructor User in class User cannot be applied to given types;
required: String,String,String,String
found: no arguments
reason: actual and formal argument lists differ in length
Below is my java class file.
public class User {
private String username;
private String pwd;
private String email;
private String role;
public User(String username, String pwd, String email, String role) {
this.username = username;
this.pwd = pwd;
this.email = email;
this.role = role;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
Your User constructor takes 4 arguments: username, pwd, email, and role, and you're trying to construct it with new User(), which provides none of the arguments. You should actually provide them:
User user = new User("username here", "pwd here", "email here", "role here");
Or, create a constructor with no arguments of the form:
public User() {
this.username = /* some default value */;
this.pwd = /* some default value */;
this.email = /* some default value */;
this.role = /* some default value */;
}
Or, to reuse your constructor:
public User() {
this(/* username default */, /* pwd default */, /* email default */, /* role default */);
}
You could use null as the default value, but that will probably just lead to NullPointerExceptions down the line.
Just create another constructor:
public User(){}
When you make a class this constructor is made for you by default. When you create a constructor yourself, this default constructor isn't made for you anymore and you have to add it in yourself.
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
I need to verify the email of the new user who would like to sign up in my application web. if the email is already in my database (mysql) so must don't accept this sign up and said said to him like: "your email already used".
Now I can save users in my database, but how to check them by his email for not repeat the inscription in my application web.
this is my Dao layer class :
public class UserDaoMysql implements UserDao {
private Session session;
private void openSession(){
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
session = sessionFactory.openSession();
session.beginTransaction();
}
private void closeSession(){
session.getTransaction().commit();
session.close();
}
public void insert(User user) {
if(checkEmail(user)){
openSession();
User p = new User(user.getName(), user.getEmail(), user.getPassword());
session.save(p);
System.out.println("sauvegarde reussi");
closeSession();
}
}
public boolean checkEmail(User user){
return true;
}
}
this is my user bean :
#ManagedBean(name="user")
public class User {
private int id;
private String name;
private String email;
private String password;
private String confirmationPass;
// private image
public User() {
super();
}
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfirmationPass() {
return confirmationPass;
}
public void setConfirmationPass(String confirmationPass) {
this.confirmationPass = confirmationPass;
}
public User(int id, String name, String email, String password,
String confirmationPass) {
super();
this.id = id;
this.name = name;
this.email = email;
this.password = password;
this.confirmationPass = confirmationPass;
}
public User(int id, String name, String email, String password) {
super();
this.id = id;
this.name = name;
this.email = email;
this.password = password;
}
public User(String name, String email, String password) {
super();
this.name = name;
this.email = email;
this.password = password;
}
#Override
public String toString() {
return "User [id=" + id + ", Name=" + name + ", email=" + email
+ ", password=" + password + "]";
}
public void save(){
UserBusiness userBusiness = new UserBusinessImp();
userBusiness.add(new User(name, email,password));
}
}
And I created a table "user" in my database.
Maybe there is an annotation which can help us to specify the email property as an unique one or something else.
What you can do is create a unique key on your email column in your table. After that, decorate your field using #Column(unique=true), that will indicate to Hibernate that this field has a unique key.
Also, be careful with your annotations. This is unrelated to your problem, but #ManagedBean marks the class as a bean able to interact with the view in JSF. Probably you want/need to use #Entity instead.
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/