This question already has an answer here:
How to check for an unique user with jQuery Ajax in Struts 2?
(1 answer)
Closed 6 years ago.
I'm building a web app using Struts2 as a framework. As the title suggest, I'm attempting to check availability of a username using an AJAX call (open to other suggestions if there is something easier that accomplishes the same result.)
Right now I'm having two issues:
Request is null in my doPost function.
Even if I set uname to a string, nothing happens.
Here is what I have for code.
Login.jsp
<s:form action="login.action" method="post" data-parsley-validate="">
<s:textfield name="user.username" key="Username" id="username" onchange="checkUsername()"/><span class="status"></span>
<s:submit method="doTheThing" align="center" onclick="hide()"/>
</s:form>
Javascript
function checkUsername(){
var uname = $(username).val();
if (uname.length > 3) {
$(".status").html("Checking availability...");
$.ajax({
type : "POST",
url : "usernameCheck.action",
data : "uname=" + uname,
success : function(msg) {
$(".status").ajaxComplete(
function(event, request, settings) {
$(".status").html(msg);
});
}
});
}
else {
$(".status").html("username should be at least 3 characters");
}
}
check.java
public class check extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ActionSupport connectionSupport = new ActionSupport();
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
Connection connection = null;
String URL = "172.ExampleIP";
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(URL, "user","pass");
String uname = request.getParameter("user.username");
PreparedStatement ps = connection.prepareStatement("select username from users where username=?");
ps.setString(1, uname);
ResultSet rs = ps.executeQuery();
if (!rs.next()) {
out.println("<b>" + uname + "</b> is avaliable");
} else {
out.println("<font color=red><b>" + uname + "</b> is already in use</font>");
}
out.println();
} catch (Exception ex) {
out.println("Error ->" + ex.getMessage());
} finally {
out.close();
}
}
public void doGet()
throws ServletException, IOException {
doPost(ServletActionContext.getRequest(), ServletActionContext.getResponse());
}
}
Struts.xml
<action name="usernameCheck" class="java.com.my.package.check" method="doGet"></action>
I'm not sure if this is important information, but the form is on a JQuery modal box.
I found my solution. I changed my java class to extend ActionSupport based on Andrea's suggestion. I changed my struts action result to be of type stream.
<action name="usernameCheck" class="java.com.my.package.check" method="doGet">
<result type="stream">
<param name="contentType">text/html</param>
<param name="inputName">stream</param>
</result>
</action>
I added the following to my java class
private InputStream stream;
public InputStream getStream() {
return stream;
}
And changed my JavaScript success function to the following:
success : function(msg) {
$(".status").html(msg);
}
Thank you all for all the input.
Related
I want to check if user's email and password from database is correct while logging in and make notifications for 3 scenarious:
wrong email;
wrong password;
both are incorrect.
I don't know how to check separate email from password and vice versa.
Could you please advise me how to modify else if conditions in User.Login.java file.
Thanks!
User.Login.java file:
import dao.UserDao;
#WebServlet("/servlets.UserLogin")
public class UserLogin extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
.......
String userEmail=request.getParameter("email");
String userPassword=request.getParameter("password");
// Successful login. Redirecting to navlibrarian.html
if(UserDao.authenticate(userEmail, userPassword)){
HttpSession session=request.getSession();
session.setAttribute("email",userEmail);
request.getRequestDispatcher("navlibrarian.html").include(request, response);
}
// Unsuccessful login due to wrong password. User stays on the same page index.html
else if (...how to check here if email is correct and password is not?...)){
request.getRequestDispatcher("index.html").include(request, response);
out.println("<h3>Wrong password</h3>");
// Unsuccessful login due to wrong email. User stays on the same page index.html
} else if (...how to check here if password is correct and email is not?...)){
request.getRequestDispatcher("index.html").include(request, response);
out.println("<h3>Wrong email</h3>");
// Unsuccessful login due to wrong email and password. User stays on the same page index.html
} else {
request.getRequestDispatcher("index.html").include(request, response);
out.println("<h3>User with such email and password not found</h3>");
}
request.getRequestDispatcher("footer.html").include(request, response);
out.close();
}
}
User.Login.java file:
public class UserDao {
.......
public static boolean authenticate(String email, String password){
boolean status=false;
try {
Connection con=DB.getCon();
PreparedStatement ps=con.prepareStatement("select * from e_librarian where email=? and password=?");
ps.setString(1,email);
ps.setString(2,password);
ResultSet rs=ps.executeQuery();
if(rs.next()){
status=true;
}
con.close();
} catch(Exception e){System.out.println(e);}
return status;
}
}
My Project Structure is this:
The body of my LoginPage is the following
<body>
<P id="errors"></P>
<p>Login Details</p>
<div id = "page"></div>
<table>
<tr>
<td> Login ID :</td>
<td><input type="number" id="loginid" min="1" max="200" style="width:169px;"/></td>
</tr>
<tr>
<td> Passowrd :</td>
<td><input type="password" id="password"/></td>
<tr>
</table>
<button id="loginB" onclick="login()">submit</button>
</body>
After Successful Login I would like to move from loginPage.jsp to home.jsp using JavaScript or Ajax. My code is
function login()
{
var name = document.getElementById("loginid").value;
var password = document.getElementById("password").value;
var url="/loginPage?name="+name+"&password="+password;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var responsetext=xhttp.responseText;
var parsedresult=JSON.parse(responsetext);
if(parsedresult.success==true)
{
window.location="home.jsp";
}
else
{
document.getElementById("errors").innerHTML=parsedresult.message;
}
}
};
xhttp.open("POST",url,true);
xhttp.send();
}
It wouldn't go to home.jsp and give a 404 Error. How to configure it to move to home.jsp ?
My Login API is the following. The LoginModel has hardcoded username and password that is used for validation. The loginmodel.validate() would return a string "false" if the credentials are incorrect.
#Controller
public class LoginController {
LoginModel loginmodel = new LoginModel();
#RequestMapping(value="/")
public ModelAndView redirect(HttpServletRequest request, HttpServletResponse response) throws IOException
{
return new ModelAndView("loginPage");
}
#RequestMapping(value="/loginPage",method=RequestMethod.POST)
public void login(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String sessionName = loginmodel.validate(request.getParameter("name"), request.getParameter("password"));
if(!sessionName.equals("false"))
{
HttpSession session = request.getSession();
session.setAttribute("name", sessionName);
JSONObject result= new JSONObject();
result.put("success", true);
response.setContentType("application/json");
response.getWriter().print(result);
}
else
{ JSONObject result= new JSONObject();
result.put("success", false);
result.put("message", "invalid credentials");
response.setContentType("application/json");
response.getWriter().print(result);
}
}
#RequestMapping(value="/logout")
public String logout(HttpServletRequest request, HttpServletResponse response) throws IOException
{
request.getSession().invalidate();
return "loginPage";
}
}
Please write one method in controller which returns home.jsp page like below :
#RequestMapping(value="/home")
public String logout(HttpServletRequest request, HttpServletResponse response) throws IOException
{
return "home";
}
AND then from your jsp page :
window.location="contextPath/home";
This is happenin after migrating my project to jsf2 on tomcat7. Earlier on tomcat5.5 for jsf 1 its was working fine. I have a .xhtml file from where I am trying to call a managed bean method through h:commandLink but its not being invoked. I have tried adding the EL 2.2 jars as suggetsed in other stackoverflow forums relating the same topic and also added the entries in web.xml :
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
but issue is not resolved. Please help.
.xhtml file :
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:t="http://myfaces.apache.org/tomahawk">
<f:view>
<f:loadBundle var="text" basename="#{basePage.bundleName}"/>
<title>#{text['user.passwordHint']}</title>
<p>Looking up password hint for ${param.username}...</p>
<h:form id="passwordForm">
<h:inputHidden id="username" value="#{passwordHint.username}"/>
<h:commandLink action="#{passworHint.execute}" id="execute">
<f:param name="username" value="${param.username}"></f:param>
</h:commandLink>
</h:form>
<script type="text/javascript">
var f = document.forms['passwordForm'];
f.elements['passwordForm:_link_hidden_'].value='passwordForm:execute';
f.elements['username'].value='${param.username}';
f.submit();
</script>
</f:view>
</html>
Managed bean:
public class PasswordHint extends BasePage {
#ManagedProperty(value="#{param.username}")
private String username;
/* private String execute;
public String getExecute() {
return execute;
}
public void setExecute(String execute) {
this.execute = execute;
}*/
public String getUsername() {
System.out.println("get username of passwordhint-------"+username);
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String execute() {
/* FacesContext context = FacesContext.getCurrentInstance();
Map<String,String> params = context.getExternalContext().getRequestParameterMap();
System.out.println(params.get("username"));
System.out.println("Inside password hint execute-------------");
*/
// ensure that the username has been sent
if (username == null || "".equals(username)) {
log.warn("Username not specified, notifying user that it's a required field.");
addError("errors.required", getText("user.username"));
return null;
}
if (log.isDebugEnabled()) {
log.debug("Processing Password Hint...");
}
// look up the user's information
try {
User user = userManager.getUserByUsername(username);
System.out.println("username retrieved---------"+username);
StringBuffer msg = new StringBuffer();
msg.append("Your password hint is: " + user.getPasswordHint());
msg.append("\n\nLogin at: " + RequestUtil.getAppURL(getRequest()));
message.setTo(user.getEmail());
String subject = '[' + getText("webapp.name") + "] " + getText("user.passwordHint");
message.setSubject(subject);
message.setText(msg.toString());
mailEngine.send(message);
addMessage("login.passwordHint.sent",
new Object[] { username, user.getEmail() });
} catch (Exception e) {
e.printStackTrace();
System.out.println("In exception----------------");
// If exception is expected do not rethrow
//addError("login.passwordHint.error", username);
addMessage("login.passwordHint.sent", username);
}
return "success";
}
faces-config.xml:
<navigation-rule>
<from-view-id>/passwordHint.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/login.jsp</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
<managed-bean>
<managed-bean-name>passwordHint</managed-bean-name>
<managed-bean-class>com.webapp.action.PasswordHint</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>username</property-name>
<value>#{param.username}</value>
</managed-property>
<managed-property>
<property-name>userManager</property-name>
<value>#{userManager}</value>
</managed-property>
<managed-property>
<property-name>mailEngine</property-name>
<value>#{mailEngine}</value>
</managed-property>
<managed-property>
<property-name>message</property-name>
<value>#{mailMessage}</value>
</managed-property>
<managed-property>
<property-name>templateName</property-name>
<value>accountCreated.vm</value>
</managed-property>
</managed-bean>
yes that's the actual code I am trying and that was a typo while copy pasting my actual code. Also the javascript error says : f.elements['passwordForm:_link_hidden_'] is null or not an object.
I am trying to load data into android webview using
webview.loadDataWithBaseURL("", htmlcontent, "text/html", null, "");
a method returns htmlContent from a StringBuilder which populates html data.
I have enabled javascript and set webChromeClient as follows
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebChromeClient(new WebChromeClient());
webview.addJavascriptInterface(new JSClass(), "Android");
my interface to javascript:
class JSClass {
public void getHTMLContent(String html)
{
Log.i(Global.TAG, "HTMLContentReceived: "+html);
}
}
and my javascript in html page:
<script type="text/javascript">
var ele = document.getElementsByClassName('test');
for(var i=0;i<ele.length;i++){
ele[i].onclick = function(){
window.Android.getHTMLContent(this.innerHTML);
}
}
</script>
but somehow the javascript is not returning any value.
It works fine with loadData(url) where url is a simple webpage in assets folder
Please help
Thanks in advance
You don't have any baseURL to use, since you're loading a dynamical generated HTML.
For this reason webview.loadData(htmlcontent, "text/html", null); should be more than enough.
Javascripts don't throw any exceptions in Java code. Remember that JS is not that type-safe/strict as Java code ... My way of doing is to put logs between sensitive Javascript calls to see if that line passes and to check values. Since you didn't provide the HTML, I would setup the WebChomeClient and override the onConsoleMessage:
webview.setWebChromeClient(new MyChromeClient());
private class MyChromeClient extends WebChromeClient {
#Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
String message = consoleMessage.message() + " -- line " + consoleMessage.lineNumber();
switch (consoleMessage.messageLevel()) {
case ERROR:
logErrorMessage(message);
break;
default:
logInfoMessage(message);
break;
}
return true;
}
private void logInfoMessage(String message) {
Log.i("JSTag", message);
}
private void logErrorMessage(String message) {
Log.e("JSTag", message);
}
}
From your JavaScript you would then call for example: console.log('check my value:' + (ele != null)). More info on this here.
Looking at your JavaScript code, I can't understand to what points this.innerHTML.
I am trying to create a demo of Group Chat using reverse ajax in Spring. I am using Spring 3.2.0.RELEASE version.
I am using DeferredResult to perform reverse ajax in my controller. Following is the snippet of my Controller class.
#Autowired
private AsyncRepository asyncRepository;
Map<Integer, List<DeferredResult<String>>> watchers = new ConcurrentHashMap<Integer, List<DeferredResult<String>>>();
#RequestMapping(value="/asyncRequest/getMessages/{id}", method=RequestMethod.GET)
#ResponseBody
public DeferredResult<String> getMessages(final #PathVariable("id") Integer id){
final DeferredResult<String> deferredResult = new DeferredResult<String>(null, Collections.emptyList());
if(watchers.containsKey(id)) {
watchers.get(id).add(deferredResult);
} else {
watchers.put(id, new ArrayList<DeferredResult<String>>());
watchers.get(id).add(deferredResult);
}
deferredResult.onCompletion(new Runnable() {
#Override
public void run() {
watchers.get(id).remove(deferredResult);
}
});
return deferredResult;
}
#RequestMapping(value="/asyncRequest/setMessages/{id}/{message}", method=RequestMethod.GET)
#ResponseBody
public String setMessage(#PathVariable("id") Integer id, #PathVariable("message") String message) {
asyncRepository.setMessage(id, message);
return "";
}
#Scheduled(fixedRate=1000)
public void processQueues() {
for (Map.Entry<Integer, Queue<AsyncDataBean>> entry : asyncRepository.getAsyncBeans().entrySet()) {
while(entry != null && entry.getValue() != null && !entry.getValue().isEmpty()) {
AsyncDataBean asyncDataBean = entry.getValue().poll();
for (DeferredResult<String> deferredResult : watchers.get(asyncDataBean.getId())) {
deferredResult.setResult(asyncDataBean.getMessage());
}
}
}
}
And below is the Repository class which holds the Map of GroupID and its relevant messageQueue. And it also has the functions for getting and setting the messages for relevant group id.
#Repository
public class AsyncRepository {
private Map<Integer, Queue<AsyncDataBean>> asyncBeans = new ConcurrentHashMap<Integer, Queue<AsyncDataBean>>();
public String getMessages(Integer id) {
StringBuilder stringBuilder = new StringBuilder();
while (asyncBeans.get(id) != null && !asyncBeans.get(id).isEmpty()) {
stringBuilder.append(asyncBeans.get(id).poll().getMessage()).append("~");
}
return stringBuilder.toString();
}
public void setMessage(Integer id, String message) {
if(asyncBeans.containsKey(id)) {
asyncBeans.get(id).add(new AsyncDataBean(id, message));
} else {
Queue<AsyncDataBean> messageQueue = new ConcurrentLinkedQueue<AsyncDataBean>();
messageQueue.add(new AsyncDataBean(id, message));
asyncBeans.put(id, messageQueue);
}
}
public Map<Integer, Queue<AsyncDataBean>> getAsyncBeans() {
return asyncBeans;
}
public void setAsyncBeans(Map<Integer, Queue<AsyncDataBean>> asyncBeans) {
this.asyncBeans = asyncBeans;
}
}
And below is the data bean I am using to store each message with its group id.
public class AsyncDataBean {
private Integer id;
private String message;
public AsyncDataBean() {
}
public AsyncDataBean(int id, String message) {
this.setId(id);
this.setMessage(message);
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
And then comes the jsp page for group chat. which looks like below.
<script type="text/javascript">
var messagesWaiting = false;
function getMessages(){
if(!messagesWaiting){
$.ajax({ url: "${pageContext.servletContext.contextPath}/asyncRequest/getMessages/${id}",
dataType:"text",
success: function(data,textStatus,jqXHR) {
if(textStatus == 'success'){
messagesWaiting = false;
var arr = data.split("~");
for(var i=0; i<arr.length; i++)
{
try
{
if(arr[i] != '') {
$("#txtaMessages").val($("#txtaMessages").val() + "\n\n" + arr[i]);
document.getElementById("txtaMessages").scrollTop = document.getElementById("txtaMessages").scrollHeight;
}
}
catch(e){
alert(e.message);
}
}
}
},
complete: function(j) {
},
error: function(xhr) {
}
});
messagesWaiting = true;
}
}
setInterval(getMessages, 1000);
getMessages();
function sendMessage() {
var xmlhttp1 = new XMLHttpRequest();
xmlhttp1.open("GET", '${pageContext.servletContext.contextPath}/asyncRequest/setMessages/${id}/' + $("#txtMessage").val(), true);
xmlhttp1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp1.send();
$("#txtMessage").val("");
$("#txtMessage").focus();
}
</script>
</head>
<body>
<h1>Hello World!</h1>
<table>
<tr>
<td>Messages :: </td>
<td>
<textarea cols="100" rows="10" id="txtaMessages"></textarea>
</td>
</tr>
<tr>
<td>Send Message :: </td>
<td><input type="text" id="txtMessage"/></td>
</tr>
<tr>
<td><input type="button" value="Send" onclick="sendMessage();"/></td>
</tr>
</table>
</body>
</html>
That is what I have coded till now to get this working. And everything is working finw in FF and Chrome. But in IE it is not working as expected. The request is never gets hold on the server and it always gets executed every second as configured in the javascript code. And it always returns the same result as previous. I have tried to use several other methods to send ajax request for IE but its not working. Can anyone get it working for me?
Since everything works fine in FF and Chrome, I suspect the problem is with javascript code to send the request to get messages.
Please help me.
Thanks in advance.
This is very very frustrating.
To get this thing work properly in IE I need to set cache:false attribute in the ajax request I am creating with jquery for getMessages. Otherwise IE will not hold the request in pending status and always returns back with the old response text.
Its a very big issue with IE. I hope no one face the problem again or finds this answer as early as possible.
:)