Storing MySQL query results in an ArrayList using Java - java

The following java code takes in a POST request from a JSP file and passes back the out ArrayList as output. The problem I'm having is figuring out how to read the output into the Arraylist properly, so they I can grab each element from the Arraylist and display it in my JSP.
How can I read in the column names as the first array of strings, and then each row of data as the following arrays of strings, so that I have one giant array list that contains the entire results of the query in an organized manner, and will allow me to read the results onto my JSP page?
EDIT:
So the only problem I'm having now is that when executing a command like SELECT * FROM table; it only shows the column names. But when I execute a command like SELECT columnName FROM table; it displays the column perfectly. The code below has been updated to reflect where I am at now.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
import java.util.ArrayList;
#SuppressWarnings("serial")
public class databaseServlet extends HttpServlet {
private Connection conn;
private Statement statement;
public void init(ServletConfig config) throws ServletException {
try {
Class.forName(config.getInitParameter("databaseDriver"));
conn = DriverManager.getConnection(
config.getInitParameter("databaseName"),
config.getInitParameter("username"),
config.getInitParameter("password"));
statement = conn.createStatement();
}
catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ArrayList<String[]> out = new ArrayList<String[]>();
ArrayList<String> columns = new ArrayList<String>();
String query = request.getParameter("query");
if (query.toString().toLowerCase().contains("select")) {
//SELECT Queries
//try {
ResultSet resultSet = statement.executeQuery(query.toString());
ResultSetMetaData metaData = resultSet.getMetaData();
int numberOfColumns = metaData.getColumnCount();
for(int i = 1; i<= numberOfColumns; i++){
columns.add(metaData.getColumnName(i));
}
while (resultSet.next()){
String[] row = new String[numberOfColumns];
for (int i = 0; i < numberOfColumns; i++){
row[i] = (String) resultSet.getObject(i+1);
}
out.add(row);
}
//}
//catch (Exception f) {
//f.printStackTrace();
//}
}
else if (query.toString().toLowerCase().contains("delete") || query.toLowerCase().contains("insert")) {
//DELETE and INSERT commands
//try {
conn.prepareStatement(query.toString()).executeUpdate(query.toString());
columns.add("\t\t Database has been updated!");
//}
//catch (Exception l){
//l.printStackTrace();
//}
}
else {
//Not a valid response
columns.add("\t\t Not a valid command or query!");
}
request.setAttribute("query", query);
request.setAttribute("resultSize", out.size());
request.setAttribute("queryResults", out);
request.setAttribute("queryColumns", columns);
RequestDispatcher dispatcher = request.getRequestDispatcher("/dbServlet.jsp");
dispatcher.forward(request, response);
}
}
Here is my .JSP file, and right now it is only printing [] with nothing in it when I execute a command. I know that commands are working because of previous tests, but the array is not displaying properly.
<?xml version = "1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- dbServlet.html -->
<html xmlns = "http://www.w3.org/1999/xhtml">
<%# page import="java.util.ArrayList" %>
<head>
<title>MySQL Servlet</title>
<style type="text/css">
body{background-color: green;}
</style>
</head>
<body>
<h1>This is the MySQL Servlet</h1>
<form action = "/database/database" method = "post">
<p>
<label>Enter your query and click the button to invoke a MySQL Servlet
<textarea name = "query" cols="20" rows="5"></textarea>
<input type = "submit" value = "Run MySQL Servlet" />
<input type = "reset" value = "Clear Command" />
</label>
</p>
</form>
<hr>
<TABLE id="results">
<%
ArrayList<String> columns = (ArrayList<String>)request.getAttribute("queryColumns");
ArrayList<String[]> results = (ArrayList<String[]>)request.getAttribute("queryResults");
out.println("<TR>");
if(columns != null && !columns.isEmpty()){
for(String columnName: columns ){
out.println("<TD>"+columnName+"</TD>");
}
}
out.println("</TR>");
//print data
if(results != null && !results.isEmpty()){
for(String[] rowData: results){
out.println("<TR>");
for(String data: rowData){
out.println("<TD>"+data+"</TD>");
}
out.println("</TR>");
}
}
%>
</TABLE>
<%= request.getAttribute("query") %>
<%= request.getAttribute("resultSize") %>
</body>
</html>

Define one list for columns as well.
ArrayList<String[]> results= new ArrayList<String[]>();
ArrayList<String> columns= new ArrayList<String>();
Populate the list of columns as:
for(int i = 1; i<= numberOfColumns; i++){
columns.add(metaData.getColumnName(i));
}
Populate the list of with results row as:
while (resultSet.next()){
String[] row = new String[numberOfColumns];
for (int i = 1; i <= numberOfColumns; i++){
row[i] = (String) resultSet.getObject(i);
}
results.add(row);
}
in the end:
request.setAttribute("queryResults", results);
request.setAttribute("queryColumns", columns);

First of all, why are you adding a toString call on a String type variable?
Now, as for your issue, I would rather create a Class, for the tables in database, with the columns as attributes. And for each row, create an instance of that class from the columns, and add it to the ArrayList.
So, your ArrayList declaration might be like this: -
List<TargetTable> records = new ArrayList<TargetTable>();
And then: -
while (res.next()) {
records.add(new TargetTable(res.getString(1), res.getString(2), ...));
}
I hope you know the number of columns in your table.

ArrayList is not the best data structure for this purpose.
You can use
Table<Integer, String, Object>
which is available in google guava library. It is really easy to use as well

U can have two arraylists as,
ArrayList<String> columnNames = new ArrayList<String>();
ArrayList<String> out = new ArrayList<String>();
Iterate through ResultSetMetadata and add the columns to the columnNames ArrayList.
Then add the columnNames to out :
out.add(columNames);
Then Create a VO class with all the column names in the table you are accessing. create all the getters and setters for the class names.
Then iterate through the Resultset,
set all the values from the result set into that VO class.
add this VO class to the out arrayList.
ResultVO vo ;
while (resultSet.next()){
vo = new ResultVO();
vo.setColumnName1(resultSet.getString(1));
vo.setColumnName2(resultSet.getString(2));
out.add(vo);
}

Related

using Jsoup to extract a table inside several divs

I am trying to use jsoup so as to have access to a table embedded inside multiple div's of an html page.The table is under the outer division with id "content-top". I will give the inner divs leading to the table: content-top -> center -> middle-right-col -> result .
Under the div result; is table round. This is the table that i want to access and whose rows I need to traverse and print out the data contained in them. Below is the java code I have been trying to use but yielding no results :
Document doc = Jsoup.connect("http://www.calculator.com/#").data("express", "sin(x)").data("calculate","submit").post();
// give the application time to calculate result before retrieving result from results table
try {
Thread.sleep(10000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
Elements content = doc.select("div#result") ;
Element tables = content.get(0) ;
Elements table_rows = tables.select("tr") ;
Iterator iterRows = table_rows.iterator();
while (iterRows.hasNext()) {
Element tr = (Element)iterRows.next();
Elements table_data = tr.select("td");
Iterator iterData = table_data.iterator();
int tdCount = 0;
String f_x_value = null;
String result = null;
// process new line
while (iterData.hasNext()) {
Element td = (Element)iterData.next();
switch (tdCount++) {
case 1:
f_x_value = td.text();
f_x_value = td.select("a").text();
break;
case 2:
result = td.text();
result = td.select("a").text();
break;
}
}
System.out.println(f_x_value + " " + result ) ;
}
The above code crashes and hardly does what I want it to do. PLEASE CAN ANYONE PLEASE HELP ME !!!
public static String do_conversion (String str)
{
char c;
String output = "{";
for(int i = 0; i < str.length(); i++)
{
c = str.charAt(i);
if(c=='e')
output += "{mathrm{e}}";
else if(c=='(')
output += '{';
else if(c==')')
output += '}';
else if(c=='+')
output += "{cplus}";
else if(c=='-')
output += "{cminus}";
else if(c=='*')
output += "{cdot}";
else if(c=='/')
output += "{cdivide}";
else output += c; // else copy the character normally
}
output += ", mathrm{d}x}";
return output;
}
#Syam S
The page doesnt directly give you a table in a div with id as "result". It uses an ajax class to a php file and get the process done. So what you need to do here is to first build a json like
{"expression":"sin(x)","intVar":"x","upperBound":"","lowerBound":"","simplifyExpressions":false,"latex":"\\displaystyle\\int\\limits^{}_{}{\\sin\\left(x\\right)\\, \\mathrm{d}x}"}
The expression key hold the expression that you want to evaluate, the latex is a mathjax expression and then post it to int.php. This expects two arguments namely q which is the above json and v which seems to a constant value 1380119311. I didnt understand what this is.
Now this will return a response like
<html>
<head></head>
<body>
<table class="round">
<tbody>
<tr class="">
<th>$f(x) =$</th>
<td>$\sin\left(x\right)$</td>
</tr>
<tr class="sep odd">
<th>$\displaystyle\int{f(x)}\, \mathrm{d}x =$</th>
<td>$-\cos\left(x\right)$</td>
</tr>
</tbody>
</table>
<!-- Finished in 155 ms -->
<p id="share"> <img src="layout/32x32xshare.png.pagespeed.ic.i3iroHP5fI.png" width="32" height="32" /> <a id="share-link" href="http://www.integral-calculator.com/#expr=sin%28x%29" onclick="window.prompt("To copy this link to the clipboard, press Ctrl+C, Enter.", $("share-link").href); return false;">Direct link to this calculation (for sharing)</a> </p>
</body>
</html>
The table in this expression gives you the result and the site uses mathjax to display it like
A sample program would be
import java.io.IOException;
import org.apache.commons.lang3.StringEscapeUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class JsoupParser6 {
public static void main(String[] args) {
try {
// Integral
String url = "http://www.integral-calculator.com/int.php";
String q = "{\"expression\":\"sin(4x) * e^(-x)\",\"intVar\":\"x\",\"upperBound\":\"\",\"lowerBound\":\"\",\"simplifyExpressions\":false,\"latex\":\"\\\\displaystyle\\\\int\\\\limits^{}_{}{\\\\sin\\\\left(4x\\\\right){\\\\cdot}{\\\\mathrm{e}}^{-x}\\\\, \\\\mathrm{d}x}\"}";
Document integralDoc = Jsoup.connect(url).data("q", q).data("v", "1380119311").post();
System.out.println(integralDoc);
System.out.println("\n*******************************\n");
//Differential
url = "http://www.derivative-calculator.net/diff.php";
q = "{\"expression\":\"sin(x)\",\"diffVar\":\"x\",\"diffOrder\":1,\"simplifyExpressions\":false,\"showSteps\":false,\"latex\":\"\\\\dfrac{\\\\mathrm{d}}{\\\\mathrm{d}x}\\\\left(\\\\sin\\\\left(x\\\\right)\\\\right)\"}";
Document differentialDoc = Jsoup.connect(url).data("q", q).data("v", "1380119305").post();
System.out.println(differentialDoc);
System.out.println("\n*******************************\n");
//Calculus
url = "http://calculus-calculator.com/calculation/integrate.php";
Document calculusDoc = Jsoup.connect(url).data("expression", "sin(x)").data("intvar", "x").post();
String outStr = StringEscapeUtils.unescapeJava(calculusDoc.toString());
Document formattedOutPut = Jsoup.parse(outStr);
formattedOutPut.body().html(formattedOutPut.select("div.isteps").toString());
System.out.println(formattedOutPut);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Update based on comment.
The unescape works perfectly well. In MathJax you could right click and view the command. So if you go to your site http://calculus-calculator.com/ and try the sin(x) equation there and right click the result and view TexCommand like
The you could see the commands are exactly the ones which we get after unsescape. The demo site is not rendering it. May be a limitation of the demo site, thats all.

How to export table contents to csv using java?

Here I need to get the values from table instead of manual values like display name, age.
And I don't need to generate csv file in location. Instead, it should show me a popup that I can download the csv file. How to achieve this?
So far I tried this to export data to csv using java.
I used some manual values like display name, age. But I need the values to get from the table. For example
<table>
<td>
--datas--
</td>
</table>
Java Code:
import java.io.FileWriter;
import java.io.IOException;
public class test
{
public static void main(String [] args)
{
generateCsvFile("D:/test.csv");
}
private static void generateCsvFile(String sFileName)
{
try
{
FileWriter writer = new FileWriter(sFileName);
writer.append("DisplayName");
writer.append(',');
writer.append("Age");
writer.append('\n');
writer.append("Dinesh");
writer.append(',');
writer.append("23");
writer.append('\n');
writer.append("Kumar");
writer.append(',');
writer.append("29");
writer.append('\n');
//generate whatever data you want
writer.flush();
writer.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Suppose you have a jsp page with the table. While submitting the jsp page you can form the comma separated table value string from javascript by reading the table.
eg
//gets table
var table= document.getElementById('table1');
//gets rows of table
var rowLen = table.rows.length;
//loops through rows
for (i = 0; i < rowLen; i++){
var oCells = table.rows.item(i).cells;
var cellLen = oCells.length;
for(var j = 0; j < cellLen; j++){
/* get your cell info here */
/* var cellVal = oCells.item(j).innerHTML; */
}
}
and once you have the string of comma separated values, you can pass it to the action handling the submitted request.
I'm assuming you are generating your table dynamically and using httpSession, you can set the table in session like so:
HttpSession.setAttribute("Data", ArrayList<Object> data);
Then get the table from there when generating:
ArrayList<Object> data = this.context.getSession().getAttribute("Data");
Simple solution:
Use RegEx to extract only the inner part of the table (between the
<table></table> tags)
Use RegEx to remove all newlines between <tr></tr> and those tags
themselves (rows)
Use RegEx to replace "</td><td>" with ","
Use RegEx to remove remaining tags

List database values in a Combobox jsp with Bean Class Attached java

I am trying to list values from the database using JSP combobox like this:
My Vector Method:
public Vector getCampusCode(StudentRegistrationBean srb){
lgcampus = srb.getLgcampus();
Vector v = new Vector();
Connection conn = null;
try{
conn = db.getDbConnection();
Statement st = conn.createStatement();
String sql = "select CAMPUS_CODE from campus_master where CAMPUS_NAME = '" + lgcampus + "'";
ResultSet rs = st.executeQuery(sql);
while(rs.next()){
String camp = rs.getString("CAMPUS_CODE");
v.add(camp);
}
}catch(Exception asd){
System.out.println(asd.getMessage());
}
return v;
}
My JSP:
<jsp:useBean id="obj1" class="com.kollega.dao.StudentRegistrationDao" scope="page"/>
<jsp:useBean id="srb" class="com.kollega.bean.StudentRegistrationBean" scope="page"/>
<option selected value="SELECT">SELECT</option>
<c:forEach var="item" items="${obj1.campusCode(srb)}">
<option>${item}</option>
</c:forEach>
</select>
Of course the Combo is not getting Populated and all the other components on the page after the Combo are masked(disappear). If I remove the bean attached to the Vector without the Where Condition, my values are getting listed. But i need only specific values and not all. how Can i achieve this?
I just tried to populate the values in the combo box, it worked just fine. Please see the code below -- JSP
<jsp:useBean id="obj1" class="com.tutorial.ComboValues" scope="page"> </jsp:useBean>
<jsp:useBean id="obj2" class="com.tutorial.Input" scope="page"> </jsp:useBean>
<select>
<option selected value="SELECT">SELECT</option>
<c:forEach var="item" items="${obj1.getValues(obj2)}">
<option>${item}</option>
</c:forEach>
</select>
ComboValues class
public class ComboValues {
public Vector getValues(Input i){
Vector v = new Vector<String>();
if(i.getInput()==0)
v.add("worked");
else
v.add("it hurts");
return v;
}
}
Input class
public class Input {
int value = 0;
public void setInput(int i){
this.value = i;
}
public int getInput(){
return this.value;
}
}
The problem may be in the reference 'srb' you are passing to StudentRegistrationDao#getCampusCode since jsp:useBean will create a new instance of that type when there is no such object available. The other area to check is lgcampus = srb.getLgcampus(); whether it returns a proper value for the where clause. Hope this helps

Populate dropdown based on another dropdown selection

I have two dropdown fields in a JSP page and I have type4 connection with oracle 10g. I want that based on one dropdown selection I want that second dropdown should get filled by fetching data from database based on data in first dropdown automatically just like refreshing that JSP page or showing an alert something like "please wait". How can I do it in JSP-Servlet?
<select name="dropdown1">
<option value="<%out.println(name);%>"><%out.println(name);%></option>
</select>
My objective is: This below dropdown should get filled base don above selection:
<select name="dropdown2">
<option value="<%out.println(rollno);%>"><%out.println(rollno);%></option>
</select>
I have found one solution :
<body onload="setModels()">
<% // You would get your map some other way.
Map<String,List<String>> map = new TreeMap<String,List<String>>();
Connection con=null;
String vehtypeout="";
String vehtypeout1="";
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("");
PreparedStatement ps=null;
ResultSet rs=null;
ps=con.prepareStatement("select c1.name, c2.roll from combo1 c1 left join combo2 c2 on c1.name=c2.name order by name");
rs=ps.executeQuery();
while(rs.next()){
vehtypeout=rs.getString(1);
vehtypeout1=rs.getString(2);
map.put(vehtypeout, Arrays.asList((vehtypeout1)));// here i want to show multiple value of vehtypeout1 from database but only one value is coming from databse, how can i fetch multiple value?
map.put("mercedes", Arrays.asList(new String[]{"foo", "bar"}));
}
rs.close();
ps.close();
con.close();
}
catch(Exception e){
out.println(e);
}
%>
<%! // You may wish to put this in a class
public String modelsToJavascriptList(Collection<String> items) {
StringBuilder builder = new StringBuilder();
builder.append('[');
boolean first = true;
for (String item : items) {
if (!first) {
builder.append(',');
} else {
first = false;
}
builder.append('\'').append(item).append('\'');
}
builder.append(']');
return builder.toString();
}
public String mfMapToString(Map<String,List<String>> mfmap) {
StringBuilder builder = new StringBuilder();
builder.append('{');
boolean first = true;
for (String mf : mfmap.keySet()) {
if (!first) {
builder.append(',');
} else {
first = false;
}
builder.append('\'').append(mf).append('\'');
builder.append(" : ");
builder.append( modelsToJavascriptList(mfmap.get(mf)) );
}
builder.append("};");
return builder.toString();
}
%>
<script>
var modelsPerManufacturer =<%= mfMapToString(map) %>
function setSelectOptionsForModels(modelArray) {
var selectBox = document.myForm.models;
for (i = selectBox.length - 1; i>= 0; i--) {
// Bottom-up for less flicker
selectBox.remove(i);
}
for (i = 0; i< modelArray.length; i++) {
var text = modelArray[i];
var opt = new Option(text,text, false, false);
selectBox.add(opt);
}
}
function setModels() {
var index = document.myForm.manufacturer.selectedIndex;
if (index == -1) {
return;
}
var manufacturerOption = document.myForm.manufacturer.options[index];
if (!manufacturerOption) {
// Strange, the form does not have an option with given index.
return;
}
manufacturer = manufacturerOption.value;
var modelsForManufacturer = modelsPerManufacturer[manufacturer];
if (!modelsForManufacturer) {
// This modelsForManufacturer is not in the modelsPerManufacturer map
return; // or alert
}
setSelectOptionsForModels(modelsForManufacturer);
}
function modelSelected() {
var index = document.myForm.models.selectedIndex;
if (index == -1) {
return;
}
// alert("You selected " + document.myForm.models.options[index].value);
}
</script>
<form name="myForm">
<select onchange="setModels()" id="manufacturer">
<% boolean first = true;
for (String mf : map.keySet()) { %>
<option value="<%= mf %>" <%= first ? "SELECTED" : "" %>><%= mf %></option>
<% first = false;
} %>
</select>
<select onChange="modelSelected()" id="models">
<!-- Filled dynamically by setModels -->
</select>
But i am getting only one value in vehtypeout1 where databse contains multiple values. How can i do it?
Using jquery, bind a function to the onchange event of "combobox1" select box.
In that function, send an ajax request (you can use jquery get function) to a jsp page in your server.
In that jsp page, retrieve the relevant data from database and send the response back to the client with those data (may be you need to use JSON format).
In the jquery get function, you can add a callback function to execute after server send you back the response.
Inside that call back function, write the code to fill "combobox2" using response data sent by the server.
You'll want an ajax call like below. Have your function that is called return a html-string of
"<option value='myVal'>myText</option>".
The jQuery/Ajax would be:
$("#ddl1").change(function() {
$.ajax({
url: "URLyouwanttoaddress",
data: "myselection=" + $("#ddl1").val();
type:"get",
success: function(data) {
$("#ddl2").html(data);
}
});
});

how to increase the data transfer speed from oracle 10g into jsp pages using scriplet

I have incorporated my jsp pages with an autosuggest features, and to make the autosuggest functioning, it has to make an array of the data to be suggested using scriplet.
My issues is, as i import the data from oracle 10G, the time to complete the import of the data into the pages, is about 20-40 second.
Hence, is there any way to increase the speed of data transfer i already try the indexing method but it does help with the time, and the number of data in the table is about 6K .
Can the oracle pro, suggest any ways to solve this issues.. hehe =D
And here is the sample of my program :-
Function in my autosuggest.java, to retrieve and filter the data from my db.
public List getVendorName() throws Exception
{
List temp=null;
Database db=null;
String tempVar, tempVar2;
boolean tempVar3, tempVar4;
int counter=0;
try {
db = PersistenceHelper.beginTransaction();
JDOQuery queryFund = new JDOQuery(db,Trader.class);
queryFund.setFilter(PersistenceHelper.getOrganizationFilter("organization"));
temp = new ArrayList();
QueryResults results = queryFund.execute();
while(results.hasMore())
{
Trader trader = (Trader) results.next();
tempVar = "\""+trader.getName()+"\"";
tempVar2 = trader.getTraderType();
tempVar3 = trader.getRegTraderStatus();
tempVar4 = trader.getMainTraderStatus();
if(!tempVar2.equalsIgnoreCase("c"))
{
if( (tempVar3 == true) && (tempVar4 == true))
{
tempVar = tempVar.replace("\n", "");
temp.add(counter,tempVar); counter++;
}
}
}
}
catch (Exception e) {
System.out.println(e);
}
finally{
PersistenceHelper.closeTransaction(db, false);
}
return temp;
}
Function in my jsp page. to retrieve the data from autosuggest.java;
function getVendorName()
{
var temp = new Array();
<%
AutoSuggest as = new AutoSuggest();
List tempList = as.getVendorName();
for(int i=0; i<tempList.size(); i++)
{
Strinmg tempVar = (String) tempList.get(i);
%> temp[<%=i%>] = <%=tempVar%>; <%
}
%>
return temp;
}
The first thing to try would be to do the filtering by trader type and status in the database query ... rather on the Java side. The way you are currently doing this will entail pulling large numbers of Trader objects from the database. I expect most of them are then being discarded by your Java code.

Categories