I am trying to get the servlet program to connect with the database and perform actions. In eclipse, when I put the connection and queries in the main() method and choose "Run as java application" it is working and the database is being updated, however, when I launch the html using "Run on server" and put the queries in the doGet() method, the servlet is running and html is being updated in the browser, but, no update is being done in the database. I also tried putting the code in the main method and calling main() through doGet() with no success.
html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Register</title>
</head>
<body>
<form action="register" method="get">
<label for="uname">Username:</label>
<input type="text" name="uname">
<label for="pwd">Password:</label>
<input type="text" name="pwd">
<button type="submit">Register</button>
</form>
</body>
</html>
doGet() method:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
// response.getWriter().append("Served at: ").append(request.getContextPath());
PrintWriter pw = response.getWriter();
String uname = request.getParameter("uname");
String pwd = request.getParameter("pwd");
Connection con = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/advjavada", "root", "");
if(!con.isClosed()) {
System.out.println("Connection SUCCESSFUL!");
PreparedStatement ps = con.prepareStatement("insert into userdata(uname, pwd) value('sample2', 'sampass2');");
//ResultSet rs = ps.executeQuery();
ps.executeQuery();
}
else {
System.out.println("Connection FAILED!");
}
}
catch (Exception e) {
System.err.print(e.getMessage());
}
pw.println("<h1>Hello, " + uname + "!</h1><p>Registration Successful</p>");
pw.close();
}
Tahir Hussain Mir's answer on this question has resolved the issue.
As it turns out, it's a problem during deployment in which the external jar file for SQL is used for compilation but is not included during runtime.
To solve this:
Add the .jar file to the Deployment Assembly under Project > Properties.
Related
I am completely new to web development and I would like some help please. I am doing a payroll system web application project using Java Eclipse EE, tomcat server and mysql. I used a tutorial and managed to create the login interface below. So right now, when i click enter my login details and click login (at localhost:8080/Payroll) I want it to go to a web page (which I have no idea how to create) and display a list of buttons (any random buttons which I can later rename). Can someone please help me. I have no idea about how to use .JSP, .html, .java and I am really confused about how these file types will help me get what I want. Please help someone, I just want the login button to redirect to a web page with buttons on it. Thank you.
Login.java (Servlet)
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
public class Login extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String employee_id = request.getParameter("employee_id");
String password = request.getParameter("password");
if(Validate.checkUser(employee_id, password)) {
RequestDispatcher rs = request.getRequestDispatcher("**SOME FILE NAME HERE TO REDIRECT TO?**");
rs.forward(request, response);
}
else
{
out.println("Employee ID or Password is incorrect. Please try again.");
RequestDispatcher rs = request.getRequestDispatcher("index.html");
rs.include(request, response);
}
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form action="login" method="post">
<h3>
Employee Login
</h3>
<b>Employee ID:</b> <br>
<input type="text"name="employee_id" size="20"><br><br>
<b>Password:</b><br>
<input type="password" name="password" size="20"><br><br>
<input type="submit" value="Login"><br><br>
</form>
</body>
</html>
Validate.java (class file)
import java.sql.*;
public class Validate
{
public static boolean checkUser(String employee_id, String password)
{
boolean st = false;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/payroll_system", "root", "");
PreparedStatement ps = con.prepareStatement("select * from employee_login where employeeID = ? and pwd = ?");
ps.setString(1, employee_id);
ps.setString(2, password);
ResultSet rs =ps.executeQuery();
st = rs.next();
}catch(Exception e)
{
e.printStackTrace();
}
return st;
}
}
As your index.html is already a "page with buttons" this seems to work for you.
However, if your page will include dynamic data, you're better of with jsp.
You might want to start by setting the username into the session and go display that in jsp:
request.setAttribute("user", employee_id);
RequestDispatcher rs = request.getRequestDispatcher("stackoverflow.jsp");
rs.forward(request, response);
And in stackoverflow.jsp
<h2><%= request.getAttribute("user") %></h2>
Now compare calling the jsp directly and when invoked through login...
Make sure to read on MVC in web projects and consider using a framework (like Spring) once you have a feel for the concepts.
Some notes on your code:
You don't ever close Connection, Statement, ResultSet. Consider a connection pool and try-with-resource:
public static boolean checkUser(String employee_id, String password)
{
boolean st = false;
try (Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/payroll_system", "root", "");
PreparedStatement ps =
con.prepareStatement("select * from employee_login where employeeID = ? and pwd = ?")) {
ps.setString(1, employee_id);
ps.setString(2, password);
try(ResultSet rs =ps.executeQuery()) {
return rs.next();
}
}catch(Exception e) {
e.printStackTrace();
}
return false;
}
Everything is working fine else why RequestDispatcher showing source code of page?
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String uName=req.getParameter("uEmail");
String uPass=req.getParameter("uPass");
try{
DBConnection con=new DBConnection();
if(con.login(uName, uPass)){
HttpSession on = req.getSession();
on.setAttribute("u_id", uName);
res.sendRedirect("dashboard.jsp");
}
else{
RequestDispatcher dis= getServletContext().getRequestDispatcher("/login.jsp");
PrintWriter write = res.getWriter();
write.println("Wrong Username or Passowrd");
dis.include(req, res);
}
}catch(ClassNotFoundException | SQLException e){}
}
}
Page redirecting fine to given url /login.jsp and also showing the error message, but why as source code?
Wrong Username or Passowrd
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<form action="LoginServlet" method="POST" />
<input type="text" name="uEmail" />
<br /><br />
<input type="text" name="uPass" />
<br /><br />
<input type="Submit" name="Register" value="Register" />
<br /><br />
</form>
</body>
</html>
direct link to login.jsp works fine.
from http://docs.oracle.com/javaee/6/api/javax/servlet/RequestDispatcher.html#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
The include method of Request Dispatcher gets the content of the resource that why you are getting the source code in browser.
I think what you want to do is forward the request to login.jsp so use forward method of request dispatcher.
As #JBNizet mentioned in his comment due to your message from Servlet, HTML is going to be invalid.
before dis.include(req,res);
add this line res.setContentType("text/html); it
I was facing the same issue when I used RequestDispacther method and try to return and String massage along with html page then i have found you have to put some kind of tag to the String massage like then use include method
so if my code was
out.println("Terms & Condition not accepted");
RequestDispatcher rd = request.getRequestDispatcher("index.html");
rd.include(request, response);
i changed it to "
out.println("<h1>Terms & Conditions not accepted </h1>")
RequestDispatcher rd = request.getRequestDispatcher("index.html");
rd.include(request, response);
"
You need to set the content type of the response.
Add the below line in your doPost method.
response.setContentType("text/html;charset=UTF-8");
Hope it works for you!!
EDIT: This has been resolved by checking the log file on the Google Developers Console. The error was not in connecting to the database, but was because I was compiling with JDK 1.8 instead of 1.7. It turned out that even though I had told Eclipse to use JDK 1.7 for the project, it was still using 1.8 because I had the following line in my Eclipse configuration file:
-vm
C:\Program Files\Java\jdk1.8.0_20\bin
when I changed this to:
-vm
C:\Program Files\Java\jdk1.7.0_71\bin
everything worked perfectly.
Original Question:
I am trying to connect to a Google Cloud SQL instance from my authorized Google App Engine application. I started by following the directions at https://cloud.google.com/appengine/docs/java/cloud-sql/#Java_Build_a_starter_application_and_database and modifying them slightly to work with my Cloud SQL instance (I did not implement the guestbook database, I used my own which also has just one table with three columns). I created the Cloud SQL instance using MySQL Workbench.
When I debug my application locally (run it at localhost:8888) it works perfectly with my local MySQL instance AND the Google Cloud SQL instance. However, when I try to deploy my application to Google App Engine it just spits back a 500 Server Error and I have no clue what went wrong (I am very new to web programming). I have been searching all over the web for a solution to this issue but I've yet to find something that does the trick.
Here is my code for the servlet:
package com.rmpm;
import java.io.*;
import java.sql.*;
import javax.servlet.http.*;
import com.google.appengine.api.utils.SystemProperty;
#SuppressWarnings("serial")
public class Synaptic_rmpmServlet extends HttpServlet {
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String url = null;
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
try {
if (SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Production) {
// Load the class that provides the new "jdbc:google:mysql://" prefix.
Class.forName("com.mysql.jdbc.GoogleDriver");
url = "jdbc:google:mysql://<my-project-id>:<my-instance-id>/test"; // Doesn't work
} else {
// Local MySQL instance to use during development.
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://173.###.##.###:3306/test"; // Connects to Google Cloud SQL instance when root password is provided
//url = "jdbc:mysql://127.0.0.1:3306/test"; // Connects to local MySQL instance
}
} catch (Exception e) {
e.printStackTrace();
return;
}
try {
Connection conn = DriverManager.getConnection(url, "root", "");
try {
String pid = req.getParameter("projID");
String own = req.getParameter("owner");
String dur = req.getParameter("duration");
if (pid == "" || own == "" || dur == "") {
out.println(
"<html><head></head><body>You are missing either a projectID, owner name, or duration! Try again! " +
"Redirecting in 3 seconds...</body></html>");
}
else {
int duration = Integer.parseInt(dur);
String statement = "INSERT INTO project VALUES(?, ?, ?)";
PreparedStatement stmt = conn.prepareStatement(statement);
stmt.setString(1, pid);
stmt.setString(2, own);
stmt.setInt(3, duration);
int success = 2;
success = stmt.executeUpdate();
if (success == 1) {
out.println(
"<html><head></head><body>Success! Redirecting in 3 seconds...</body></html>");
} else if (success == 0) {
out.println(
"<html><head></head><body>Failure! Please try again! " +
"Redirecting in 3 seconds...</body></html>");
}
}
} finally {
conn.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
resp.setHeader("Refresh", "3; url=/databaseIO.jsp");
}
}
And my code for the databaseIO.jsp:
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<%# page import="java.util.List" %>
<%# page import="java.sql.*" %>
<%# page import="com.google.appengine.api.utils.SystemProperty" %>
<html>
<body>
<%
String url = null;
if (SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Production) {
// Load the class that provides the new "jdbc:google:mysql://" prefix.
Class.forName("com.mysql.jdbc.GoogleDriver");
url = "jdbc:google:mysql://<my-project-id>:<my-instance-id>/test"; // Doesn't work
} else {
// Local MySQL instance to use during development.
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://173.###.##.###:3306/test"; // Connects to Google Cloud SQL instance when root password is provided
//url = "jdbc:mysql://127.0.0.1:3306/test"; // Connects to local MySQL instance
}
Connection conn = DriverManager.getConnection(url, "root", "");
ResultSet rs = conn.createStatement().executeQuery(
"SELECT * FROM project");
%>
<table style="border: 1px solid black">
<tbody>
<tr>
<th width="40%" style="background-color: #CCFFCC; margin: 5px">projectID</th>
<th style="background-color: #CCFFCC; margin: 5px">owner</th>
<th style="background-color: #CCFFCC; margin: 5px">duration</th>
</tr>
<%
while (rs.next()) {
String aPID = rs.getString(1);
String anOwner = rs.getString(2);
int aDur = rs.getInt(3);
%>
<tr>
<td><%= aPID %></td>
<td><%= anOwner %></td>
<td><%= aDur %></td>
</tr>
<%
}
conn.close();
%>
</tbody>
</table>
<br />
No more projects!
<p><strong>Add a project:</strong></p>
<form action="/sign" method="post">
<div>Project ID: <input type="text" name="projID"></input></div>
<br />
<div>Owner: <input type="text" name="owner"></input></div>
<br />
<div>Duration: <input type="text" name="duration"></input></div>
<br />
<div><input type="submit" value="Insert Project"></input></div>
</form>
</body>
</html>
Based on what I've read online, I gather that I shouldn't need a password when connecting as the root user to my Google Cloud SQL instance from my authorized Google App Engine application. When I connect to the Google Cloud SQL instance locally in debug mode, I do provide the root password which I set in the Google Developers Console and it works perfectly.
What I've done:
I am already logged into Eclipse with the Google account that is linked to my Google App Engine application.
I have already included the <use-google-connector-j>true</use-google-connector-j> line in the appengine-web.xml file.
I have copied the mysql-connector-java-5.1.33-bin.jar to the project's war/WEB-INF/lib folder and to the GAE SDK directory at D:\Program_Files\Eclipse\plugins\com.google.appengine.eclipse.sdkbundle_1.9.13\appengine-java-sdk-1.9.13\lib\impl (reading similar questions online said to do this).
I have authorized my Google App Engine application to connect to my Google Cloud SQL instance.
I have authorized my local network to connect to my Google Cloud SQL instance.
I am 100% sure the <my-project-id> and <my-instance-id> fields are correct in the JDBC url.
I've tried using my Google Cloud SQL instance's IP address in the JDBC url instead of the project-id and instance-id.
What I'm using:
Eclipse SE Luna (4.4.1) with Google Plugin for Eclipse (4.4) and Google App Engine Java SDK (1.9.13). I deploy from Eclipse straight to Google App Engine with the plugin.
JDK 1.7
Windows 8.1 64-bit
If you need any additional information just post here as I'll be checking this regularly.
Local mysql will be working on your code , i was having the same problem but as i changed .GoogleDriver to .Driver it started working
I have a very beginner question as I'm just learning to work with DBs. I have a very simple HTML form with a textField for a name, an add button to add a name to a MySQL database, and a sort button to sort the names in the database and display them. I almost have it working, however when I hit the "add" or "sort" buttons I get the same messages that appear after a user clicks those buttons along with the sorted list of names. It looks like this when clicking the add button:
Please go back and add a name or sort
Bill Jones
David G
Debbie Downer
Jane Doe
Would someone be able to advise me on what I have to change on my code to make just the list show up by itself when the user clicks sort? I am not a programmer just someone trying to learn.
Servlet code:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*;
#WebServlet("/Main")
public class Main extends javax.servlet.http.HttpServlet implements
javax.servlet.Servlet {
static final long serialVersionUID = 1L;
public Main() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String name = request.getParameter("name");
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager
.getConnection("jdbc:mysql://localhost:3306/test?user=root&password=root");
Statement stmt = con.createStatement();
try {
//stmt.execute("DROP TABLE simple");
stmt.execute("CREATE TABLE IF NOT EXISTS simple( name char(30))");
} catch (Exception e) {
}
if (name == "" || name == null) {
out.print("<h1>Please enter a name.<h1>");
}
else if (name != null) {
String s = "Insert into simple values(\'" + name + "\')";
stmt.execute(s);
out.print("<h1>Please go back and add a name or sort.<h1>");
}
ResultSet rs = stmt.executeQuery("Select * FROM simple ORDER BY name");
while (rs.next())
out.println("<h1>" + rs.getString(1) + "</h1>");
} catch (Exception ex) {
System.out.println(ex);
}
System.out.println("Program terminated with no error.");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
HTML code:
<!-- Main.html -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>DB Sort</title>
</head>
<body>
<form action="http://localhost:8080/DB_Sorts/Main">
<center>
<br><br>
User Name:
<input name="name" type="text" value="">
<br><br>
<input name="add" type="Submit" value="Add">
<input name="sort" type="Submit" value=" Sort ">
</center>
</form>
</body>
</html>
Each submit button calls the same servlet with slightly different parameters.
If you wish to have different behaviour based on the button that is pressed you need to test which button was pressed.
If you click the add button the parameters name=???? and add=Add will be submitted. So if you add some code along the lines of.
if (request.getParameter("add") != null){
// do add
} else if (request.getParameter("sort") != null){
// do sort
}
you should get what you want.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Calling servlet from HTML form, but servlet is never invoked
I'm calling servlet from html form, servlet takes the form data and it will insert that form data into database.But when i click the submit button error page is coming. Please help whats wrong in my servlet code.
My html code:
<html>
<head>
<title> Sign Up </title>
</head>
<body>
<form action="servlet/Loginservlet" method="post" >
<font size='5'>Create your Account:</font><br/><br>
<label for="username" accesskey="u" style="padding-left:3px;">User Name: </label>
<input type="text" style="background-color:#ffffff;margin-left:14px;padding-top:7px;border-width:0px;margin-top:6px;padding-right:85px;" id="username" name="username" tabindex="1"><br/><br>
<label for="password" accesskey="p" style="padding-left:4px;">Password: </label>
<input type="password" style="background-color:#ffffff;margin-left:14px;padding-top:7px;border-width:0px;padding-right:85px;" id="password" name="pasword" tabindex="2"><br/><br>
<input type="submit" value="Submit" style="margin-left:164px;"/>
<input type="reset" value="Reset" style="margin-left:17px;"/>
</form>
</body>
</html>
My servlet code:
import javax.servlet.http.HttpServlet;
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Loginservlet extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
System.out.println("login servlet");
String connectionURL = "jdbc:mysql://localhost:3306/mysql";
Connection connection = null;
res.setContentType("text/html");
PrintWriter out = res.getWriter();
String username = req.getParameter("username");
String password = req.getParameter("password");
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(connectionURL, "root", "root");
String sql = "insert into signup values (?,?)";
PreparedStatement pst = connection.prepareStatement(sql);
pst.setString(1, username);
pst.setString(2, password);
int numRowsChanged = pst.executeUpdate();
out.println(" Data has been submitted ");
pst.close();
} catch (ClassNotFoundException e) {
out.println("Couldn't load database driver: " + e.getMessage());
} catch (SQLException e) {
out.println("SQLException caught: " + e.getMessage());
} catch (Exception e) {
out.println(e);
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException ignored) {
out.println(ignored);
}
}
}
}
My web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>Loginservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
I think, mistake is here: <form action="servlet/Loginservlet"
Try this <form action="/<your-app-name>/login"
since in form action you have given servlet/Loginservlet . you should map same in web.xml like
<url-pattern>/servlet/Loginservlet</url-pattern>
or change in the form like
action='login'
you can do any one of above.
try this
<form action="login" method="post" >
you servlet url is
<url-pattern>/login</url-pattern>
When you run your web application for local host then the url like
localhost:8080/test
then the test is the name of your application name which contain your web application into the web dir. Now suppose you create the index file then it will run index file from this only and another page url like
localhost:8080/test/page1.html
now from page1.html you start your login page then the link looks like for servlet is
localhost:8080/test/login
as define the url pattern for specific servlet that url you have to set for calling the specific servlet like above. this url will hide the actual servlet for the client you can set anything in url pattern