Form onSubmit() not being called after upgrade to Wicket 7 - java

I'm in the process of upgrading our web app to use Wicket 7 (was using 6.19).
The first page is a login screen, but for some reason, the form's onSubmit() method isn't being called, so on clicking the submit button, I just get the login page re-displayed.
I've consulted the Wicket 7 migration guide, which doesn't mention any specific changes in this area.
It's a pretty straightforward case, as you can see, it's a simple form containing username and password fields
<form wicket:id="loginform" id="loginform" >
<table style="display: table; border: 0px; margin: auto;">
<tr style="display: table-row;">
<td class="login" colspan="2"><span wicket:id="feedback">Feedback</span></td>
</tr>
<tr style="display: table-row;">
<td class="login">
<label for="username"><wicket:message key="username">Username</wicket:message>: </label>
</td>
<td class="login">
<input wicket:id="username" id="username" type="text" name="user" value="" size="30" maxlength="50"/>
</td>
</tr>
<tr style="display: table-row;">
<td class="login">
<label for="password"><wicket:message key="password">Password</wicket:message>: </label>
</td>
<td class="login">
<input wicket:id="password" id="password" type="password" name="pswd" value="" size="30" maxlength="16"/>
</td>
</tr>
<tr style="display: table-row;">
<td class="login"> </td>
<td class="login"><input class="btn" type="submit" name="Login" value="Login" wicket:message="title:loginButtonTitle"/></td>
</tr>
</table>
</form>
Here's the Java code setting up the page components -
public class Login extends UnSecurePageTemplate {
private static final long serialVersionUID = -7202246935258483555L;
#SpringBean private IBrandingService brandingService;
#SpringBean private IRemonService remonService;
#SpringBean private IUserAdminService userAdminService ;
private static final Logger logger = LoggerFactory.getLogger( Login.class);
public Login() {
this(new PageParameters());
}
public Login(PageParameters pageParameters) {
super(pageParameters);
BrandingThemeProperties properties = brandingService.getBrandingThemeProperties();
String welcomeLabel = properties.getProperty("welcome-label");
add(new Label("welcome", welcomeLabel));
add(new Label("loginHeader", getStringFromPropertiesFile("loginInstruction", this)));
LoginForm form = new LoginForm("loginform", new SimpleUser(), pageParameters);
form.add(new FeedbackPanel("feedback"));
add(form);
}
And here's the Login form (the login() method authenticates the user and returns another page) -
public final class LoginForm extends Form<SimpleUser>
{
PageParameters pageParameters;
public LoginForm(String id, SimpleUser simpleUser, PageParameters pageParameters)
{
super(id, new CompoundPropertyModel<SimpleUser>(simpleUser));
this.pageParameters = pageParameters;
add(new TextField<String>("username").setRequired(true).add(StringValidator.maximumLength(50)));
add(new PasswordTextField("password").setResetPassword(true).add(StringValidator.maximumLength(50)));
}
/**
* Called upon form submit. Attempts to authenticate the user.
*/
protected void onSubmit()
{
SimpleUser user = getModel().getObject();
String username = user.getUsername();
String password = user.getPassword();
login(username, password, pageParameters);
}
}
I also tried using a submit Button, but its onSubmit() wasn't called either.

Related

Passing thymeleaf information to a hidden form

I am trying to pass the information from a thymeleaf list and trying to add it to database.
I am getting data from the tmdb and it will be changing so i display the information obtain to the endpoint "/LatestMovies" this information is not saved in the db and ether should it be. so i am trying to add a save button for the custumer to add the movie listed.(its simple it just haves movieid and moviename)
Showing the movies listed i have no problem and it works fine but where i get error is when i add a hidden form. The current code i have is this:
<div class="container">
<table class="table table-hover">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr th:each="LatestMovies : ${latestMovies}">
<td th:text="${LatestMovies.id}"></td>
<td th:text="${LatestMovies.movieName}"></td>
<td>
<form action="#" th:action="#{/LatestMovies}" th:object="${addMovies}" method="post">
<p><input type="hidden" th:field="*{id}" th:attr="value = ${LatestMovies.id}" /></p>
<p><input type="hidden" th:field="*{movieName}" th:attr="value = ${LatestMovies.movieName}" /></p>
<p><input type="submit" value="Submit" /></p>
</form>
</td>
</tr>
</table>
#Controller
public class LatestMoviesController {
#Autowired
private LatestMoviesDao listOfMovies;
#Autowired
private savedMoviesDao movieRepo;
#GetMapping("/LatestMovies")
public String prueba(Model model) {
TmdbMovies movies = new TmdbApi("22914f477aaa3e7f86c6f5434df8d1eb").getMovies();
ResultsPage<MovieDb> movie = movies.getPopularMovies("en", 1);
for(int i=0; i <= 19; i++){
int movieId = movie.getResults().get(i).getId();
String movieName = movie.getResults().get(i).toString();
listOfMovies.save(new LatestMovies(movieId, movieName));
}
model.addAttribute("latestMovies", listOfMovies.findAll());
return "index";
}
#PostMapping("/LatestMovies")
public String save(#ModelAttribute("addMovies") Model model, SavedMovies addMovies) {
movieRepo.save(addMovies);
return "index";
}
}
Thx in advance
First, let's change your form. You don't need to add a new object to it, since you are already iterating through a list of them. That way, you will also avoid having to add the value for each field manually using th:attr. What we are gonna do, is send the required params separately and then build our movie object with them.
<div class="container">
<table class="table table-hover">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr th:each="LatestMovies : ${latestMovies}">
<td th:text="${LatestMovies.id}"></td>
<td th:text="${LatestMovies.movieName}"></td>
<td>
<form th:action="#{/LatestMovies}" method="post">
<p><input type="hidden" th:value="${LatestMovies.id}" name="id"/></p>
<p><input type="hidden" th:value="${LatestMovies.movieName}" name="name"/></p>
<p><input type="submit" value="Submit"/></p>
</form>
</td>
</tr>
</table>
</div>
Now, on your controller, do the following modifications.
#PostMapping("/LatestMovies")
public String save(#RequestParam("id") Integer id, #RequesParam("name") String name) {
SavedMovies movie = new SavedMovies();
movie.setId(id);
movie.setName(name);
movieRepo.save(movie);
return "index";
}
These changes should do the trick.

Wicket AjaxButton does not update FeedbackPanel

I am trying to send a success message to a FeedbackPanel in Wicket, if an AjaxButton was clicked. Yet I recieve the following error message:
Wicket.Ajax.Call.processComponent: Component with id [[065DFC0DD1DC51103CC5FFEE61F2AE12]] was not found while trying to perform markup update.
I am already aware, that I have to output the markupID in the Java Code before I use the AjaxButton and set the target in the onSubmit. I also set setOutputMarkupPlaceholderTag once, yet it changed nothing.
I have also created a small test page, where I succeeded in sending the success message to the FeedbackPanel.
I thus started to debug the project and found out that the markupID returned from DefaultMarkupIdGenerator.generateMarkupId was indeed different that the one displayed in the HTML. Additionally all FeedbackPanels recieve this markupID during the ajax call.
feedbackPanelWartung12 vs. 065DFC0DD1DC51103CC5FFEE61F2AE12
To further complicate things, my FeedbackPanel is within a RepeatingView contained in a Panel within a page already containing a FeedbackPanel (inherited from its superclasses). The structure goes as follows:
Java Code
MyPage
public MyPage extends MySuperPage{
//Constructors were left out
//this method is called in the onInitialize of some
//super class.
#Override
protected Component newContent() {
setFeedbackPanelFilter();
return new MyContainerPanel();
}
//this FeedbackPanel shall not recieve messages from child containers
private void setFeedbackPanelFilter() {
((FeedbackPanel) this.get("feedback"))
.setFilter( new ContainerFeedbackMessageFilter(this) {
#Override
public boolean accept(FeedbackMessage message) {
return !super.accept(message);
}
});
}
}
MyContainerPanel
public MyContainerPanel extends Panel {
//Constructors were left out
#Override
protected void onInitialize() {
super.onInitialize();
RepeatingView repeater = new RepeatingView("repeater");
add(repeater);
for (Object o : objects) {
String id = repeater.newChildId();
repeater.add(new MyPanel(id,o));
}
}
}
MyPanel
public MyPanel extends Panel {
private Object o;
private CheckBox chkBox;
private DateTimeField startDate, endDate;
private TextField<String> message;
private Form<Object> form;
private AjaxButton button;
private Label name;
private FeedbackPanel feedbackPanel;
//Constructors were left out
#Override
protected void onInitialize() {
super.onInitialize();
initFields();
addFields();
addAjaxButton();
addAjaxFormComponentUpdatingBehavior();
if (!o.isMaintenance())
disableFields();
}
private void addAjaxButton() {
button = new AjaxButton("submit") {
#Override
public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
//do something
feedbackPanel.success("Speichern erfolgreich");
target.addChildren(AppWartungPanel.this.getPage(), FeedbackPanel.class);
}
};
form.add(button);
}
private void addAjaxFormComponentUpdatingBehavior() {
chkBox.add(new AjaxFormComponentUpdatingBehavior("onchange") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
switchVisibility();
target.add(startDate);
target.add(endDate);
target.add(message);
target.add(feedbackPanel);
}
});
}
private void switchVisibility() {
if (o.isMaintenance())
enableFields();
else
disableFields();
}
private void addFields() {
add(form);
form.add(feedbackPanel);
form.add(chkBox);
form.add(startDate);
form.add(endDate);
form.add(message);
form.add(name);
}
private void initFields() {
form = new Form<WartungDAO>("form", AppWartungPanel.this.getModel());
chkBox = new CheckBox("wartung", new PropertyModel<Boolean>(o, "wartung"));
chkBox.setOutputMarkupId(true);
startDate = new DateTimeField("startDate", new PropertyModel<Date>(o, "startDate"));
startDate.setOutputMarkupId(true);
startDate.setRequired(true);
endDate = new DateTimeField("endDate", new PropertyModel<Date>(o, "endDate"));
endDate.setOutputMarkupId(true);
endDate.setRequired(true);
message = new TextField<String>("message", new PropertyModel<String>(o, "message"));
message.setOutputMarkupId(true);
message.setRequired(true);
name = new Label("name", new PropertyModel<String>(o, "portal"));
feedbackPanel = new FeedbackPanel("feedbackPanelWartung");
feedbackPanel.setOutputMarkupId(true);
feedbackPanel.setFilter(new ContainerFeedbackMessageFilter(this));
}
private void disableFields() {
startDate.setEnabled(false);
endDate.setEnabled(false);
message.setEnabled(false);
}
private void enableFields() {
startDate.setEnabled(true);
endDate.setEnabled(true);
message.setEnabled(true);
}
}
HTML markup
MyPage
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<body class="BG_MAIN">
<div class="grid_16 BG1_GLOBAL">
<div style="margin:10px;">
<div class="grid_3 alpha">
<wicket:container wicket:id="menu"></wicket:container>
</div>
<div class="grid_12 omega">
<div class="INHALT">
<h1 wicket:id="appHeader" style="margin-top: 0;"></h1>
<div wicket:id="wartung" />
<div wicket:id="feedback"></div>
<wicket:container wicket:id="content"></wicket:container>
</div>
</div>
</body>
</html>
MyContainerPanel
<html xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<div wicket:id="repeater">
</div>
</wicket:panel>
</html>
MyPanel
<html xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
<div style="margin-left: 25px; margin-top: 25px;">
<form wicket:id="form">
<h2 wicket:id="name"></h2>
<div wicket:id="feedbackPanelWartung"></div>
<table style="border: none;">
<tbody>
<tr>
<td style="border: none;">Wartung aktiv?</td>
<td style="border: none;">
<input wicket:id="wartung" type="checkbox" />
</td>
</tr>
<tr>
<td style="border: none;">Nachricht zum Anzeigen:</td>
<td style="border: none;">
<input wicket:id="message" type="text" size="50" />
</td>
</tr>
<tr>
<td style="border: none;">Startdatum</td>
<td style="border: none;">
<div wicket:id="startDate"></div>
</td>
</tr>
<tr>
<td style="border: none;">Enddatum</td>
<td style="border: none;">
<div wicket:id="endDate"></div>
</td>
</tr>
<tr>
<td style="border: none;"></td>
<td style="border: none;">
<input wicket:id="submit" type="submit" value="Speichern" style="float: right;" />
</td>
</tr>
</tbody>
</table>
</form>
</div>
</wicket:panel>
</html>
I can only guess that the error is due to the complexity of the page.
I also disabled the AjaxFormComponentUpdatingBehavior to check if it messes with the AjaxButton - It did not.
I also implemented everything with a normal Button, to check if the ContainerFeedbackMessageFilter and the FeedbackPanels worked - they did.
The AjaxButton is not crucial to the Page. Yet I would really like to understand, so if anybody has another nice idea to try out...
FeedbackPanel feedbackPanel = new FeedbackPanel("feedbackPanelWartung") {
#Override
public String getMarkupId() {
return "feedbackPanelWartung." + someUniqueValuePassedToThePanel;
}
};
feedbackPanel.setOutputMarkupId(true);
As luck had it, I had a unique value in one modelObject of the panel. I then overwrote the Component.getMarkupId() method and simply set my Id.
Worked like a charm.
I also found out, that the method feedbackPanel.setOutputMarkupId(true); Was irrelevant to my error message.
In other words: even if I tried to set the markup id for my component, it was never set in the first place and thus the ajax component was, rightfully so, never able to find a target.

Execute a java class method from JSP in Spring MVC

I'm working e-commerce store project using spring mvc. In a JSP login page, i need to check user name and user password after clicking submit button. If all information are ok then i'm gonna go to the next page, otherwise stay on the same page.
This is my Administrator class(Model) Administrator.java
#Entity
#Table(name="ADSMINISTRATOR")
public class Administrator {
#Id
private String userName;
private String userPassword;
//getter and setter
}
This is my controller class AdministratorController.java
#Controller
#RequestMapping(value="/administratorController")
public class AdministratorController {
#RequestMapping(value="/loginForm.html")
public ModelAndView getAdministratorLoginForm() {
return new ModelAndView("Administrator");
}
public ModelAndView goToMainPage(#ModelAttribute("administrator") Administrator administrator) {
//Checking userName and userPassword here
//if ok then
return new ModelAndView("mainPageDemo");
}
}
And this is my JSP(View) Administrator.jsp
<body>
<table>
<tr> <td>User Name: </td> <td><input type="text" name="userName" value="" placeholder="User Name"></input></td> </tr>
<tr> <td>User Password: </td> <td><input type="text" name="userPassword" value="" placeholder="User Password"></input></td> </tr>
<tr><td><input type="submit"></input></td> </tr>
</table>
</body>
</html>
Now When I click submit button in Administrator.jsp page, I need to execute goToMainPage() method in AdministratorController.java class. How can i do this?

Java – How can I Log into a Website with HtmlUnit?

I am writing a Java program to log into the website my school uses to post grades.
This is the url of the login form: https://ma-andover.myfollett.com/aspen/logon.do
This is the HTML of the login form:
<form name="logonForm" method="post" action="/aspen/logon.do" autocomplete="off"><div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="30883f4c7e25a014d0446b5251aebd9a"></div>
<input type="hidden" id="userEvent" name="userEvent" value="930">
<input type="hidden" id="userParam" name="userParam" value="">
<input type="hidden" id="operationId" name="operationId" value="">
<input type="hidden" id="deploymentId" name="deploymentId" value="ma-andover">
<input type="hidden" id="scrollX" name="scrollX" value="0">
<input type="hidden" id="scrollY" name="scrollY" value="0">
<input type="hidden" id="formFocusField" name="formFocusField" value="username">
<input type="hidden" name="mobile" value="false">
<input type="hidden" name="SSOLoginDone" value="">
<center>
<img src="images/spacer.gif" height="15" width="1">
<script language="JavaScript">
document.forms[0].elements['deploymentId'].value = 'ma-andover';
</script>
<script language="JavaScript">
$(function()
{
$('form').attr('autocomplete', 'off');
var name = $('#username');
var password = $('#password');
name.attr('autocomplete', 'off');
password.attr('autocomplete', 'off');
if (name.val() == '')
{
password.attr('disabled','disabled');
}
});
</script>
<img src="images/spacer.gif" height="30" width="1">
<table border="0" cellpadding="0" cellspacing="0">
<tbody><tr>
<td>
<div id="logonDetailContainer" class="logonDetailContainer">
<table border="0" cellpadding="0" cellspacing="0">
<tbody><tr>
<td>
<label style="text-align: center; margin-bottom: 0px">Andover Public Schools</label>
<img src="images/spacer.gif" height="10" width="1">
<hr class="logonHorizontalRule">
</td>
</tr>
<tr>
<td>
<img src="images/spacer.gif" height="10" width="1">
<input type="text" name="fakeuser" style="display: none">
<input type="password" name="fakepassword" style="display: none">
</td>
</tr>
<tr>
<td class="labelCell">
<label>Login ID</label>
<input type="text" name="username" tabindex="1" value="" onkeypress="$('#password').prop('disabled', false)" id="username" class="logonInput" autocomplete="off">
</td>
</tr>
<tr>
<td class="labelCell">
<label>Password</label>
<input id="password" type="password" name="password" tabindex="2" value="" class="logonInput" autocomplete="off" disabled="disabled">
<a href="javascript:EmbeddedPopup.popupManager.open('passwordRecovery.do?isSecondary=false&deploymentId=ma-andover', 400, 400, 100)" tabindex="5" style="float: right">
I forgot my password
</a>
</td>
</tr>
<tr>
<td width="1" class="logonTopPadding" style="float: left">
<input type="submit" tabindex="3" value="Log On" class="log-button">
</td>
</tr>
</tbody></table>
</div>
</td>
</tr>
</tbody></table>
</center>
<script>
setTimeout(function(){window.location.reload(true);}, 1800000);
</script>
</form>
I am trying to use the following code to log in:
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class LoginAttempt {
public static void main(String[] args) throws Exception {
WebClient webClient = new WebClient();
HtmlPage page = (HtmlPage) webClient.getPage("https://ma-andover.myfollett.com/aspen/logon.do");
HtmlForm form = page.getFormByName("logonForm");
form.getInputByName("username").setValueAttribute("myUsername"); //works fine
form.getInputByName("password").setValueAttribute("myPassword"); //does not work
page = form.getInputByValue("Log On").click(); //works fine
System.out.println(page.asText());
}
}
The program fills the username box and clicks the "Log On" button, but it does not fill the password box. What can I change to make this program work? I suspect the "type = 'password'" attribute of the password box has something to do with the problem, but please correct me if I am wrong. Any help is appreciated. Thank you very much.
The target page: https://ma-andover.myfollett.com/aspen/home.do
And this is my output, in case it might be helpful:
Aspen: Log On
Aspen
About Aspen
Andover Public Schools
Login ID myUsername
Password I forgot my password
Log On
Copyright © 2003-2014 Follett School Solutions. All rights reserved.
Follett Corporation Follett Software Company Aspen Terms of Use
You must enter a password.
OK
The password field is disabled until you type something in the username field.
By setting the value in username doesn't trigger the event that manages the enabling of password field.
The below works
public static void main(String[] args) {
WebClient webClient = new WebClient();
try {
HtmlPage page = (HtmlPage) webClient
.getPage("https://ma-andover.myfollett.com/aspen/logon.do");
HtmlForm form = page.getFormByName("logonForm");
form.getInputByName("username").setValueAttribute("myUsername");
HtmlInput passWordInput = form.getInputByName("password");
passWordInput.removeAttribute("disabled");
passWordInput.setValueAttribute("myPassword");
page = form.getInputByValue("Log On").click(); // works fine
System.out.println(page.asText());
} catch (Exception e) {
e.printStackTrace();
} finally {
webClient.close();
}
}
The output is
Aspen: Log On
Aspen
About Aspen
Andover Public Schools
Login ID myUsername
Password I forgot my password
Log On
Copyright © 2003-2014 Follett School Solutions. All rights reserved.
Follett Corporation Follett Software Company Aspen Terms of Use
Invalid login.
OK
To automatically handle the JavaScript, you should use type() instead.
try (WebClient webClient = new WebClient()) {
HtmlPage page = (HtmlPage) webClient.getPage("https://ma-andover.myfollett.com/aspen/logon.do");
HtmlForm form = page.getFormByName("logonForm");
form.getInputByName("username").type("myUsername");
form.getInputByName("password").type("myPassword");
page = form.getInputByValue("Log On").click();
System.out.println(page.asText());
}
I used:
final WebClient webClient = new WebClient())
HtmlPage page = webClient.getPage("url");
((HtmlTextInput) page.getHtmlElementById("usernameID")).setText("Username");
page.getHtmlElementById("passwordID").setAttribute("value","Password");
page.getElementsByTagName("button").get(0).click();
System.out.println(page.asText());
I clicked the button that way because my button doesn't have an id, name, or value, but luckily its the only button on the page. So I just get all the button tags (all one of them) and select the first element in the List to click.

Autofill fields in web view android

I am creating an application which shows an external website in a webview. I want to fill the username and password fields of that web view with my custom values, but i am not finding any success to do so:
HERE IS THE WEBSITE PAGE SOURCE SNIPPET:
<form name="LoginForm" method="post" action="https://xyz" onsubmit="document.LoginForm.Submit.disabled=true;">
<input type=hidden name="XXX" value="####www#">
<input type=hidden name="YYY" value="xyz.0">
<tr>
<td width="50%">Username
<font class=starmand align="absmiddle">*</font></td>
<td width="50%"><input type="text" name="userName" class="txtfld" autocomplete="off" size="12"/>
</td>
</tr>
<tr>
<td>Password
<font class=starmand align="absmiddle">*</font></td>
<td><input type="password" name="password" size="12" value="" class="txtfld">
</td>
</tr>
<tr>
<td align="right" colspan="2"><input type="submit" name="Submit" value="GO" onclick="return xyz();" class="btnSubmit"></td>
</tr>
</table></td>
</table>
</tbody>
</form>
And here is my Android Code Snippet:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
browser = (WebView)findViewById(R.id.webView1);
browser.setWebViewClient(new MyBrowser());
browser.getSettings().setLoadsImagesAutomatically(true);
browser.getSettings().setJavaScriptEnabled(true);
browser.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
browser.loadUrl(AppConstants.LOGIN_URL);
}
private class MyBrowser extends WebViewClient {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String TAG="onPageFinished";
Logger.i(TAG,"Called..");
if(url.equals(AppConstants.LOGIN_URL)) {
Logger.i(TAG,"Login page load done..");
updateStatus("Login Page Loaded..!",TYPE_GREEN);
browser.loadUrl(getLoginScript("USER_NAME","PASS_WORD"));
}
}
}
public static String getLoginScript(String userName,String password){
return "javascript: {" +
"document.getElementsByName('userName').value = '"+userName +"';" +
"document.getElementsByName('password').value = '"+password+"'; };";
}
On the Running the above code:
-I get a new web Page with a text as USER_NAME
Please Help me!
I need to get this working...
Thanks in advance.
It looks like you're loading it as a default of "USER_NAME". To me it would be make more sense if the field is populated with the text "USER_NAME" since you pass that string as a parameter like below:
browser.loadUrl(getLoginScript("USER_NAME","PASS_WORD"));

Categories

Resources