How to break the loop? - java

everyone who is watching this question. I have a small problem that i am not fixing. I have a program in which a user or a manager can login in and the input check whether the person who logged is a user or a manager. Unfortunately I can't separate them. This is what i would get all the time.
Incorrect username or password. Try Again!
This is the code:
int check = 0;
while(check == 0)
{
screen.displayString("Enter the username: ");
String usernameLogin = keypad.getString();
screen.displayString("Enter the password: ");
String passwordLogin = keypad.getString();
for (int i = 0; i < users.size(); i++) {
if (users.get(i).getUsername().equals(usernameLogin) && users.get(i).getPassword().equals(passwordLogin)) {
no = users.get(i).getId();
check = 1;
break;
}
else
{
check = 0;
}
}
if(check == 1)
{
break;
}
if (manager.getUsername().equals(usernameLogin) && manager.getPassword().equals(passwordLogin)) {
no = manager.getId();
check = 1;
break;
}
else {
check = 0;
}
if(check==0)
{
screen.displayStringLine("Incorrect username or password. Try Again!");
}
}
Thank you once again for the help.

first off a bit of small advice for code formatting, after each curly brace/code block leave one empty line - it will be easier to read
So let's clean your code a little bit by adhering to these steps:
do the easier tasks first, meaning there are many users in this app but only one manager so maybe we should check if it's him firstly and not waste compute resources
remove redundant variables - to break the loop you don't need the check variable, only a break statement after a correct login
you can use for each to iterate through a collection
while (true) {
screen.displayString("Enter the username: ");
String usernameLogin = keypad.getString();
screen.displayString("Enter the password: ");
String passwordLogin = keypad.getString();
if (manager.getUsername().equals(usernameLogin) && manager.getPassword().equals(passwordLogin)) {
no = manager.getId();
break;
}
for (User user : users) {
if (user.getUsername().equals(usernameLogin) && user.getPassword().equals(passwordLogin)) {
no = users.get(i).getId();
break;
}
}
screen.displayStringLine("Incorrect username or password. Try Again!");
}
This code should be easier to debug - just place 2 breakpoints on both lines containing if statement and check if values are matching.
If you see that everything looks good, check the string encoding - maybe there is a mismatch there (Java uses by default UTF8)

Related

How to create a Java 2-Step authentication on Java 8?

Hello everyone at StackOverflow,
I will be asking a question that I'm confused about and searched for hours for, it's to put a 2-Step authentication on a Java program, what I want is that is send a generated code to a login page like the one I created below.
package log;
import javax.swing.JOptionPane;
public class Login {
public static void main(String args[]) {
String username = JOptionPane.showInputDialog("Enter your username");
String password = JOptionPane.showInputDialog("Enter your password");
if (
username != null && password != null &&
(
(username.equals("g17") && password.equals("ire35")) ||
(username.equals("ree") && password.equals("melikejava")) ||
(username.equals("citizenzap") && password.equals("javarules23"))||
(username.equals("devs") && password.equals("password"))
)
)
{
JOptionPane.showMessageDialog(null, "Logged in!" );
} else {
JOptionPane.showMessageDialog(null, "Incorrect username or password! Try again later." );
}
}
}
Everything is fine with the code above, it's just that I want to send a randomly generated code to a phone number, like as I said before a 2-Step verification. Like Google has or Microsoft and etc. For example: You write a phone number, 123-456-7890, then it sends a code to the phone number and it's says something like Your code is 178634 then you write it into the input box, then it checks if it was the code it sent.
If the question I said is not specific enough or something like that please tell me.
Thanks and keep on coding!
-CitizenZap
First, I suggest you put your data in map, combine username, password, phoneNumber into one class, like UserInfo. Because you need to bind phoneNumber to user, or any phoneNumber after login is acceptable.
Then, you replace
{
JOptionPane.showMessageDialog(null, "Logged in!" );
}
with
String newPhoneNumber = null;
{
newPhoneNumber = JOptionPane.showInputDialog("Enter your phone number");
}
You need to check if newPhoneNumber equals with the phoneNumber bind to the user.
// this should be in a while(true) loop
if (newPhoneNumber.equals(phoneNumber)) {
sendSms(phoneNumber);
String code = JOptionPane.showInputDialog("Enter your code");
boolean result = validateAuthorizationCode(code); // here you validate the code
if (result) {
JOptionPane.showMessageDialog(null, "Logged in!" );
} else {
JOptionPane.showMessageDialog(null, "Wrong code!" );
}
} else {
noticeWrongNumber(newPhoneNumber); // tell him the number is wrong, please reinput.
}

How do I keep asking the user for input if the input wasn't a number?

I'm making a cash register with an "other" option, which allows the user to add an amount through user input. I have done this with a JOptionPane, the "other" button code is the following:
private void btnOverigActionPerformed(java.awt.event.ActionEvent evt) {
String prijs = JOptionPane.showInputDialog(this, "Vul een bedrag in");
try {
double overigePrijs = Double.parseDouble(prijs);
if (overigePrijs > 0){
aantalProducten[6]++;
totaalPerProduct[6] += overigePrijs;
}
huidigePrijsDisplay();
}
catch (Exception letter){
while (true){
prijs = JOptionPane.showInputDialog(this, "Vul a.u.b. alleen cijfers in.");
}
}
This while-loop will not close the JOptionPane, even when inputting numbers, how do I loop this correctly?
Edit after almost finishing my SE studies:
I was missing an if-statement in my while-loop. What I was trying to do was checking if the input of prijs were only numbers and if not, keep showing the dialog. I never got around to fixing this because it's an old project but I should have stated the motivation behind the code more clearly!
The question is not clear itself. What I assume that if the try part does not run as you wish, the JOptionPane should reopen and user should be prompted to do it again. If it is so, you can do the following:
Create a method:
private void doTheTask(){
String prijs = JOptionPane.showInputDialog(this, "Vul een bedrag in");
try{
//your task here.
}
catch (Exception letter){
//Call the method again.
doTheTask();
}
}
And call the method inside your action:
private void btnOverigActionPerformed(java.awt.event.ActionEvent evt){
doTheTask();
}
I suggest you a different approach in your code:
String prijs = "";
double overigePrijs = -1;
while (true) {
prijs = JOptionPane.showInputDialog(null, "Vul een bedrag in");
if (prijs != null) { // if user cancel the return will be null
try {
overigePrijs = Double.parseDouble(prijs);
break; // Exits the loop because you have a valid number
} catch (NumberFormatException ex) {
// Do nothing
}
} else {
// You can cancel here
}
// You can send a message to the user here about the invalid input
}
if (overigePrijs > 0) {
aantalProducten[6]++;
totaalPerProduct[6] += overigePrijs;
}
huidigePrijsDisplay();
This code will loop until the user enters a valid number and then you can use after the while loop. Some improvement may be necessary like a cancel logic or change the message on the second time but the main idea is this.

How do I display a whole category from a text file?

I managed to display 1 record of the asked category but what i need is for the program to display everything from that category. If it's too vague the code might help. Thanks in advance
public static void SearchCatRecord() throws Exception
{
LoadFile();
System.out.println("\t\t\t*******************************");
System.out.println("\n\t\t\t---------SEARCH CATEGORIZED ITEM--------");
System.out.println("\n\t\t\t*******************************");
System.out.print("\t\t\tEnter Category: ");
String searchnum = br.readLine();
boolean found = false;
for(int i=0;i<row;i++)
{
String record[] = list.get(i).split(",");
String num = record[1];
if(searchnum.equals(num))
{
found = true;
System.out.println("\t\t\t*******************************");
System.out.println("\n\t\t\t---------RECORD FOUND----------");
System.out.println("\n\t\t\tProduct Number : "+record[0]);
System.out.println("\t\t\tCategory : "+record[1]);
System.out.println("\t\t\tProduct Name : "+record[2]);
System.out.println("\t\t\tPrice : "+record[3]);
System.out.println("\t\t\tQuantity : "+record[4]);
System.out.println("\n\t\t\t*******************************");
Thread.sleep(2000);
found = true;
System.out.println("\n\n\t\t\tSearch Completed");
exiting();
}
}
if(found == false)
{
System.out.println("\t\t\tNo Record Found");
System.out.println("\t\t\t*******************************");
exiting();
}
MainMenu();
}
The following code asks the user which category should the program display. then it displays the asked category but it only displays one record.
This is because you call exiting(); when you found the first record. You should remove it in your loop.
for example:
for(int i=0;i<row;i++)
{
String record[] = list.get(i).split(",");
String num = record[1];
if(searchnum.equals(num))
{
found = true;
System.out.println("\t\t\t*******************************");
System.out.println("\n\t\t\t---------RECORD FOUND----------");
System.out.println("\n\t\t\tProduct Number : "+record[0]);
System.out.println("\t\t\tCategory : "+record[1]);
System.out.println("\t\t\tProduct Name : "+record[2]);
System.out.println("\t\t\tPrice : "+record[3]);
System.out.println("\t\t\tQuantity : "+record[4]);
System.out.println("\n\t\t\t*******************************");
Thread.sleep(2000);
}
}
System.out.println("\n\n\t\t\tSearch Completed");
if(found == false)
{
System.out.println("\t\t\tNo Record Found");
System.out.println("\t\t\t*******************************");
}
exiting();
If you want to find all the records then you should not breakout after finding one record that meets your criteria. I believe your method invocation exiting() is not needed in loop.
On a side note why are you setting found=true twice in the loop? Also what is the need of Thread.sleep(2000) in the code?

reducing number of return statements in a method

I have a java code in which there are multiple return statements in a single method. But for code cleaning purpose, I can have only one return statement per method. What can be done to overcome this.
Here is a method from my code:-
public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
// Kill any old sessions
//request.getSession().invalidate();
DynaValidatorForm dynaform = (DynaValidatorForm)form;
// validate the form
ActionErrors errors = form.validate(mapping, request);
if(!errors.isEmpty()) {
this.saveErrors(request, errors);
return mapping.getInputForward();
}
// first check if token is set
if(!isTokenValid(request, true)) {
String errmsg="There was a problem with your login. Please close your browser then reopen it and try again. Make sure to click the Login button only ONCE.";
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// check the form for input errors
String errmsg = checkInput(form);
if (errmsg != null) {
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// no input errors detected
String resumekey = null;
// check for valid login
ObjectFactory objFactory = ObjectFactory.getInstance();
DataAccessor dataAccessor = objFactory.getDataAccessor();
request.setCharacterEncoding("UTF-8");
String testcode = dynaform.getString("testcode").trim();
String studentname = dynaform.getString("yourname").trim();
String password = dynaform.getString("password").trim();
// 4/3/07 - passwords going forward are ALL lower case
if (!CaslsUtils.isEmpty(password)) {
password = password.toLowerCase();
}
try{
resumekey = new String(studentname.getBytes("ISO-8859-1"),"UTF-8");
} catch (Exception e) {
log_.error("Error converting item content data to UTF-8 encoding. ",e);
}
String hashWord = CaslsUtils.encryptString(password);
// Make sure this is short enough to fit in the db
if (hashWord.length() > ConstantLibrary.MAX_PASSWORD_LENGTH) {
hashWord = hashWord.substring(0, ConstantLibrary.MAX_PASSWORD_LENGTH);
}
Login login = dataAccessor.getLogin(testcode, hashWord, false);
if (login == null || !login.getUsertype().equals(Login.USERTYPE_SUBJECT)) {
request.setAttribute("errormessage", "Incorrect test code or password.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// Check if the login has expired
if (login.getLoginexpires() != null && login.getLoginexpires().before(new Date())) {
request.setAttribute("errormessage", "Your login has expired.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// Check if the password has expired
if (login.getPasswordexpires() != null && login.getPasswordexpires().before(new Date())) {
request.setAttribute("errormessage", "Your login password has expired.");
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
HttpSession session = request.getSession();
session.setAttribute(ConstantLibrary.SESSION_LOGIN, login);
session.setAttribute(ConstantLibrary.SESSION_STUDENTNAME, studentname);
List<Testtaker> testtakers = null;
try {
//invalidate the old session if the incoming user is already logged in.
synchronized(this){
invalidateExistingSessionOfCurrentUser(request, studentname, testcode);
testtakers = dataAccessor.getTesttakersByResumeKey(studentname, login);// Adding this code to call getTesttakersByResumeKey instead of getTesttakers to improve the performance of the application during student login
}
} catch (Exception e) {
log.error("Exception when calling getTesttakers");
CaslsUtils.outputLoggingData(log_, request);
throw e;
}
session = request.getSession();
if(testtakers!=null)
{
if(testtakers.size() == 0) {
// new student -> start fresh
log_.debug("starting a fresh test");
// if this is a demo test, skip the consent pages and dump them directly to the select test page
if (login.getTestengine().equals(Itemmaster.TESTENGINE_DEMO)) {
return mapping.findForward("continue-panel");
}
}
// send them to fill out the profile
// check for custom profiles
String[] surveynames = new String[4];
List<Logingroup> logingroups = dataAccessor.getLoginGroupsByLogin(login.getLoginid());
for(Logingroup logingroup : logingroups) {
Groupmaster group = logingroup.getGroupmaster();
log_.debug(String.format("group: {groupid: %d, grouptype: %s, groupname: %s}", new Object[] {group.getGroupid(), group.getGrouptype(), group.getName()}));
Set<Groupsurvey> surveys = group.getGroupsurveys();
if(surveys.size() > 0) {
// grab the first (and only) one
Groupsurvey survey = surveys.toArray(new Groupsurvey[0])[0];
if(group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_CLASS)) {
surveynames[0] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_SCHOOL)){
surveynames[1] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_DISTRICT)){
surveynames[2] = survey.getSurveyname();
} else if (group.getGrouptype().equalsIgnoreCase(Groupmaster.GROUPTYPE_STATE)){
surveynames[3] = survey.getSurveyname();
}
}
}
// match the most grandular survey
for(int i=0; i < surveynames.length; ++i) {
if(surveynames[i] != null) {
saveToken(request);
return mapping.findForward("student-profile-"+surveynames[i]);
}
}
// no custom profile, send them to the default
saveToken(request);
return mapping.findForward("student-profile");
}
// get the set of availible panels
Set<Panel> availiblePanels = dataAccessor.getAvailiblePanels(login, studentname);
if(availiblePanels.size() == 0) {
// no panels availible. send to all done!
log_.debug(String.format("No panels availible for Login:%s with resumekey:%s", login.toString(), studentname));
session.setAttribute("logoutpage", true);
resetToken(request);
return mapping.findForward("continue-alldone");
}
//Eventum #427 - Prevent test takers from retaking a finished test.
TestSubjectResult testSubjecResult=dataAccessor.getTestSubjectResult(login, resumekey);
if(testSubjecResult != null){
if(testSubjecResult.getRdscore() != null && testSubjecResult.getWrscore() != null && testSubjecResult.getLsscore() != null && testSubjecResult.getOlscore() != null){
if(testSubjecResult.getRdscore().getFinishtime() != null && testSubjecResult.getWrscore().getFinishtime() != null && testSubjecResult.getLsscore().getFinishtime() != null && testSubjecResult.getOlscore().getFinishtime() != null){
log_.debug(String.format("Already completed all the Skill Tests.", login.toString(), studentname));
session.setAttribute("logoutpage", true);
resetToken(request);
return mapping.findForward("continue-alldone");
}
}
}
// get a list of resumeable testtakers
List<Testtaker> resumeableTesttakers = new ArrayList<Testtaker>();
for(Testtaker testtaker : testtakers) {
if(testtaker.getPhase().equals(ConstantLibrary.PHASE_GOODBYE)) {
// testtaker is done with test. skip.
continue;
}
if(testtaker.getCurrentpanelid() == null) {
// testtaker is the profile testtaker
continue;
}
resumeableTesttakers.add(testtaker);
}
// sort them from least recent to latest
Collections.sort(resumeableTesttakers, new Comparator<Testtaker>() {
#Override
public int compare(Testtaker o1, Testtaker o2) {
// TODO Auto-generated method stub
//return 0;
return new CompareToBuilder()
.append(o1.getLasttouched(), o2.getLasttouched())
.toComparison();
}
});
if(resumeableTesttakers.size() == 0 && availiblePanels.size() > 0) {
// nobody is resumeable but there are panels left to take
// send them to the panel choice
// TODO: This is probably a misuse of Struts.
log_.info("No resumeable testtakers. Sending to panel select");
saveToken(request);
ActionForward myForward = (new ActionForward("/do/capstartpanel?capStartPanelAction=retest&lasttesttakerid="
+ testtakers.get(0).getTesttakerid(), true));
return myForward;// mapping.findForward(ConstantLibrary.FWD_CONTINUE + "-panel");
} else {
// grab the one most recently created and take their test
log_.info(String.format("Resuming with choice of %d testtakers", resumeableTesttakers.size()));
// we're forwarding to resume at this point, so we should do the some of the initialization
// that would have happened if we were still using getTesttaker() instead of getTesttakers() above.
session.setAttribute(ConstantLibrary.SESSION_LOGIN, login);
session.setAttribute(ConstantLibrary.SESSION_TESTTAKER, resumeableTesttakers.get(resumeableTesttakers.size()-1));
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_RESUME);
}
}
It's not a worth changing multiple returns to a single return statement per method. Actually, that will unnecessarily increase the burden of storing the result in a local variable and then making the return finally,
ActionForward result = null;
//scenario 1
result = ...
//scenario 2
result = ...
//scenario 3
result = ...
//finally
return result;
Hope this helps, but, it doesn't make much sense to me
As pointed out by others, having a single return statement does not necessarily make your code cleaner. However, in this case splitting up the method in smaller pieces probably makes the code more readable.
For example, this part:
// first check if token is set
if(!isTokenValid(request, true)) {
String errmsg="There was a problem with your login. Please close your browser then reopen it and try again. Make sure to click the Login button only ONCE.";
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
// check the form for input errors
String errmsg = checkInput(form);
if (errmsg != null) {
request.setAttribute("errormessage", errmsg);
saveToken(request);
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
could be replaced by introducing two methods and using those to write:
If(tokenNotSet() || formHasErrors()){
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
}
By doing this on multiple places the structure of the algorithm becomes more clear, possibly giving you more insight in how this code could be refactored to adhere to your coding guidelines.
I would set a an action forward variable at the start of the method.
ActionForward actionForwardToReturn = null;
Then replace each of these two lines
return mapping.getInputForward();
return mapping.findForward(ConstantLibrary.FWD_CONTINUE);
with these two lines :
actionForwardToReturn = mapping.getInputForward()
actionForwardToReturn = mapping.findForward(ConstantLibrary.FWD_CONTINUE);
finally return the variable.
return actionForwardToReturn;
This shouldn't be too difficult :)
On a side note... (actually the orginal answer to the question) :
Multiple return statements can make it hard to debug code.
I personally would have just one action object that you return at the end of the method. The benefit of this, is that i can put a break point right on the return statement and look at exactly what that object is.
Any logging or other cross cutting concern I would want to add later, would only have to be done at one point. Otherwise I would have to add a log statement to every line where you are returning.
The complexity added to a method in an attempt to remove multiple return statements is many a times not worth it, especially in a method such as yours.There's nothing wrong with using them in this case.
Like user3580294 there's nothing wrong with multiple return statements. However you could combine the last two if statements since they are essentially returning the same thing.
Use #Octopus 's method if you absolutely have to have one return statement

How to delete entry in an Address Book program using Java?

I am having trouble with the logic of deleting an entry in an Address Book... I am saving all the entries using an ARRAY.
I am try to make the array[i] = null, if array[i] is equals to the entered name of the user. But after i delete an entry and then try to view all entries again, nothing shows.. and output says :
Exception in thread "main" java.lang.NullPointerException
at AddressBook.viewAll(AddressBook.java:61)
at AddressBook.main(AddressBook.java:35)
Java Result: 1
this is my code in deleting an Entry:
public void deleteEntry() {
SName = JOptionPane.showInputDialog("Enter Name to delete: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
//JOptionPane.showMessageDialog(null, "Found!");
entry[i] = null;
}
}
}
Can you help me figure out what was wrong with my code... or LOGICAL ERROR?
If you have any suggestion or better way to delete an entry that would be a big help..
please help...
if (entry[i].getName().equals(SName)) {
if on one pass you make
entry[i] = null
then how would you getName() afterwords?
try adding a null check to your if statement
if (entry[i] != null && entry[i].getName().equals(SName)) {
EDIT: Benjamin brings up a good point. You should be prepared for a null result from showinputdialog(). For example, there's a cancel button right? If they press that, you'll get null I believe. Here's some better code for that case:
public void deleteEntry() {
/* get the input */
SName = JOptionPane.showInputDialog("Enter Name to delete: ");
/* if no input, nothing to delete */
if(SName == null) return;
/* find the name */
for (int i = 0; i < counter; i++) {
/* make sure we have an entry*/
/* we know SName is not null */
if (entry[i] != null && SName.equals(entry[i].getName())) {
/* null out the deleted entry */
entry[i] = null;
// break; /* If you know you have unique names, you can leave the for loop now */
} /* end if */
} /* end for i*/
}

Categories