You can include content into your servlets using the following techniques:
include method
getResource methodFor more information on using the RequestDispatcher object, see "Passing control".
You can use the RequestDispatcher object's include method to include multiple types of content in your servlet:
include method copies the text into the output stream. This text can include HTML tags.
include method invokes the servlet.RequestDispatcher object wraps a JSP, the include method invokes the JSP.
When you use the include method, the calling servlet can write to ServletOutputStream or PrintWriter objects before and after calling the include method. If necessary, you can pass information to the target servlet or JSP using the ServletRequest object's setAttribute method, as described in "Passing control", or using session objects, as described in "Working with sessions".
The following example includes a servlet:
...
PrintWriter out = resp.getWriter();
ServletContext sc = this.getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher("/servlet/includeMe");
if (rd !=null) {
try {
// Note- the included servlet has control over its own buffer only.
rd.include(req, resp);
}
catch (Exception e) {
sc.log("Problem invoking servlet.", e);
}
}
...
To see a sample servlet, start the samples JRun server and open a browser to http://localhost:8200/techniques.
You can use the ServletContext object's getResource method to include content in your servlet. The getResource method returns a URL object. Then you can use the URL object to access the content. One advantage of using the URL object is that you can parse the content before returning it to the browser. You can also use this technique to include content that is otherwise not accessible to the users directly, such as files in the /WEB-INF directory.
The following example includes content using the getResource method:
...
resp.setContentType("text/html");
ServletOutputStream out = resp.getOutputStream();
ServletContext sc = this.getServletContext();
try {
URL u = sc.getResource("/includedText.htm");
if (u !=null) {
// Access the content, casting to an InputStream
InputStream in = (InputStream)u.getContent();
byte[] buf = new byte[255];
int numRead = in.read(buf);
while(numRead != -1){
out.write(buf, 0, numRead);
numRead = in.read(buf);
}
}else {
out.println("<p>u was null");
}
} catch (Exception e) {}
...
J2EE makes it easy to get web pages from the Internet, parse those pages, and include the content in your own pages. Common applications of this technique are to add box scores or stock ticker symbols price quotes to your own pages to provide dynamic data.
The target website must output regular data that you can parse using known string. Regular data means that each piece falls within a set of delimiters. To get price information, for example, the price of a product must be represented the same way with the same HTML tags surrounding it on the target page for all of your harvesting calls to work.
For example, the website www.funagain.com generates dynamic pages using a game ID. Funagain generates a page that lists a number of attributes such as price, designer, and manufacturer for each game. These attributes are represented in the HTML of the Funagain web pages as hidden form fields, as the following example shows:
<INPUT TYPE="HIDDEN" NAME="manufacturer" VALUE="Amigo">
In this example, the HTML page that shows a game's details at Funagain contains a hidden form field that defines the manufacturer. Funagain generates a page with the same regularity for all games. In the same manner, finance.yahoo.com generates page with the same data format for stock quotes.
You can use the technique in this section to extract the value of the manufacturer hidden form field.
...
String gameID = request.getParameter("gameID");
String urlString = "http://kumquat.com/cgi-kumquat/funagain/" + gameID;
...
funagainURL = new URL(urlString);
...
funagainConnection = funagainURL.openConnection();
webPageInputStream = funagainConnection.getInputStream();
...
StringBuffer webPageDataBuffer = new StringBuffer(32000);
int totalBytesRead = 0;
boolean moreToRead = true;
byte[] readBuf = new byte[4096]; // Read the web page in 4K chunks
while (moreToRead) {
int numBytesRead = 0;
try {
numBytesRead = webPageInputStream.read(readBuf);
} catch (IOException e) {
moreToRead = false;
numBytesRead = -1;
}
if (numBytesRead > 0) {
totalBytesRead += numBytesRead;
webPageDataBuffer.append(new String(readBuf, 0, numBytesRead));
} else {
moreToRead = false;
}
}
...
webpageDataBuffer.setLength(totalBytesRead);
...
String webPageData = webPageDataBuffer.toString();
label[3] = "Year: "; predetails[3] = "year\" VALUE=\""; postdetails[3] = "\">";
This example searches for the occurrence of the following String as the starting delimiter:
year" VALUE="The example searches for \"> and sets that as an ending delimiter.
The following line from the target website matches the search:
<INPUT TYPE="HIDDEN" NAME="year" VALUE="1999">The 1999 is delimited by the predetails and postdetails delimiters.
...
int preStringLoc;
int postStringLoc;
preStringLoc = WebPageData.indexOf(predetails[i]);
postStringLoc = WebPageData.indexOf(postdetails[i], preStringLoc);
if (preStringLoc == -1 || postStringLoc == -1) {
details[i] = "N/A";
} else {
details[i] = WebPageData.substring(preStringLoc + predetails[i].length(), postStringLoc);
}
...
...
for (int i = 0; i < details.length; i++) {
out.println(label[i] + details[i]);
out.println("<BR>");
}
...
To see a sample servlet, start the samples JRun server and open a browser to http://localhost:8200/techniques.