I have to classes, and I need to input two values into one of the classes in my program.
import java.io.IOException;
import java.sql.*;
import static java.lang.System.out;
public class login{
private String username;
private String password;
public void logon() throws IOException {
System.out.println("Write your Name");
username = System.console().readLine();
System.out.println(username);
System.out.println("Write your Password");
password = System.console().readLine();
System.out.println(password);
try {
// Does stuff
}
catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
Mainly after username and password have been verified in the try catch. I need to transfer those two strings to another class. Seen Below.
public class ClientHandler {
protected Socket client;
protected PrintWriter out;
protected String Username;
protected String Password;
public ClientHandler(Socket client) {
//Does Stuff
}
}
I would like some pointers to how I can achieve this, either through constructors, or any other method that would be efficient.
I need to transfer those two strings to another class.
You can do this by creating a setter method (or more than one).
You need to add these two methods to your ClientHandler class.
public void setPassword(String password) {
this.Password = password;
}
public void setUsername(String username) {
this.Username = username;
}
Then, you set username and password variables by using these setter method
ClientHandler handler = ... //Create this object somehow
handler.setUsername(username);
handler.setPassword(password);
In your case this should go in you 'try' block
Related
I'm trying to simulate a method with mockito in Android Studio, but, one of the methods in the presenter class need an interface as parameter, but, when i call the method inside When() of Mockito this not recognize the interface. See the below code:
This is my MVP code example.
SignUpContract interface:
public interface SignUpContract {
interface view{
void showSignInScreen();
void onError(int code, String message);
}
interface model{
interface onFinish<R>{
void onResponse(R data);
void onError(String error);
}
void trySignIn(onFinish onFinish, String name, String password);
}
interface presenter{
void handleSignInButtonClick(String username, String password);
}
}
SignUpModel:
public class SignUpModel implements SignUpContract.model {
SignUpRepository repository;
public SignUpModel(){}
#Override
public void trySignIn(onFinish onFinish, String name, String password){
repository = new SignUpRepository();
String result = repository.signInUser(name, password);
if(!result.isEmpty()){
onFinish.onResponse(result);
} else {
onFinish.onError("Has error ocurred during the operation");
}
}
}
SignUpRepository:
public class SignUpRepository {
public String signInUser(String username, String password){
String data = "Someone";
return data;
}
}
SignUpPresenter:
public class SignUpPresenter implements SignUpContract.presenter,
SignUpContract.model.onFinish {
SignUpContract.view view;
SignUpContract.model model;
public SignUpPresenter(SignUpContract.view view, SignUpContract.model model){
this.view = view;
this.model = model;
}
#Override
public void handleSignInButtonClick(String username, String password) {
try{
model.trySignIn(this, username, password);
}catch (Exception e){
Log.d("",e.getMessage());
}
}
#Override
public void onResponse(Object data) {
view.showSignInScreen();
}
#Override
public void onError(String error) {
view.onError(1, error);
}
}
this is my test:
#RunWith(MockitoJUnitRunner.class)
public class SignUpPresenterTest {
public static final String USERNAME = "username";
public static final String PASSWORD = "password";
#Mock SignUpContract.model model;
#Mock SignUpContract.model.onFinish listener;
#Mock SignUpContract.view view;
#InjectMocks SignUpPresenter SUT;
#Before
public void setUp() throws Exception {
SUT = new SignUpPresenter(view, model);
}
public void success() throws Exception {
**when(model.trySignIn(any(SignUpContract.model.onFinish.class), any(String.class), any(String.class))).then(SUT.onResponse(1));**
}
#Test
public void try_signin_success() throws Exception{
success();
ArgumentCaptor<String> ac = ArgumentCaptor.forClass(String.class);
SUT.handleSignInButtonClick(USERNAME, PASSWORD);
verify(model, times(1)).trySignIn(any(SignUpContract.model.onFinish.class), ac.capture(), ac.capture());
List<String> captures = ac.getAllValues();
Assert.assertThat(captures.get(0), is(USERNAME));
Assert.assertThat(captures.get(1), is(PASSWORD));
verify(view).showSignInScreen();
}
}
I copied your code into an example to verify this myself.
I made a few changes, some are just for my convenience.
Note that I used JUnit5 with a newer mockito version (3.2.4) to test it.
You do not need to use both #InjectMocks and #Before, either one of them suffices.
You are using the wrong argument inside the doAnswer. It should have been args[0].
Using trySignIn(listener, USERNAME, PASSWORD); did not work for me, because listener refers to a different mock while you are actually passed the class under test (SUT) along as parameter.
I changed it to use matchers instead.
Edit:
I removed SignUpModel and SignUpRespository from my example as all the test does is to mock the interface. The implementation is not really relevant for your question.
The listener mock is also not required as its not used anymore.
import java.util.List;
import org.junit.Assert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;
#ExtendWith(MockitoExtension.class)
public class SignUpPresenterTest {
public interface SignUpContract {
interface view {
void showSignInScreen();
void onError(int code, String message);
}
interface model {
interface onFinish<R> {
void onResponse(R data);
void onError(String error);
}
void trySignIn(onFinish onFinish, String name, String password);
}
interface presenter {
void handleSignInButtonClick(String username, String password);
}
}
public static class SignUpPresenter implements SignUpContract.presenter, SignUpContract.model.onFinish {
SignUpContract.view view;
SignUpContract.model model;
public SignUpPresenter(SignUpContract.view view, SignUpContract.model model) {
this.view = view;
this.model = model;
}
#Override
public void handleSignInButtonClick(String username, String password) {
try {
model.trySignIn(this, username, password);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onResponse(Object data) {
view.showSignInScreen();
}
#Override
public void onError(String error) {
view.onError(1, error);
}
}
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
#Mock
SignUpContract.model model;
#Mock
SignUpContract.view view;
SignUpPresenter SUT;
#BeforeEach
public void setUp() throws Exception {
SUT = new SignUpPresenter(view, model);
}
#Test
public void try_signin_success() throws Exception {
Mockito.doAnswer(new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
SignUpContract.model.onFinish callback = (SignUpContract.model.onFinish) args[0];
callback.onResponse(0);
return null;
}
}).when(model).trySignIn(Mockito.any(SignUpContract.model.onFinish.class), Mockito.eq(USERNAME), Mockito.eq(PASSWORD));
ArgumentCaptor<String> ac = ArgumentCaptor.forClass(String.class);
SUT.handleSignInButtonClick(USERNAME, PASSWORD);
Mockito.verify(model, Mockito.times(1)).trySignIn(Mockito.any(SignUpContract.model.onFinish.class), ac.capture(), ac.capture());
List<String> captures = ac.getAllValues();
Assert.assertEquals(USERNAME, captures.get(0));
Assert.assertEquals(PASSWORD, captures.get(1));
Mockito.verify(view).showSignInScreen();
}
}
Note that the verifcation of the trySignIn call is not really necessary, as your test does not work if the behaviour definition on the mock is not invoked. So this is already verified by the flow of the test.
Also try to follow the Java Naming Conventions: Class Names / Interface names should start with an uppercase letter. That usually makes the code easier to read.
I'm trying to create immutable configuration by creating an interface and its implementation that is of package private. Only the interface is exposed to the client; the implementation is hidden and cannot be called outside of the package. Interface has accessors and mutators and a static method that instantiates its implementation and returns itself. Whenever mutator is called a new instance is being created passing all the fields in the constructor in order not to change the original values of the first object.
Here are my codes:
package com.example.api;
public interface Config {
static Config newConfig() {
return new ConfigImpl();
}
String host();
Config host(String host);
int port();
Config port(int port);
String database();
Config database(String database);
String user();
Config user(String user);
String password();
Config password(String password);
}
package com.example.api;
class ConfigImpl implements Config {
private final String host;
private final int port;
private final String database;
private final String user;
private final String password;
public ConfigImpl() {
this(null, -1, null, null, null);
}
public ConfigImpl(String host, int port, String database, String user, String password) {
this.host = host;
this.port = port;
this.database = database;
this.user = user;
this.password = password;
}
#Override
public String host() {
return host;
}
#Override
public Config host(String host) {
return new ConfigImpl(host, port, database, user, password);
}
#Override
public int port() {
return port;
}
#Override
public Config port(int port) {
return new ConfigImpl(host, port, database, user, password);
}
#Override
public String database() {
return database;
}
#Override
public Config database(String database) {
return new ConfigImpl(host, port, database, user, password);
}
#Override
public String user() {
return user;
}
#Override
public Config user(String user) {
return new ConfigImpl(host, port, database, user, password);
}
#Override
public String password() {
return password;
}
#Override
public Config password(String password) {
return new ConfigImpl(host, port, database, user, password);
}
}
Sample program that uses the API:
import com.example.api.Config;
public class App {
public static void main(String[] args) {
Config config = Config.newConfig()
.host("localhost")
.port(7000)
.database("mydb")
.user("admin")
.password("pwd");
config.database("mydb2"); // won't change 'mydb'
Config config2 = config.database("mydb2"); // needs to be assigned to new instance
System.out.println(config.host() + "|" + config.port() + "|" + config.database() + "|" + config.user() + "|" + config.password());
System.out.println(config2.host() + "|" + config2.port() + "|" + config2.database() + "|" + config2.user() + "|" + config2.password());
}
}
This is working as expected:
localhost|7000|mydb|admin|pwd
localhost|7000|mydb2|admin|pwd
My concern is, is this a good design? Does it affect memory and performance since every mutator/setter creates a news instance?
I would prefer this over builder pattern if there's nothing wrong with my current design.
Thanks.
A builder should probably have a separate build() method to perform final set of operations e.g. validations on multiple fields that can't be addressed with just method signatures. It feels cleaner:
Config config = Config.newConfig()
.host("localhost")
.build();
The only concerning thing about your design is:
The amount of boilerplate code that has to be written by hand to make this work. Perhaps it's worth it in the end but if you plan to implement this for multiple types you should consider something to auto-generate the code e.g. Lombok #Builder.
Since you are not using regular getXXX() and setXXX() methods some frameworks that depend on the property method notation won't be able to process your class. Might be completely irrelevant in your case.
This is a very simple example of my project which is a lot more bigger in scale.
Tasks:
The password will be set at the setpassword method.
The getpassword method will return the password.
The password is called at sendmail class in order to be send via email to the user to log in with the new credentials.
But When I run the whole code everything works except that the sendmail class won't access the password from the getpassword method in users class.
I put a simple version of my code:
users class >>>>>
public class users {
private String password;
public users (){}
// GETTING PASSWORD
public String getpassword(){
return password;
}
// SETTING PASSWORD
public void setapassword(String password){
this.password=password;
}
}
Signup class>>>>>>
public class signup {
public void signsup(){
users user1 =new users();
user1.setapassword("player");
sendmail mail1 =new sendmail();
mail1.Sendsmail();
}
}
sendmail class>>>>
public class sendmail {
public void Sendsmail(){
users user1 =new users(); // object
user1.getpassword(); //getting password
System.out.println(user1.getpassword()); // If print here I get null
}
}
Main signup Class>>>>
public class SignupMain {
public static void main(String[] args) {
signup signup1= new signup();
signup1.signsup();
}
}
The user1 object from your signup class and your sendmail class are different. Surely their variable is named the same way but they refer to different Objects. To access the password from the user you have to pass the user to the sendmail class e.g.:
Signup.java
public class signup
{
public void settingPassowrd()
{
users user1 = new users();
user1.setapassword( "player" );
sendmail mail1 = new sendmail();
mail1.Sendsmail(user1);
}
}
with:
public class sendmail
{
public void Sendsmail(user usr)
{
usr.getpassword(); // getting password
System.out.println( usr.getpassword() ); // will be the proper value from now on.
}
}
Please follow the standard coding conventions. I changed your code with standard coding conventions. just copy paste it , it will work
Users class
public class Users {
private String password;
public users (){}
// GETTING PASSWORD
public String getpassword(){
return password;
}
// SETTING PASSWORD
public void setapassword(String password){
this.password=password;
}
}
Signup class
public class Signup {
public void settingPassowrd(){
Users user1 =new Users();
user1.setapassword("player");
SendMail mail1 =new SendMail(user1);
mail1.Sendsmail();
}
}
SendMail class
public class SendMail {
private Users user1;
SendMail(Users user1){
this.user1 = user1
}
public void sendMail(){
user1.getpassword(); //getting password
System.out.println(user1.getpassword()); // If print here I get null
}
}
Main class to test the code
public class SignupMain {
public static void main(String[] args) {
Signup signup1= new Signup();
signup1.settingPassowrd();
}
}
Problem is that in your sendmail class you create a new user users user1 =new users(); --> so you don't access the user you previously created, but you create a new one which obviously does not have a password.
Instead, pass your user to the sendmail function in the signup class:
public void settingPassowrd(){
users user1 =new users();
user1.setapassword("player");
sendmail mail1 =new sendmail();
mail1.Sendsmail(user1);
}
and in class sendsmail:
public void Sendsmail(users user) {
System.out.println(user.getpassword());
}
By the way, I suggest you read some coding guidelines for Java. for example:
Class names should always start with a capital letter
Class names are usually singular (class users --> class User)
Method names always start with a lowercase letter and use camelCase (getpassword() --> getPassword())
I defined a Logininfo class to store the email and password of a user in. I get the email and password from a Login GUI. There are put into the Logininfo class using setMethods. I'm connecting the programming to a mysql server (mysql is not an issue here). I need the the emailadres and password so I can use it for queries in other GUI's later on.
This is the Logininfo class
public class Logininfo {
public static Emailadres emailadres = new Emailadres();
public static Password password = new Password();
public static class Emailadres
{
private String emailadres;
public Emailadres()
{
emailadres = " ";
}
public void setEmailadres(String emailadres)
{
this.emailadres = emailadres;
}
public String getEmailadres()
{
return(emailadres);
}
}
public static class Password
{
private String password ;
public Password()
{
password = " ";
}
public void setPassword(String password)
{
this.password = password;
}
public String getPassword()
{
return(password);
}
}
}
In the login GUI I use the setMethod to store the emailadress and password.
public class Login extends javax.swing.JFrame {
Logininfo logininfo;
Logininfo.Emailadres emailadres = new Logininfo.Emailadres();
Logininfo.Password password = new Logininfo.Password();
private boolean validate_login(String email,String wachtwoord) {
emailadres.setEmailadres(email);
wachtwoord.setPassword(password);
Later on I try to retrieve the emailadress and password in another class.
public class Account extends javax.swing.JFrame {
Logininfo logininfo;
Logininfo.EmailAdres emailadres;
Logininfo.WachtWoord password;
emailadres.getEmailadres(email);
password.getPassword(password);
I get a Nullpointerexception here. I know that you have to make a new instance of Logininfo in the Login GUI screen. However in the Account class you can't make another new instance. Are public class not supposed to be used for this and should I use something else?
Any help would be appreciated
email_adres in your Login class is an instance field of that class, and is completely unrelated to emailadres instance field of Account class. The two pointers point to different places in memory.
If you want the instance of Account to have that data from Login instance, you have to give it to it somehow.
I have a GUI that has 2 JTextFields- EmailLoginField and jPasswordField1. Ill just discuss the EmailLoginField and just duplicate what is recommended on jPasswordField1 too.
So heres some GUI code:
package p;
imports ...
public class EmailLoginGUI extends javax.swing.JFrame {
public EmailLoginGUI() {
initComponents();
}
private void initComponents() {
...
EmailLoginField = new javax.swing.JTextField();
}
...
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
EmailMainGUI open = new EmailMainGUI();
open.setVisible(true);
This next code snippet is what I have tried to do to get the text from the JTextField EmailLoginField in EmailLoginGUI.java
public String getEmailLoginField(){
return EmailLoginField.getText();
}
public String getjPasswordField(){
return jPasswordField1.getText();
}
Here is the next part (not assuming the code immediately above is correct). This next code is an entirely different public class, which same package of course. Here is what I have tried it should look at the EmailLoginGUI class and get the JTextField content, eventually storing it as a String.
PLEASE NOTE: the final strings that contain the JTextField content MUST NOT be inside the SendEmail(EmailLoginGUI c1, EmailLoginGUI c2){. They should be just outside of it just inside public class SendEmail { this is so that they can be used by other code later.
package p;
imports ...
public class SendEmail {
JTextField userTF;
JPasswordField passPF;
SendEmail(EmailLoginGUI c1, EmailLoginGUI c2){
userTF.setText(c1.getEmailLoginField());
passPF.setText(c2.getjPasswordField());
}
public String user(){
return userTF.getText();
}
public String pass() {
return passPF.getText();
}
...
SendEmail(...) {
Properties props = new Properties();
...
Session session = Session.getInstance(props, new javax.mail.Authenticator()
{
protected javax.mail.PasswordAuthentication getPasswordAuthentication()
{
return new javax.mail.PasswordAuthentication(user(), pass()); //This is where the final strings need to go.
}
});
Hopefully what I am trying to do is clear:
Get the content from JTextField created in EmailLoginGUI.java. Get this into SendEmail.java. Its final type should be String and is 'just on the inside' of the public class SendEmail. I have had everything from NullPointerException to Cannot find symbol for hours! Think I've been attempting it for so long that I could benefit from some fresh eyes!
Help would be greatly appreciated.
In SendEmail class create Constructor which has an argument of user input
SendEmail(String userInput) {
//Your Code
}
In EmailLoginGUI create
String userInput = EmailLoginField.getText().toString();
SendEmail sendemail = new SendEmail(userInput);
This method works I have used it. Hope it helps.
I realised both the security risk and how a dialogue would be easier, however I don't have time to go back to change it really. I have already coded the listener too so that's not a problem. But yes that's what I want to do! Where am I going wrong?
Then you need to implement some kind of Observer Pattern.
Start by defining the expected operations that the login view might generate, for example, it's reasonable to expect that the user can either accept or cancel the view
public interface EmailLoginListener {
public void emailLoginWasAccepted(EmailLoginGUI gui);
public void emailLoginWasCanceled(EmailLoginGUI gui);
}
Update the view to provide support for the listener
public class EmailLoginGUI extends javax.swing.JFrame {
private List<EmailLoginListener> listeners;
public EmailLoginGUI() {
initComponents();
listeners = new ArrayList<>(25);
}
//...
public void addEmailLoginListener(EmailLoginListener listener) {
listeners.add(listener);
}
public void removeEmailLoginListener(EmailLoginListener listener) {
listeners.add(listener);
}
protected void fireLoginWasAccepted() {
for (EmailLoginListener listener : listeners) {
listener.emailLoginWasAccepted(this);
}
}
protected void fireLoginWasCanceled() {
for (EmailLoginListener listener : listeners) {
listener.emailLoginWasCanceled(this);
}
}
}
In your action handlers for your buttons on the EmailLoginGUI view, trigger the required event...
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
fireLoginWasAccepted();
}
Remember, you should also do this for the cancel operation if you have one.
Now, when you create an instance of EmailLoginGUI, make sure you also register a EmailLoginListener with it
EmailLoginGUI loginView = new EmailLoginGUI();
loginView.addEmailLoginListener(new EmailLoginListener() {
#Override
public void emailLoginWasAccepted(EmailLoginGUI gui) {
gui.dispose();
String email = gui.getEmailLoginField();
String password = gui.getjPasswordField();
EmailMainGUI open = new EmailMainGUI();
open.setCredentials(email, password);
//...
open.setVisible(true);
}
#Override
public void emailLoginWasCanceled(EmailLoginGUI gui) {
// Exit the program?
gui.dispose();
}
});
//...
loginView.setVisible(true);
This will require you to either change the constructor of EmailMainGUI to accept the email and password or a method to pass that information to the class (as I've demonstrated above)
Finally change SendEmail to accept String values instead of your gui components
public class SendEmail {
String email;
String password;
SendEmail(String email, String password) {
this.email = email;
this.password = password;
}
public String user() {
return email;
}
public String pass() {
return password;
}
}