Map two ArrayList with different sizes - java

For Example:
ArrayList1 = {userid1, userid2, userid1, userid4, userid1, userid3, userid2, userid4, userid4, userid4, userid2};
ArrayList2 = {username1, username2, username3, username4};
Mapping these two array so that whenever I call ArrayList1.get(0).getUserName(), it should provide me with username1.

public class User {
String username;
public User(String username)
{
this.username = username;
}
/**
* #return the username
*/
public String getUsername() {
return username;
}
/**
* #param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
}
userid1, userid2... must be User objects
User userid1 = new User("username1");
User userid2 = new User("username2");
Initialize all the user objects
ArrayList1 = {userid1, userid2, userid1, userid4, userid1, userid3, userid2, userid4, userid4, userid4, userid2};
Then you can call
String username = ArrayList1.get(0).getUserName();
this will return username1

There is a better way to do that and that is by using HashMap:
//create your custom object which will be mapped
public class User{
public String userId;
public String userName;
}
ArrayList<String> userKeys = new ArrayList<String>();
HashMap<String, User> users = new HashMap<String, User>();
Now using a userKey, you can access its corresponding userData;
Example:
User user = users.get("yourKey");

I think you should use :
List<List<T>> = ArrayList<ArrayList<T>>;
T is the class of you UserName.

Use HashSet instead of arraylist. Set does not allow duplicate.

Related

DynamoDBMappingException: no RANGE key value present

I am new to NoSQL and Amazon Dynamo DB. I am trying to retreive a user by username first from a DynamoDB UserMaster table.
I have a table UserMaster with 5 attributes(username, correct-hash, email, lastLogin, role), each of type String and I have a corresponding UsermasterBean mapped to the table UserMaster. UserMaster table's Partition Key(Hashkey) is username and Sort key(Range Key) is correct-hash
UsermasterBean
#DynamoDBTable(tableName = "UserMaster")
public class UsermasterBean {
private String username;
private String correctHash;
private String email;
private String lastLogin;
private String role;
#DynamoDBHashKey(attributeName = "username")
#DynamoDBAttribute(attributeName = "username")
public String getUsername() {
return username;
}
#DynamoDBRangeKey(attributeName = "correct-hash")
#DynamoDBAttribute(attributeName = "correct-hash")
public String getCorrectHash() {
return correctHash;
}
#DynamoDBAttribute(attributeName = "email")
public String getEmail() {
return email;
}
#DynamoDBAttribute(attributeName = "last-login")
public String getLastLogin() {
return lastLogin;
}
#DynamoDBAttribute(attributeName = "role")
public String getRole() {
return role;
}
public void setUsername(String username) {
this.username = username;
}
....
....
}
Retrieve data from UI:
UsermasterBean usermasterBean = new UsermasterBean();
UsermasterDao usermasterDao = new UsermasterDao();
usermasterBean.setUsername(username.getValue()); // Get the username from UI form
final String inputtedPassword = password.getValue(); // Get the password from UI form
UsermasterBean retrievedUserBean = usermasterDao.findByUsernameAndPassword(usermasterBean,inputtedPassword);
Validate User:
public UsermasterBean findByUsernameAndPassword(final UsermasterBean usermasterBean, final String inputtedPassword)
throws IOException {
AmazonDynamoDBClientHandler amazonDynamoDBClientHandler = AmazonDynamoDBClientHandler.getNewInstance();
UsermasterBean retrievedUser;
try {
AmazonDynamoDB amazonDynamoDB = amazonDynamoDBClientHandler.createNewClient();
DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB);
retrievedUser = dynamoDBMapper.load(usermasterBean.getClass(), usermasterBean.getUsername());
System.out.println("RETRIEVED CORRECT-HASH FROM DATABASE: " + retrievedUser.getCorrectHash()); // Check if hash retrieved is correct for this user.
// PasswordUtilityManager.verifyPassword(inputtedPassword,retrievedUser.getCorrectHash());
} catch (IOException ioException) {
throw ioException;
} finally {
amazonDynamoDBClientHandler.shutdownClient();
}
return retrievedUser;
}
Problem:
retrievedUser = dynamoDBMapper.load(usermasterBean.getClass(), usermasterBean.getUsername()); throws com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException
I am expecting retrievedUser.getCorrectHash() should display the hashed password stored in database as a String so that I can verify if the inputted password creates the same hash as retrieved from the database.
This exception is being throw because the DynamoDBMapper is expecting the range key to be passed in too (as your DynamoDB table contains a range key of correct-hash).
The correct function call should be as below
retrievedUser = dynamoDBMapper.load(usermasterBean.getClass(), usermasterBean.getUsername(), usermasterBean.getCorrectHash());
As this is presumably the hash for your users password, you can specify a hashed copy of the password provided by the user. If this returns no results in DynamoDB you can assume that either their username or password is incorrect.
As per your data model, there can be more than one entry in the UserMaster table for a single user (username) which is not your intention. (Why would a user have two hashed passwords?)
Do not model correctHash as a range key. If you do, DynamoDB mandates you to provide both the hash and range key when calling load (else you have to query).
See: DynamoDBMapper load vs query

Vaadin ThreadLocal for User Management

I'm currently developing a web application in Java which will be accessed by multiple users at the same time and as such need to store userdata in order to tailor the application to their individual requirements (such as what company they are apart of etc).
There are 2 classes that i use to manage this. User, MainSystem detailed below:
User
#Entity
public class User implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String username;
private String password;
private String type;
private String company;
private String DOB;
private String email;
private int PayrollId;
public User(String firstName, String lastName, String username, String password, String type, String company, String DOB, String email) {
this.firstName = firstName;
this. lastName = lastName;
this.username = username;
this.password = password;
this.type = type;
this.company = company;
this.DOB = DOB;
this.email = email;
}
MainSystem:
public class MainSystem {
public UserController userController;
private UserRepository userRepository;
private static ThreadLocal<User> loggedInUser = new ThreadLocal<>();
public DbController dbController;
public MainSystem(){
userController = new UserController(userRepository);
loggedInUser.set(new User());
}
public Boolean Login(String username, String password) {
if(userController.checkUser(username,password)){
User aUser = userController.getUser(username);
setLoggedInUser(userController.getUser(username));
VaadinSession.getCurrent().setAttribute("username",loggedInUser.get().getUsername());
System.out.println("Logged in User: "+loggedInUser.get().getUsername());
return true;
}
else {
return false;
}
}
public static void setLoggedInUser(User user){
loggedInUser.set(user);
}
public static User getLoggedInUser() {
return loggedInUser.get();
}
Ideally what i'd like to do is access the ThreadLocal variable from another class, for instance the ViewProfile.View:
public class EditProfileView extends VerticalLayout implements View {
MainSystem main = new MainSystem();
NavigatorUI aUI = new NavigatorUI();
User aUser = main.getLoggedInUser();
TextField username = new TextField("Username");
TextField Id = new TextField("Id");
TextField email = new TextField("Email");
TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");
TextField type = new TextField("Type");
PasswordField oldPassword = new PasswordField("Current Password");
PasswordField changePassword1 = new PasswordField("New Password");
PasswordField changePassword2 = new PasswordField("Confirm Password");
private UserController userController;
private UserRepository userRepository;
public EditProfileView() {
setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
userController = new UserController(userRepository);
setStyleName("backgroundImage");
setMargin(true);
setSizeFull();
addComponent(aUI.getHeader());
FormLayout content = new FormLayout(generateInfo());
Panel aPanel = new Panel("Edit User",content);
aPanel.setWidthUndefined();
content.setMargin(true);
aPanel.setStyleName(ValoTheme.PANEL_WELL);
addComponent(aPanel);
}
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
try {
aUser = main.getLoggedInUser();
System.out.println( aUser.getUsername());
Id.setValue(aUser.getId().toString());
username.setValue(aUser.getUsername());
firstName.setValue(aUser.getFirstName());
lastName.setValue(aUser.getLastName());
type.setValue(aUser.getType());
email.setValue(aUser.getEmail());
aUI.setUserMenu();
aUI.refreshPayroll();}
catch (Exception e){
System.out.println(e.getMessage());
}
}}
However, i'm finding that it is presenting me with a "null" value? I fear i may have missunderstood how ThreadLocal works. but essentially what i'm trying to achieve is to Store an instance relevant variable of the User.Class in MainSystem for other classes to use?
Any help would be appreciated.
My Solution:
My solution to this was to store the User.class in a VaadinSession Attribute like so:
public Boolean Login(String username, String password) {
if(userController.checkUser(username,password)){
User aUser = userController.getUser(username);
VaadinSession.getCurrent().setAttribute("user",aUser);
VaadinSession.getCurrent().setAttribute("username",loggedInUser.get().getUsername());
System.out.println("Logged in User: "+loggedInUser.get().getUsername());
return true;
}
else {
return false;
}
}
Then in other classes if i want to use that attribute i retrieved it like so:
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
try {
aUser = (User)VaadinSession.getCurrent().getAttribute("user");
}
catch (Exception e){
System.out.println(e.getMessage());
}
}
The problem is that there's no guarantee that MainSystem.Login() and EditProfileView.enter() will happen on the same thread. Every user action is processed as a separate HTTP request that the servlet container will run on any available thread.
For this kind of functionality, I would instead recommend storing the user information in the HTTP session. If you don't have any custom servlets or such, you could instead have a an field that contains the user object in your own custom UI class. Vaadin takes care of making UI.getCurrent() always return the right value in all code that is run through Vaadin.
If you instead also are integrating with other servlet functionality, you could store the user in the HttpSession instead. Generic servlet code can find the session through the getSession() method in e.g. servlet requests and response. In code run by Vaadin, you can use VaadinSession().getCurrent().getSession() to get a WrappedSession instance that is based on to the same HttpSession data.
There is also another approach. Instead it could be possible to make #SessionScoped user service, and either #Inject or #Autowire that depending whether you are using CDI or Spring. When doing this way, it will be the bean manager that takes care of binding correct entity with your view.

Java Spring hash AND validate passwords

I'm pulling my hair out over this. I have a simple User entity like this
#Entity
public class User {
private static final PasswordEncoder pwEncoder = new BCryptPasswordEncoder();
#Id
#GeneratedValue
private long id;
#NotNull(message = "FIELD_IS_NULL")
#NotEmpty(message = "FIELD_IS_REQUIRED")
#Length(min = 3, message = "FIELD_MUST_HAVE_AT_LEAST_3_CHARACTERS")
private String username;
#NotNull(message = "FIELD_IS_NULL")
#NotEmpty(message = "FIELD_IS_REQUIRED")
#Length(min = 6, message = "FIELD_MUST_HAVE_AT_LEAST_6_CHARACTERS")
#Pattern(regexp = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{6,128}$", message="PW_MIN_6_MAX_128_1_UPPER_1_LOWER_1_NUMERIC")
private String password;
public User(String username, String password){
this.username = username;
this.password = pwEncoder.encode(password);
}
/* getters and setters */
}
This works fine except that the password hashing happens before any validation, which means that the hashed password is validated instead of the unhashed.
I'm using a PagingAndSortingRepository for all my repository needs and I'd really like to avoid implementing a controller just for this case.
I'm feeling like I'm missing something really big there...
If you using this constructor
public User(String username, String password){
this.username = username;
this.password = pwEncoder.encode(password);
}
you'll have encoded password instead of original value
you can make #PrePersist method like this:
#PrePersist
public void prePersist(){
password = pwEncoder.encode(password);
}

GSON - JSON to Java object

I have been applying my expert level googling skills to no avail, so Stackoverflow I need your assistance.
I want to convert my json object to a java object in java.
JSON object appears as...
- {"password":"b","userName":"a"}
and the print statements once i 'attempt' to convert it are...
username = b
password = null
my question is why is this happening and how can i solve the issue? (Code follows)
Gson gson = new Gson();
JSONObject jObj = new JSONObject(request.getParameter("input"));
User user = gson.fromJson(jObj.toString(), User.class);
System.out.println(user.getPassword());
System.out.println(user.getUsername());
and the 'model' class....
public class User {
private String username;
private String password;
public User(String uName, String pWord){
this.username = uName;
this.password = pWord;
}
public void setUsername(String uName){
username = uName;
}
public String getUsername(){
return username;
}
public void setPassword(String pWord){
password = pWord;
}
public String getPassword(){
return password;
}
}
The solution in this case was was related to the mapping in the JSON as 'userName' when it should have been 'username'
refer to the comments for additional information.
hopefully other users find this a useful resource.

Taking Records from Database Java

I have a Table Like below
I run a Query to get Values in Table as Below
SELECT Id, UserName, UserId, Password,
CASE Status WHEN 1 THEN 'Active' ELSE 'Inactive' END AS Status
FROM users
Now I Java code for the Above Query is as below.
String[] arrUsersList[] = new String[100][5];
String[] arrUsersTem = new String[5];
pstmt = conn.createStatement(rs.TYPE_FORWARD_ONLY, rs.CONCUR_READ_ONLY);
rs = pstmt.executeQuery(strSQL);
while(rs.next())
{
arrUsersTem[0] = rs.getString("Id");
arrUsersTem[1] = rs.getString("UserName");
arrUsersTem[2] = rs.getString("UserId");
arrUsersTem[3] = rs.getString("Password");
arrUsersTem[4] = rs.getString("Status");
arrUsersList.add(arrUsersTem);
}
My Question is
I know I should use two dimensional array for getting the values from Recordset. I also know I am Doing it wrong way.What is the right way of taking records from Result set for the above.
Is array right option or i should use ArrayList or Some thing else.
Thanks for Reply.
Java is OOP language, so common way is to create class describing entities of your table and form Collection with this class objects
class Account {
private long id;
private String userName;
private String userId;
private String password;
private boolean status;
// getters, setters
}
List<Account> accountList = new ArrayList();
Account account;
while(rs.next()) {
account = new Account();
account.setId(rs.getLong("Id"));
account.setUserName(rs.getString("UserName"));
account.setUserId(rs.getString("UserId"));
account.setPassword(rs.getString("Password"));
account.setStatus(rs.getBoolean("Status"));
accountList.add(account);
}
You should create a User bean that contains fields for each of your database columns. Then create a List of User beans and do this:
List<User> users = new ArrayList<User>();
while(rs.next()) {
User user = new User();
user.setId(rs.getString("Id"));
user.setUsername(rs.getString("UserName"));
//More fields here
users.add(user);
}
You will then be left with a list of Users rather than a confusing 2d array
Since you result set can be of any size, you should not use Array, you should use Collection (or any derived implementation).
First you should create a class that represent the tuple you are retrieving:
public class User {
// fields
private int id;
private int userId;
private String username;
private String password;
private String status;
// constructor
public User(ResultSet rs) {
id = rs.getInt("Id");
// the same for the other fields...
}
}
Second and last, when iterating just create a new instance for each row/tuple, and add the resulting object to a collection that will grow as needed.
List<User> users = new ArrayList<User>();
while(rs.next())
{
users.add(new User(rs));
}
I would create a class User:
public class User {
private int id;
private String userName;
private String userId;
private String password;
private boolean active;
// getters & setters...
}
And then create Users like this:
SQL:
SELECT Id, UserName, UserId, Password, Status FROM users
Java:
List<User> users = new ArrayList<User>();
while (rs.next()) {
User user = new User();
user.setId(rs.getInt(1));
user.setUserName(rs.getString(2));
user.setUserId(rs.getString(3));
user.setPassword(rs.getString(4));
user.setActive(rs.getInt(5)>0);
users.add(user);
}
Try this:
while(rs.next()) {
account = new Account();
account.setId(rs.getLong("Id"));
account.setUserName(rs.getString("UserName"));
account.setUserId(rs.getString("UserId"));
account.setPassword(rs.getString("Password"));
account.setStatus(rs.getBoolean("Status"));
accountList.add(account);
}

Categories

Resources