I am trying to create a servlet on a specific URL to handle a HTML post from another server and receive all parameters and their values and insert them into a database.
Got to this code so far:
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;
import java.sql.*;
public class QueryServlet extends HttpServlet {
#Override
public void doPost(HttpServletRequest req,HttpServletResponse res) throws IOException, ServletException
{
String instId=req.getParameterValues("instId")[0];
String cartId=req.getParameterValues("cartId")[0];
String desc=req.getParameterValues("desc")[0];
String cost=req.getParameterValues("cost")[0];
String amount=req.getParameterValues("amount")[0];
String currency=req.getParameterValues("currency")[0];
String name=req.getParameterValues("name")[0];
String transId=req.getParameterValues("transId")[0];
String transStatus=req.getParameterValues("transStatus")[0];
String transTime=req.getParameterValues("transTime")[0];
String cardType=req.getParameterValues("cardType")[0];
Connection conn = null;
Statement stmt = null;
PrintWriter out=res.getWriter();
try
{
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/orders", "root", "root");
stmt = conn.createStatement();
String sqlStr = "insert into orderdetails values('"+transId+"','"+instId+"','"+cartId+"','"+desc+"'"+cost+"','"+amount+"','"+currency+"','"+name+"','"+transStatus+"','"+transTime+"','"+cardType+")";
out.println("<html><head><title>Query Response</title></head><body>");
out.println("<h3>Thank you for your query.</h3>");
out.println("<p>You query is: " + sqlStr + "</p>"); // Echo for debugging
ResultSet rset = stmt.executeQuery(sqlStr); // Send the query to the server
}
catch(SQLException ex)
{
ex.printStackTrace();
}
}
}
I have tried some changes to it and I allways get errors.
Could you give me a hand?
Btw, I have very little knowledge of java, been trying to "hack my way" into doing this from other people examples and from going trough guides.
Thanks in advance
Edit: I can't log into my dev machine atm as it is having problems and is down, it had something to do with Null pointer or Null value, can't give the exact error atm, will update as soon as possible.
I am also aware of the SQL injection with the code, just trying to test it first and make it work and change the code before I set it live.
There where some quote/comma hickups and it should be exevcuteUpdate.
However it is important to use a PreparedStatement:
easier on the SQL string, escapes special chars in the strings (like apostrophe)
you can used typed parameters, like BigDecimal below
security SQL injection
I used the try-with-resources syntax to close the stmt.
String instId = req.getParameter("instId");
String cartId = req.getParameter("cartId");
String desc = req.getParameter("desc");
String cost = req.getParameter("cost");
BigDecimal amount = new BigDecimal(req.getParameter("amount"));
String currency = req.getParameter("currency");
String name = req.getParameter("name");
String transId = req.getParameter("transId");
String transStatus = req.getParameter("transStatus");
String transTime = req.getParameter("transTime");
String cardType = req.getParameter("cardType");
Connection conn = null;
Statement stmt = null;
PrintWriter out = res.getWriter();
try {
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/orders", "root", "root");
String sqlStr = "insert into orderdetails "
+ "values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sqlStr)) {
stmt.setString(1, transId);
stmt.setString(2, instId);
stmt.setString(3, cartId);
stmt.setString(4, desc);
stmt.setString(5, cost);
stmt.setBigDecimal(6, amount);
stmt.setString(7, currency);
stmt.setString(8, name);
stmt.setString(9, transStatus);
stmt.setString(10, transTime);
stmt.setString(11, cardType);
int updateCount = stmt.executeUpdate();
out.println("<html><head><title>Query Response</title></head><body>");
out.println("<h3>Thank you for your query. " + updateCount + " record(s) updated.</h3>");
out.println("<p>You query is: " + sqlStr + "</p>"); // Echo for debugging
for (Enumeration<String> en = req.getParameterNames(); en.hasMoreElements();) {
String paramName = en.nextElement();
String paramValue = req.getParameter(paramName);
out.println("<p>" + paramName + ": " + paramValue + "</p>"); // Echo for debugging
}
} // Does stmt.close()
} catch (SQLException ex) {
ex.printStackTrace();
}
For inserting or updating or deleting use executeUpdate() but you are using executeQuery()
and executeUpdate method returns an integer(No.of rows affected) so change
ResultSet rset = stmt.executeQuery(sqlStr);
to
int update= stmt.executeUpdate(sqlStr);
Also prefer to use PreparedStatement
Related
I'm passing my method InsertQuery variables from another method which are entered by the user via Scanner.
How do I fill in the iName, iType etc. into my iQuery so that I can insert them into my DB?
public void InsertQuery (String iName, String iType, int health_Problem, Date date2, String aRemind, String docName, String docType, String docAdress)
{
final String url = "jdbc:mysql://localhost/ehealthdb?serverTimezone=UTC";
final String DBUSER = "root";
final String DBPSWD = "root";
try {
Connection con = DriverManager.getConnection(url,DBUSER,DBPSWD);
Statement stmt = con.createStatement();
String iQuery = "INSERT into appointment"
+ "(ID, PatientID, Insurance_Name, Insurance_Type, Health_Problem, Appointment_Date, Appointment_Remind, Doctor_Name,Doctor_Type,Doctor_Adress)"
+ "values ('1','1',,'Gesetzlich','5','15.01.2020','1 Week','Musterarzt','Hausarzt','Musterstraße')";
stmt.executeUpdate(iQuery);
} catch (Exception e) {
System.out.println("Something went wrong #InsertQuery");
}
}
The easiest approach would probably be to use a PreparedStatement:
public void insertQuery
(String iName, String iType, int healthProblem, Date date2, String aRemind, String docName, String docType, String docAddress)
throws SQLException {
final String url = "jdbc:mysql://localhost/ehealthdb?serverTimezone=UTC";
final String DBUSER = "root";
final String DBPSWD = "root";
try (Connection con = DriverManager.getConnection(url,DBUSER,DBPSWD);
PreparedStatement stmt = con.prepareStatement(
"INSERT into appointment" +
"(ID, PatientID, Insurance_Name, Insurance_Type, Health_Problem, Appointment_Date, Appointment_Remind, Doctor_Name, Doctor_Type, Doctor_Adress) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
stmt.setString(1, iName);
stmt.setString(2, iType);
stmt.setInt(3, healthProblem);
stmt.setTimestamp(4, new Timestamp(date2.getTime()));
stmt.setString(5, aRemind);
stmt.setString(6, docName);
stmt.setString(7, docType);
stmt.setString(8, docAddress);
stmt.executeUpdate();
}
}
Don't use a statement, use a PreparedStatement. Otherwise, you get hacked.
More generally, JDBC is a tricky beast and not a particularly nice API. For fairly good reasons - it is designed to be the lowest common denominator, and it is more focused on exposing all the bells and whistles of all databases in existence, than in giving you, programmer who wants to interact with a database, a nice experience.
Try JDBC or JOOQ.
Your exception handling is also wrong. If you catch an exception, either handle it, or make sure you throw something. Logging it, (or worse, printing it) definitely does not count. Add throws to your method signature. If that's not possible (and it usually is possible, try that first), throw new RuntimeException("Uncaught", e) is what you want. not e.printStackTrace(), or even worse, what you did: You just tossed out all relevant information. Don't do that.
The recommended approach is to use PreparedStatement which solves the following two important problems apart from many other benefits:
It helps you protect your application from SQL Injection.
You will not have to enclose the text values within single quotes yourself.
Typical usage is as shown below:
String query = "INSERT INTO appointment(ID, PatientID, Insurance_Name, Insurance_Type, Health_Problem) VALUES (?, ?, ?, ?, ?)";
try (PreparedStatement pstmt = con.prepareStatement(query)) {
//...
pstmt.setString(1, id);
pstmt.setString(2, patientId);
pstmt.setString(3, insuranceName);
//...
pstmt.executeUpdate();
} catch(SQLException e) {
e.printStackTrace();
}
Note that for each ?, you will have to use pstmt.setXXX. Another thing you need to understand is that in the method call, pstmt.setString(1, Id), 1 refers to the first ? and not the first column in your table.
Some other important points:
I have used try-with-resources statement which is an easier and recommended way to close the resources after the program is finished with it. Learn more about it from Oracle's tutorial on it.
Always follow Java naming conventions e.g. Insurance_Name should be named as insuranceName.
I used this way and it is working greatly
for iName
public void InsertQuery (String iName, String iType, int health_Problem, Date date2, String aRemind, String docName, String docType, String docAdress)
{
final String url = "jdbc:mysql://localhost/ehealthdb?serverTimezone=UTC";
final String DBUSER = "root";
final String DBPSWD = "root";
try {
Connection con = DriverManager.getConnection(url,DBUSER,DBPSWD);
Statement stmt = con.createStatement();
String iQuery = "INSERT into appointment"
+ "(ID, PatientID, Insurance_Name, Insurance_Type, Health_Problem, Appointment_Date, Appointment_Remind, Doctor_Name,Doctor_Type,Doctor_Adress)"
+ "values ('1','1',,'"+iName+"','5','15.01.2020','1 Week','Musterarzt','Hausarzt','Musterstraße')";
stmt.executeUpdate(iQuery);
} catch (Exception e) {
System.out.println("Something went wrong #InsertQuery");
}
}
I am just trying to insert a new row in a table from a java application to an SQL database. I have used the same code before and it worked but for some reasons this doesn't. I have checked my query by inserting it directly in phpmyadmin and it works. Here is my code:
where I actually try to sent the query:
static Connection conn = MySQLAccess.connectDB();
static PreparedStatement pst = null;
static ResultSet rs = null;
public static String submit(String usrn, String psw){
String sql = "INSERT INTO tbl_user VALUES('', '"+usrn+"', '"+psw+"')";
try {
pst = conn.prepareStatement(sql);
System.out.println(sql);
rs=pst.executeQuery();
if (rs.next()){
return "ok";
} else {
return "fail";
}
} catch (Exception e){
return "fail_connection";
}
}
MySQLAccess.java (which I am sure works because I use is at other points in the code):
public class MySQLAccess {
Connection conn=null;
public static Connection connectDB (){
try{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/g52gui","root","");
return conn;
}catch(Exception e){
return null;
}
}
}
I have just changed my code (suggestion of Luiggi Mendoza) but no result:
public static String submit(String usrn, String psw){
//String sql = "INSERT INTO tbl_user VALUES('', '"+usrn+"', '"+psw+"')";
String sql = "INSERT INTO tbl_user VALUES('', '?', '?')";
String result = "failed";
try (Connection conn = MySQLAccess.connectDB();
PreparedStatement pst = conn.prepareStatement(sql)) {
pst.setString(1, usrn);
pst.setString(2, psw);
pst.executeUpdate();
result = "worked";
} catch (SQLException e) {
//handle your exception...
}
return result;
}
Three issues:
Use PreparedStatement#executeUpdate rather than PreparedStatement#executeQuery.
Keep the variables in the narrowest possible scope. Don't set them as static variables in your class.
Don't concatenate the parameters into the query string. Instead, use PreparedStatement#setXyz method to set the proper parameter.
Gluing all of these together produces the following code:
public static String submit(String usrn, String psw){
//String sql = "INSERT INTO tbl_user VALUES('', '"+usrn+"', '"+psw+"')";
String sql = "INSERT INTO tbl_user VALUES('', ?, ?)";
String result = "failed";
try (Connection conn = MySQLAccess.connectDB();
PreparedStatement pst = conn.prepareStatement(sql)) {
pst.setString(1, usrn);
pst.setString(2, psw);
pst.executeUpdate();
result = "worked";
} catch (SQLException e) {
//handle your exception...
}
return result;
}
From your new code, the problem is here:
String sql = "INSERT INTO tbl_user VALUES('', '?', '?')";
^ ^ ^ ^
You're wrapping the parameter character ? with quotes '. Remove such quotes, as shown in my code:
String sql = "INSERT INTO tbl_user VALUES('', ?, ?)";
//No quotes around ?
You should use executeUpdate and not executeQuery;
I tried to save / edit / delete a new row in the database. writing in the gui values to be saved with getText ()
here is the code
Connection conn = Connessione.ConnecrDb();
Statement stmt = null;
ResultSet emps = null;
try{
String sql;
sql = "INSERT INTO PROGETTO.LIBRO (ISBN, DISPONIBILITA, TITOLO, CASA_EDITRICE, CODICE_AUTORE, GENERE, PREZZO)"
+ "VALUES (txt_isbn, txt_disp, txt_titolo, txt_casa, txt_autore, txt_genere, txt_prezzo)";
stmt = conn.createStatement();
emps = stmt.executeQuery(sql);
String ISBN= txt_isbn.getText();
String DISPONIBILITA= txt_disp.getText();
String TITOLO= txt_titolo.getText();
String CASA_EDITRICE= txt_casa.getText();
String CODICE_AUTORE= txt_autore.getText();
String GENERE= txt_genere.getText();
String PREZZO = txt_prezzo.getText();
JOptionPane.showMessageDialog(null, "SALVATO");
}catch(SQLException | HeadlessException e)
{
JOptionPane.showMessageDialog(null, e);
}
finally
{
try{
if (emps != null)
emps.close();
}
catch (SQLException e) { }
try
{
if (stmt != null)
stmt.close();
}
catch (SQLException e) { }
}
Getting this error: column not allowed here
Above code just takes care of insert operation. How can I delete and modify table record?
You have asked 2 different questions here
1. Column not allowed here
This happened because you have not passed values for any of parameter into insert statement.
I am not sure about your requirement however I will use PreparedStatement for this scenario.
Example
String insertTableSQL = "INSERT INTO DBUSER"
+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES"
+ "(?,?,?,?)";
PreparedStatement preparedStatement = dbConnection.prepareStatement(insertTableSQL);
preparedStatement.setInt(1, 11);
preparedStatement.setString(2, "MindPeace");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
preparedStatement .executeUpdate();
2. This code is only to save the data, delete, and modify an entire row how can I do?
Answer is very simple. You have to write code for the same :)
You need 3 SQL statement which has DELETE and UPDATE operation just like insert in above example.
String sql = "INSERT INTO PROGETTO.LIBRO (ISBN, DISPONIBILITA, TITOLO, "
+ "CASA_EDITRICE, CODICE_AUTORE, GENERE, PREZZO)"
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement stmt = conn.createStatement()) {
NumberFormat numberFormat = NumberFormat.getInstance(Locale.ITALY);
String ISBN = txt_isbn.getText();
String DISPONIBILITA = txt_disp.getText();
String TITOLO = txt_titolo.getText();
String CASA_EDITRICE = txt_casa.getText();
String CODICE_AUTORE = txt_autore.getText();
String GENERE = txt_genere.getText();
BigDecimal PREZZO = new BigDecimal(
numberFormat.parse(txt_prezzo.getText()).doubleValue())
.setScale(2);
stmt.setString(1, ISBN);
stmt.setString(2, DISPONIBILITA);
stmt.setString(3, TITOLO);
stmt.setString(4, CASA_EDITRICE);
stmt.setString(5, CODICE_AUTORE);
stmt.setString(6, GENERE);
stmt.setBigDecimal(7, PREZZO);
int updateCount = stmt.executeUpdate();
JOptionPane.showMessageDialog(null, "SALVATO");
} catch(SQLException | HeadlessException e) {
JOptionPane.showMessageDialog(null, e);
}
Try-with-resources closes the stmt automatically.
The prepared statement replaces the value in the SQL with something like:
INSERT INTO table(column1, colum2, ....)
VALUES('De\'l Rey',
1234.50,
...)
for:
"De'l Rey"
1.234,50
updateCount should be 1 on success.
Wooow..true!!
I created three buttons to delete / update / insert and now it all works and automatically updates the tables.
you've been very very great. Thank you very much.
one last thing.
if I wanted to insert an error message when I delete / update etc "book not found" I tried to create an if:
Boolean found = false;
try{
sql= delete......
etc
if (!found)
JOptionPane.showMessageDialog(null, "NOT FOUND","ERRORE",JOptionPane.WARNING_MESSAGE);
etc...
Connection conn = Connessione.ConnecrDb();
Statement stmt = null;
ResultSet emps = null;
try{
String sql= "DELETE FROM progetto.libro WHERE isbn =?"; /
pst=(OraclePreparedStatement) conn.prepareStatement(sql);
pst.setString (1, txt_isbn.getText());
pst.execute();
JOptionPane.showMessageDialog(null, "ELIMINATO");
Update_table();
txt_isbn.setText("");
txt_disp.setText("");
txt_titolo.setText("");
txt_casa.setText("");
txt_autore.setText("");
txt_genere.setText("");
txt_prezzo.setText("");
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null,e);
}
if you find the book must exit the book removed, or "not found". but as I deployed I always come out "deleted". why?
thanks again
I am developing an application with java on netbeans/windows 7. I was trying to insert data to database with PreparedStatement using SQL. So this is my code;
private void addInfoActionPerformed(java.awt.event.ActionEvent evt) {
Connection conn;
PreparedStatement pst;
String url = "jdbc:derby://localhost:1527/records";
String SQL_INSERT = "INSERT INTO records"+
"VALUES(?,?,?)";
String name, surname, number;
try {
conn = DriverManager.getConnection(url, "system", "app");
System.out.println("connected to db");
pst = conn.prepareStatement(SQL_INSERT);
name = nameField.getText();
surname = surnameField.getText();
number = numberField.getText();
System.out.println("got data from textfields");
pst.setString(1, name);
pst.setString(2, surname);
pst.setString(3, number);
System.out.println("variables set");
pst.executeUpdate();
System.out.println("sql command executed");
pst.close();
conn.close();
} catch (SQLException ex) {
Logger.getLogger(addition.class.getName()).log(Level.SEVERE, null, ex);
}
}
But I got an error like this;
java.sql.SQLSyntaxErrorException: Syntax error: Encountered "?" at
line 1, column 27.
Name of my table is records and it has three coloumns named; name, surname and number. As I can understand from the println lines, there is a problem with that line;
pst = conn.prepareStatement(SQL_INSERT);
or maybe I created SQL_INSERT string and SQL code wrong. I couldn't figure out what is the problem exactly.
You're missing a space in
String SQL_INSERT = "INSERT INTO records"+
"VALUES(?,?,?)";
When you do the concatenation, it produces "INSERT INTO recordsVALUES(?,?,?)"
Change it to
String SQL_INSERT = "INSERT INTO records"+
" VALUES(?,?,?)";
Most of my code seems to work, but I keep on getting Exception in thread "main" java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0). It happens after the finally block in readDatabase(). It doesn't get to the print statement System.out.println("DOESN'T GET HERE");
I don't know why. Here is the class where everything is processed. In the main class, it just makes an object of this one and calls readDatabase();
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//static because when creating an object of it in main, you won't have to make an object of the outer class (SQLProject) first
public class MySQLAccess{
private Connection connect = null;
private Statement statement = null;
private PreparedStatement preparedStatement = null;
private ResultSet resultSet = null;
public void readDatabase() throws Exception
{
try{
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");
statement = connect.createStatement();
System.out.println("here1");
resultSet = statement.executeQuery("select * from test.comments");
writeResultSet(resultSet);
preparedStatement = connect.prepareStatement("INSERT INTO test.comments values(default, ?, ?, ?, ?, ?, ?)");
//columsn in test.comments
// myuser, email, webpage, datum, summary, COMMENTS
preparedStatement.setString(1, "Test");
preparedStatement.setString(2, "TestEmail");
preparedStatement.setString(3, "TestWebpage");
preparedStatement.setDate(4, new java.sql.Date(2009, 12, 11));
preparedStatement.setString(5, "Test Summary");
preparedStatement.setString(6, "Test Comment");
System.out.println("here2");
preparedStatement.executeUpdate();
preparedStatement = connect.prepareStatement("SELECT myuser, webpage, datum, summary, comments FROM test.comments");
System.out.println("here3");
resultSet = preparedStatement.executeQuery();
writeResultSet(resultSet);
preparedStatement = connect.prepareStatement("DELETE FROM test.comments WHERE myuser='?';");
preparedStatement.setString(1, "Test");
preparedStatement.executeUpdate();
resultSet = statement.executeQuery("SELECT * FROM test.comments;");
System.out.println("Writing meta data");
writeMetaData(resultSet);
}
catch (Exception e){
throw e;
}
finally{
close();
System.out.println("ALMOST");
}
System.out.println("DOESN'T GET HERE");
}
private void writeMetaData(ResultSet resultSet) throws SQLException
{
System.out.println("The columns in the table are: ");
System.out.println("Table: " + resultSet.getMetaData().getTableName(1));
for(int i=1;i<=resultSet.getMetaData().getColumnCount(); i++)
{
System.out.println("Column " + i + " " + resultSet.getMetaData().getColumnName(i));
}
}
private void writeResultSet(ResultSet resultSet) throws SQLException
{
while(resultSet.next())
{
String user = resultSet.getString("myuser");
String website = resultSet.getString("webpage");
String summary = resultSet.getString("summary");
Date date = resultSet.getDate("datum");
String comment = resultSet.getString("comments");
System.out.println("User: " + user);
System.out.println("website: " + website);
System.out.println("summary: " + summary);
System.out.println("date: " + date);
System.out.println("comment: " + comment);
}
}
private void close()
{
try{
if(resultSet != null)
resultSet.close();
if(statement != null)
statement.close();
if(connect != null)
connect.close();
}
catch(Exception e){
e.printStackTrace();
System.out.println("hello");
System.out.println(e);
}
}
}//private inner class
preparedStatement =
connect.prepareStatement("DELETE FROM test.comments WHERE myuser='?';");
preparedStatement.setString(1, "Test");
This is the problematic statement. The question mark is enclosed in quotes and so the statement parser is not able to find it out and so the next statement is throwing the error.
Though the parameter type is String, the corresponding placeholder shouldn't be included in quotes. The prepared statement processor will take care of generating the appropriate SQL based on the data type of parameters. So, it is always a plain ? that should be used as placeholder for parameters of any data type.
So, those two statements should simply be as follows:
preparedStatement =
connect.prepareStatement("DELETE FROM test.comments WHERE myuser=?");
preparedStatement.setString(1, "Test");