In the GetQuote example we provide a list of stocks in a drop down. When a particular stock is selected we want to automatically display the stock description.
index.jsp
<%@ page language="java" %>
<%@ page import="java.sql.*" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<script type="text/javascript" src="Ajax.js"></script>
<html>
<head>
<title>Stock Quote Struts Application</title>
</head>
<body>
<table width="500" border="0" cellspacing="0" cellpadding="0">
<tr>
<td> </td>
</tr>
<tr>
<td height="68" width="48%">
<div align="left">
<img src="images/stockquote.jpg" alt="Logo">
</div>
</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td> </td>
</tr>
</table>
<h2>Enter a Stock Symbol</h2>
<!-- Begin Struts form -->
<html:form action="Lookup">
<table width="45%" border="0">
<tr>
<td>Stock Symbol:</td>
<select name="symbol" onchange="retrieveURL('/getquoteAjax/stockname.do?','lookupForm',this);">
<option value="-1">Select</option>
<%
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/stocks?useSSL=false&allowPublicKeyRetrieval=true";
String user = "root";
String pass = "mysql";
int sumcount = 0;
Statement st;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, user, pass);
String query = "select * from stocks";
st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
%>
<%
while (rs.next()) {
%>
<option value="<%=rs.getString(1)%>"><%=rs.getString(1)%></option>
<%
}
%>
<%
}
catch (Exception e) {
e.printStackTrace();
}
%>
</select>
</tr>
<tr><td><b>Stock Name:</b></td>
<td><span id="stockName"><input type="text" name="stock_name" id="sname" value=""></span></td></tr>
<tr>
<td colspan="2">
<html:submit value="Get Quote" />
</td>
</tr>
</table>
</html:form>
</body>
</html>
Ajax.js
/**
* Ajax.js
*
* Collection of Scripts to allow in page communication from browser to (struts) server
* ie can reload part instead of full page
*
* How to use
* ==========
* 1) Call retrieveURL from the relevant event on the HTML page (e.g. onclick)
* 2) Pass the url to contact (e.g. Struts Action) and the name of the HTML form to post
* 3) When the server responds ...
* - the script loops through the response , looking for <span id="name">newContent</span>
* - each <span> tag in the *existing* document will be replaced with newContent
*
* NOTE: <span id="name"> is case sensitive. Name *must* follow the first quote mark and end in a quote
* Everything after the first '>' mark until </span> is considered content.
* Empty Sections should be in the format <span id="name"></span>
*/
//global variables
// var req;
// var which;
/**
* Get the contents of the URL via an Ajax call
* url - to get content from (e.g. /struts-ajax/sampleajax.do?ask=COMMAND_NAME_1)
* nodeToOverWrite - when callback is made
* nameOfFormToPost - which form values will be posted up to the server as part
* of the request (can be null)
*/
function retrieveURL(url, nameOfFormToPost, selectElement) {
// Get symbol value from the select element
var symbolValue = selectElement.value;
console.log("retrieveURL called", selectElement);
console.log("Symbol value:", symbolValue);
console.log("Base URL:", url);
// Validate selection
if (!symbolValue || symbolValue === "-1" || symbolValue === "") {
alert("Please select a valid stock symbol");
return;
}
// Build final URL with symbol parameter
// Since url already ends with '?', just append the parameter
var finalUrl = url + "symbol=" + encodeURIComponent(symbolValue);
console.log("Final URL:", finalUrl);
// Create XMLHttpRequest
var req;
if (window.XMLHttpRequest) { // Non-IE browsers
req = new XMLHttpRequest();
req.onreadystatechange = function() {
processStateChange(req);
};
try {
req.open("GET", finalUrl, true);
req.send(null);
} catch (e) {
alert("Problem Communicating with Server\n" + e);
}
} else if (window.ActiveXObject) { // IE
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = function() {
processStateChange(req);
};
req.open("GET", finalUrl, true);
req.send();
}
}
}
function processStateChange(req) {
console.log("ReadyState:", req.readyState);
console.log("Status:", req.status);
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
console.log("Processing response..........");
console.log("Ajax response:", req.responseText);
// Split the text response into Span elements
var spanElements = splitTextIntoSpan(req.responseText);
console.log("Span elements:", spanElements);
//alert("Span elements:", spanElements);
// Use these span elements to update the page
replaceExistingWithNewHtml(spanElements);
} else {
alert("Problem with server response:\n " + req.statusText);
}
}
}
/**
* Splits the text into <span> elements
* @param the text to be parsed
* @return array of <span> elements - this array can contain nulls
*/
function splitTextIntoSpan(textToSplit){
//Split the document
returnElements=textToSplit.split("</span>")
//Process each of the elements
for ( var i=returnElements.length-1; i>=0; --i ){
//Remove everything before the 1st span
spanPos = returnElements[i].indexOf("<span>");
//if we find a match , take out everything before the span
if(spanPos>0){
subString=returnElements[i].substring(spanPos);
returnElements[i]=subString;
}
}
return returnElements;
}
/*
* Replace html elements in the existing (ie viewable document)
* with new elements (from the ajax requested document)
* WHERE they have the same name AND are <span> elements
* @param newTextElements (output of splitTextIntoSpan)
* in the format <span id=name>texttoupdate
*/
function replaceExistingWithNewHtml(newTextElements){
//loop through newTextElements
for ( var i=newTextElements.length-1; i>=0; --i ){
//check that this begins with <span
if(newTextElements[i].indexOf("<span")>-1){
//get the name - between the 1st and 2nd quote mark
startNamePos=newTextElements[i].indexOf('"')+1;
endNamePos=newTextElements[i].indexOf('"',startNamePos);
name=newTextElements[i].substring(startNamePos,endNamePos);
//get the content - everything after the first > mark
startContentPos=newTextElements[i].indexOf('>')+1;
content=newTextElements[i].substring(startContentPos);
//Now update the existing Document with this element
//check that this element exists in the document
console.log("element check:", document.getElementById(name));
console.log("element name:", name);
if(document.getElementById(name)){
//alert("Replacing Element:"+name);
document.getElementById(name).innerHTML = content;
} else {
//alert("Element:"+name+"not found in existing document");
}
}
}
}
struts-config.xml changes
<action path="/stockname"
type="org.StockNameAction"
name="lookupForm" >
<forward name="success" path="/index.jsp" />
<forward name="failure" path="/index.jsp" />
</action>
StockNameAction.java
package org;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.io.*;
import org.apache.log4j.Logger;
public class StockNameAction extends Action {
protected final Logger log = Logger.getLogger(getClass());
protected String getStockName ( HttpServletRequest request, String symbol) {
String stockName = null;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
DataSource dataSource = null;
try {
dataSource = getDataSource(request);
conn = dataSource.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery ("select stock_name from stocks where symbol = '" + symbol + "'");
if (rs.next()){
String tmp = "";
tmp = rs.getString("stock_name");
stockName = new String(tmp);
System.err.println ("stockName : " + stockName);
} //end rs.next
else {
System.err.println("Symbol not found returning null [" + symbol);
}
} //end try
catch (SQLException sqle) {
System.err.println (sqle.getMessage());
}
finally {
if (rs != null) {
try {
rs.close();
}
catch (SQLException sqle) {
System.err.println (sqle.getMessage());
}
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} //end try
catch (SQLException sqle) {
System.err.println (sqle.getMessage());
}
stmt = null;
} // end stmt not null
if (conn != null) {
try {
conn.close();
} //end try
catch (SQLException sqle) {
System.err.println (sqle.getMessage());
}
conn = null;
} // end conn not null
} //end finally
if ( symbol.equalsIgnoreCase ("SUNWWWW") ) {
return new String ("SUNWWWW");
}
return stockName;
} //end Action
public ActionForward execute (ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response )
throws IOException, ServletException {
String stockName = null;
String target = new String ("success");
if (form != null ) {
//Use the LookupForm to get the request parameters
LookupForm lookupForm = (LookupForm) form;
String symbol = lookupForm.getSymbol();
// request.getParameter(symbol);
// System.err.println("In execute Symbol " + symbol);
log.debug("StockNameAction " + symbol);
stockName = getStockName(request, symbol);
StringBuilder html = new StringBuilder();
html.append("<span id=\"stockName\">")
.append("<input type=\"text\" name=\"stock_name\" id=\"sname\" value=\"")
.append(stockName)
.append("\" readonly>")
.append("</span>");
System.out.println("Generated HTML: " + html.toString());
// Write directly to response
response.setContentType("text/html;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
out.print(html.toString());
out.flush();
out.close();
System.out.println("=== getStockName END ===");
}
return null; // Important: return null when writing directly to response
} //execute
}
No comments:
Post a Comment