Spring MVC check username availability with ajax - java

I've searched for username availability in google. There was no any good solution to this problem. Here I'm trying to check username availability in database table user. I have following code
<input type="text" name="username" id="usernamee" tabindex="1"class="form-control" placeholder="Username"><span class="status">
this is my script code
<script>
$(function(){
$("#usernamee").blur(function(){
var uname = $('#usernamee').val();
if(uname.length >= 3){
$(".status").html("<font> Checking availability...</font>");
$.ajax({
type: "GET",
url: "/exist/"+uname,
success: function(msg){
$(".status").html(msg);
}
});
}
else{
$(".status").html("<font color=red>Username should be <b>3</b> character long.</font>");
}
});
});
</script>
this is my controller code
#RequestMapping(value = { "/exist/{name}" }, method = RequestMethod.POST)
public void checkUsername(#PathVariable("name") String username, HttpServletResponse response , HttpServletRequest request) throws IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
String connectionURL = "jdbc:mysql://localhost:81/name"; // students is my database name
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = (Connection) DriverManager.getConnection(connectionURL, "root", "root");
PreparedStatement ps = (PreparedStatement) connection.prepareStatement("select username from users where username=?");
ps.setString(1,username);
ResultSet rs = ps.executeQuery();
if (!rs.next()) {
out.println("<font color=green><b>"+username+"</b> is avaliable");
}
else{
out.println("<font color=red><b>"+username+"</b> is already in use</font>");
}
out.println();
} catch (Exception ex) {
out.println("Error ->" + ex.getMessage());
} finally {
out.close();
}
}
When I run these code the statusspan tag only shows checking availability..... only. My controller haven't been invoked.
Above code is copied from internet. Any suggestions are welcomed.
Thank you in advance

You send GET request
$.ajax({
type: "GET"
But your controller expect POST
#RequestMapping(value = { "/exist/{name}" }, method = RequestMethod.POST)
Either change ajax to POST or controller to GET

I haven't get you question from what you said above, but you should add #ResponseBody for ajax request.
I recall what I said above, PrintWriter is used and #ResponseBody is not needed, but use #ResponseBody will be better

Related

Password validation with JSP and Servlet

I have a user Sign in Html form where I get the user's email and password and check them against a database. So far I have the following code but when I submit the form it does not go to the specified JSP page. What can I do to improve my code and how can I just generate an error message when the user presses submit but still stay on the same page?
Thank you in advance.
//SERVLET doPost Method
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userinp = request.getParameter("userinp"); //hidden type in html sign up form
HttpSession s = request.getSession();
User u = new User();
if(userinp.equals("signup")) {
u.setName(request.getParameter("name"));
u.setLname(request.getParameter("lname"));
u.setEmail(request.getParameter("email"));
u.setPassword(request.getParameter("password"));
s.setAttribute("User", u);
//Save to DB
u = (User)s.getAttribute("User");
s.invalidate();
UserM ud = new UserM(); //class which contains CRUD methods
ud.createTable();
ud.insert(u);
ServletContext ctx = request.getSession().getServletContext();
forwardTo(ctx, request, response, "/Somepage.jsp");
} else if(userinp.equals("login")) {
String pass1 = request.getParameter("pass");
String email = request.getParameter("useremail");
Connection conn = null;
PreparedStatement stm = null;
try {
conn = ConnectionConfiguration.getConnection();
stm = conn.prepareStatement("SELECT password FROM users WHERE email = ?");
stm.setString(4, email);
ResultSet resultSet = stm.executeQuery();
while(resultSet.next()) {
String pass2 = resultSet.getString("password");
if(pass1.equals(pass2)) {
ServletContext ctx = request.getSession().getServletContext();
forwardTo(ctx, request, response, "/Somepage.jsp");
} else {
//code to generate "Wrong Password" message
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if(stm != null) {
try {
stm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
//ForwardTo Method
public static void forwardTo(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String dest) throws ServletException
{
RequestDispatcher rd = ctx.getRequestDispatcher(dest);
try
{
rd.forward(req, resp);
}
catch(Throwable t)
{
t.printStackTrace();
throw new ServletException(t);
}
}
//HTML FORM
<html>
<head>
<meta charset="ISO-8859-1">
</head>
<body>
<form action = "UserServ" method="POST">
<h3>Enter the details below to Sign In</h3><br>
Email: <input type="text" name="useremail" required><br>
Password: <input type="password" name="pass" required><br>
<input type="submit" value="Sign In">
</form>
</body>
</html>
You have an error in your database preparedStatement:
stm.setString(4, email);
What is 4 supposed to be here? The first parameter of setString corresponds to the '?' in your prepared statement.
stm = conn.prepareStatement("SELECT password FROM users WHERE email = ?");
You only have 1 question mark, so it should be:
stm.setString(1, email);
What can I do to improve my code
Seperate the database logic from your servlet. Use the MVC pattern, it will make your life easier.
and how can I just generate an error
You can easily achieve this with JSTL/EL in your JSP. Set an attribute in your servlet and forward that to the jsp page. JSTL will check if the attribute exists and show the appropriate message.
You could also just forward the user to a specific page if the details are wrong, like i have shown in the example below.
A more advanced way would be to implement AJAX, this is basically using javascript to make asynchronous calls to your servlet so that you don't have to refresh the page. You could use this to check see if the details are correct.
message when the user presses submit but still stay on the same page?
You mean if they haven't typed in any details? You could use javascript/jquery to do this. Maybe disable the submit btn/form from submitting when the text fields are empty.
Below is your servlet code, i condensed your database logic. Much easier to manage this way:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userinp = request.getParameter("userinp"); //hidden type in html sign up form
HttpSession s = request.getSession();
User u = new User();
ServletContext ctx = s.getServletContext();
//check for null first, because if userinp is empty, then you will get a NPE
if(userinp != null && userinp.equals("signup")) {
u.setName(request.getParameter("name"));
u.setLname(request.getParameter("lname"));
u.setEmail(request.getParameter("email"));
u.setPassword(request.getParameter("password"));
s.setAttribute("User", u);
//Save to DB
u = (User)s.getAttribute("User");
s.invalidate();
UserM ud = new UserM(); //class which contains CRUD methods
ud.createTable(); //why are you creating a table for each user? (you need to create a table called 'users' and just insert the new user there.
ud.insert(u);
forwardTo(ctx, request, response, "/Somepage.jsp");
} else if( userinp != null && userinp.equals("login")) { //you should separate the register and login logic (easier to maintain in two different servlets
String pass1 = request.getParameter("pass");
String email = request.getParameter("useremail");
//so instead of getting the password from the database, you can check to see if the details exist instead and return a boolean.
if(validate(email,pass1)){
forwardTo(ctx, request, response, "/Welcome.jsp"); //user is logged in
}else{
forwardTo(ctx, request, response, "/Error.jsp"); //user is not logged in, details do not match
}
}
}
validate method:
//this should be in a different class. So it's easier to maintain and can be used elsewhere. It's bad practice to have database logic in your servlet. Because what if you want to use this in a different servlet or another part of your application? (you don't want to copy and pasta it everywhere do you?)
public static boolean validate(String email, String password){
boolean status = false;
PreparedStatement pst = null;
ResultSet rs = null;
//if you put your getConnection method as a try condition, it will automagically close the connection for you.
try(Connection conn= ConnectionConfiguration.getConnection()){
pst = conn.prepareStatement("select * from users where email=? and password=?;");
pst.setString(1, email); //1 here corresponds to the first '?' in preparedStatement
pst.setString(2, password); //2 corresponds to the second '?'
rs = pst.executeQuery();
status = rs.next(); //if there are any results, then status is true.
} catch (SQLException e) {
e.printStackTrace();
}
return status;
}
Let me know if you have problems anywhere or other questions, happy to help.

Why is the url showing /ServletName though what is displayed is from jsp

I have a servlet where I get data from Sql Server using ResultSet. I use
request.setAttribute("list", list);
request.getRequestDispatcher("Display.jsp").forward(request, response); to display as a table in the jsp.
But in the omnibox of chrome I see /ServletName instead of /JSPName.jsp. The table is displayed in the jsp using foreach based on the list received from servlet.
This is the servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Connection connection = null;
Statement stmt = null;
try {
StringBuffer data = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException ex) {
Logger.getLogger(NewServlet.class.getName()).log(Level.SEVERE, null, ex);
}
connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=DesktopScreen","sa","sa123");
stmt = connection.createStatement();
ArrayList list = new ArrayList();
String query = "select * from ClientLogin";
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String UniqueId,ClientId,RequestedDateTime,ConnectionStatus;
UniqueId = rs.getString("UniqueID");
ClientId = rs.getString("ClientId");
RequestedDateTime = rs.getString("RequestDateTime");
ConnectionStatus = rs.getString("ConnectionStatus");
BeanClass beanClass = new BeanClass();
beanClass.setUniqueId(UniqueId);
beanClass.setClientId(ClientId);
beanClass.setConnectionStatus(ConnectionStatus);
beanClass.setRequestDateTime(RequestedDateTime);
list.add(beanClass);
}
request.setAttribute("list", list);
request.getRequestDispatcher("Display.jsp").forward(request, response);
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
connection.close();
} catch (SQLException ex) {
Logger.getLogger(NewServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This is Display.jsp:
<table border ="1" style="border: border-collapse">
<tr><td>UniqueId</td><td>ClientId</td><td>Request Date and Time</td><td>Connection Status</td></tr>
<c:forEach items="${list}" var="item">
<tr>
<td>${item.getUniqueId()}</td>
<td>${item.getClientId()}</td>
<td>${item.getRequestDateTime()}</td>
<td>${item.getConnectionStatus()}</td>
</tr>
</c:forEach>
</table>
Your browser has requested for the servlet url and the servlet has forwared it to jsp. Your browswer does not know that. This is because you are using [requestDispatcher.forward()][1] method. Check the image from thejavageek.com
This is what happens
Browser requests the servlet.
Servlet forwards the task to jsp.(Browser doesn't know that)
Broswer still thinks the response has come from servlet and not jsp.
If you want the url to be shown in browser, then you need to user response.sendRedirect() which is explained in image below
If you use response.sendRedirect(), below steps will happen.
Your browser requests servlet.
Servlet calls response.sendredirect();
Browser will make another request to another resource and url will be changed in the address bar.
When you use requestDispatcher.forward(); the resources are forwarded within the server from where the call is made. This is done by container internally and client or browser is not involved in it.

Unexpected token END OF FILE at position while parsing BufferedReader to JSON Object

I am passing an object to the Java Servlet publishStory using Angularjs $http service. And however this same servlet code has worked fine with other requests but here I am getting the following error:
I have researched it on the internet but could not find solution to this particular case where I am using BufferedReader, as the same servlet works fine with other requests.
Here is my publishStory servlet:
public class publishStory extends HttpServlet{
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
PreparedStatement pstmt = null;
Connection cn = null;
ResultSet rs = null;
boolean flag = false;
PrintWriter out = null;
try{
System.out.println("CALLING THE METHOD");
Class.forName("com.mysql.jdbc.Driver");
cn = DriverManager.getConnection("jdbc:mysql://localhost/storyboard","root","");
BufferedReader reader = request.getReader();
JSONParser parser = new JSONParser();
JSONObject juser = null;
juser = (JSONObject)parser.parse(reader);
String welcomeStoryTitle = (String)juser.get("welcomeStoryTitle");
String welcomeStoryWords = (String)juser.get("welcomeStoryWords");
String query = "INSERT INTO stories (storytitle, storytext) VALUES (?,?)";
pstmt = cn.prepareStatement(query);
pstmt.setString(1, welcomeStoryTitle);
pstmt.setString(2, welcomeStoryWords);
int i = pstmt.executeUpdate();
if(i>0)
System.out.println(welcomeStoryTitle=" : "+welcomeStoryWords);
else
System.out.println("No data inserted");
}
catch(Exception e){
e.printStackTrace();
}
}
I am retrieving two request parameters welcomeStoryTitle and welcomeStoryWords in this servlet.
And below is my angularjs controller with a function implementing $http service:
app.controller('welcomeStoryPublishCtrl', ['$log','$http',function($log,$http){
this.publishGroup = function(wsPublish){
$http({
method:'POST',
url: 'http://localhost:9090/Writer/publishStory',
header: {'Content-Type':'application/json'},
data: wsPublish
}).success(function(){});
};
}]);
I am getting this error where I am parsing the reader object, at line:
juser = (JSONObject)parser.parse(reader);
Could this be because of the size of a String being retrieved from request?
'At position 0' is a giveaway. You are trying to parse an empty response.

HttpSession with Servlet + Java not working

i have the following pice of code 'anmelden.java':
#WebServlet("/anmelden")
public class anmelden extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String benutzer = request.getParameter("benutzer");
String passwort = request.getParameter("passwort");
try {
PrintWriter out = response.getWriter();
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/test","admin","*****");
PreparedStatement stmt = con.prepareStatement("SELECT benutzer,passwort,rolle FROM login WHERE benutzer = ? AND passwort = ?");
stmt.setString(1, benutzer);
stmt.setString(2, passwort);
ResultSet rs = stmt.executeQuery();
if(rs.next())
{
HttpSession session = request.getSession();
session.setAttribute("benutzer", rs.getString("benutzer"));
RequestDispatcher dis = request.getRequestDispatcher("mandant.jsp");
dis.forward(request, response);
out.print("1");
}
else
{
out.print("Benutzername und/oder Passwort falsch");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is my jsp file 'login.jsp':
$("#anmelden").click(function(){
var benutzer = $("#benutzer").val();
var passwort = $("#passwort").val();
if(benutzer == "" || passwort == "")
{
return;
}
$.ajax({
url:"anmelden",
type:"POST",
data:"benutzer="+benutzer+"&passwort="+passwort
}).success(function(data){
var erfolg = data;
if(erfolg == "1")
{
window.location.href="http://localhost:8080/PSD/mandant.jsp";
}
else
{
$("#ok").text(erfolg);
}
});
});
As u can see i tries to set the name coming from my DB into my session Attribute.
I want to use the Attribute in my 'mandant.jsp' file.
But it dosen't work - all what happens is, that my 'login.jsp' file which makes the ajax call, print the code from 'mandant.jsp' into my div as text.
So it dosen't opend the next page as i want -.-
But if i comment out the HttpSession block then it works fine but then i can't use ,of course,the session Attribute.
So what's wrong or what must i change so that this code works?
Many thanks
This is because this part of the code:
RequestDispatcher dis = request.getRequestDispatcher("mandant.jsp");
dis.forward(request, response);
is generating the HTML from mandant.jsp file using the request object (along with HttpSession and ServletContext) to fulfill any Expression Language and writing this HTML into the response. Just remove these lines and you'll be ok.
You are mixing two types of communication here, from the JSP page you are making an ajax call but from the Servlet you are making a Dispatch redirect.
If you want the login page to be redirected after a a successful login then don't call the Servlet with an ajax call and better do a form submit.
If you rather want to only check credentials on the servlet and redirect from the client then keep the ajax call but avoid the request dispatcher in the servlet and return a success/error code instead. Then capture that code from the ajax response and redirect to a successful page if you want.

Uncaught TypeError: Illegal invocation

I am trying to delete users from my database using Ajax, Servlet and HTML. when I submit data Illegal Invocation occurs. I think that there won't be any problems with connection or SQL statement
delete.html
<input type="text" id="delete">
<input type="submit" onclick="deleteUSer()" value="Delete">
delete.js
function deleteUSer(){
var username = document.getElementById("delete");
var params = {
username: username
}
$.post("Delete", params, function(data){}
)
}
Delete.java servlet
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = null;
DBUtils dbutils = null;
Connection conn = null;
try{
String username = request.getParameter("username");
dbutils = new DerbyUtils();
conn = dbutils.getConnection();
DeleteDAO dao = new DeleteDAO(conn);
dao.deleteUser(username);
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher("/index.html");
dispatcher.forward(request, response);
}
DeleteDAO.java
public void deleteUser(String username) throws SQLException{
try{
String sql = "delete from users where username='"+username+"'";
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.executeQuery();
you are sending html doc elemect not username ...
try this --
<input type="text" id="delete" value="vivek">
<input type="submit" onclick="deleteUSer()" value="Delete">
function deleteUSer(){
var username = document.getElementById("delete");
var params = {
username: username.value
}
$.post("Delete", params, function(data){}
)
}
If you're trying to enact the "delete" command that you can use with HTTP requests, you're going to want to use $.ajax, not $.post.
To quote the docs (https://api.jquery.com/jQuery.post/):
This is a shorthand Ajax function, which is equivalent to:
$.ajax({
type: "POST",
url: url,
data: data,
success: success,
dataType: dataType
});
if you're trying to enact the "delete", you'd want to do something like:
var dataObj = {
'username': document.getElementById("delete").value;
}
$.ajax({
type:"DELETE",
data: dataObj,
url: 'url/to/your/servlet'
});
You may also want to include a datatype in there but for this example jquery can figure it out.

Categories