How to save a .pdf from a browser? - java

I tried to save .pdf file using different methods I found on stackoverflow including FileUtils IO, however, I would always get it damaged. As I opened the damaged file using a notepad I got the following stuff:
<HEAD>
<TITLE>
09010b129fasdf558a-
</TITLE>
</HEAD>
<HTML>
<SCRIPT language="javascript" src="./js/windowClose.js"></SCRIPT>
<LINK href="./theme/default.css" rel="stylesheet" type="text/css">
<LINK href="./theme/additions.css" rel="stylesheet" type="text/css">
<BODY leftmargin="0" topmargin="0">
<TABLE cellpadding="0" cellspacing="0" width="100%">
<TR>
<TD class="mainSectionHeader">
<A href="javascript:windowClose()" class="allLinks">
CLOSE
</A>
</TD>
</TR>
</TABLE>
<script language='javaScript'>
alert('Session timed out. Please login again.\n');
window.close();
</script>
</BODY>
</HTML>
Later, I tried to save a .pdf file from a browser using the answer provided by #BalusC. This solution is very helpful: I was able to get rid of the session issues. However, it also produces a damaged .pdf. But as I open it with a notepad, it is completely different. There are no login issues anymore though:
<HTML>
<HEAD>
<TITLE>
Evidence System
</TITLE>
</HEAD>
<LINK href="./theme/default.css" rel="stylesheet" type="text/css">
<TABLE cellpadding="0" cellspacing="0" class="tableWidth760" align="center">
<TR>
<TD class="headerTextCtr">
Evidence System
</TD>
</TR>
<TR>
<TD colspan="2">
<HR size="1" noshade>
</TD>
</TR>
<TR>
<TD colspan="2">
<HTML>
<HEAD>
<link href="./theme/default.css" rel="stylesheet" type="text/css">
<script language="JavaScript">
function trim(str)
{
var trmd_str
if(str != "")
{
trmd_str = str.replace(/\s*/, "")
if (trmd_str != ""){
trmd_str = trmd_str.replace(/\s*$/, "")
}
}else{
trmd_str = str
}
return trmd_str
}
function validate(frm){
//check for User name
var msg="";
if(trim(frm.userName.value)==""){
msg += "Please enter your user id.\n";
frm.userName.focus();
}
if(trim(frm.password.value)==""){
msg += "Please enter your password.\n";
frm.userName.focus();
}
if (trim(msg)==""){
frm.submit();
}else{
alert(msg);
}
}
function numCheck(event,frm){
if( event.keyCode == 13){
validate(frm);
}
}
</script>
</HEAD>
<BODY onLoad="document.frmLogin.userName.focus();">
<FORM name='frmLogin' method='post' action='./ServletVerify'>
<TABLE width="100%" cellspacing="20">
<tr>
<td class="mainTextRt">
Username
<input type="text" name="userName" maxlength="32" tabindex="1" value=""
onKeyPress="numCheck(event,this.form)" class="formTextField120">
</TD>
<td class="mainTextLt">
Password
<input type="password" name="password" maxlength="32" tabindex="2" value=""
onKeyPress="numCheck(event,this.form)" class="formTextField120">
</TD>
</TR>
<tr>
<td colspan="2" class="mainTextCtr" style="color:red">
Unknown Error
</td>
</tr>
<tr>
<td colspan="2" class="mainTextCtr">
<input type="button" tabindex="3" value="Submit" onclick="validate(this.form)" >
</TD>
</TR>
</TABLE>
<INPUT TYPE="hidden" NAME="actionFlag" VALUE="inbox">
</FORM>
</BODY>
</HTML>
</TD>
</TR>
<TR>
<TD height="2"></TD>
</TR>
<TR>
<TD colspan="2">
<HR size="1" noshade>
</TD>
</TR>
<TR>
<TD colspan="2">
<LINK href="./theme/default.css" rel="stylesheet" type="text/css">
<TABLE width="80%" align="center" cellspacing="0" cellpadding="0">
<TR>
<TD class="footerSubtext">
Evidence Management System
</TD>
</TR>
<!-- For development builds, change the date accordingly when sending EAR files out to Wal-Mart -->
<TR>
<TD class="footerSubtext">
Build: v3.1
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
</HTML>
What other options do I have?
PS: When I try to save the file manually using CTRL+Shift+S , the file gets saved OK.

From the errorneous response which appears to be just a HTML error page:
alert('Session timed out. Please login again.\n');
It thus appears that downloading the PDF file is required to take place in a valid HTTP session. The HTTP session is backed by a cookie. The HTTP session in turn contains in the server side usually information about the currenty active and/or logged-in user.
The Selenium web driver manages cookies all by itself fully transparently. You can obtain them programmatically as follows:
Set<Cookie> cookies = driver.manage().getCookies();
When manually fiddling with java.net.URL outside control of Selenium, you should be making sure yourself that the URL connection is using the same cookies (and thus also maintaining the same HTTP session). You can set cookies on the URL connection as follows:
URLConnection connection = new URL(driver.getCurrentUrl()).openConnection();
for (Cookie cookie : driver.manage().getCookies()) {
String cookieHeader = cookie.getName() + "=" + cookie.getValue();
connection.addRequestProperty("Cookie", cookieHeader);
}
InputStream input = connection.getInputStream(); // Write this to file.

A PDF is considered a Binary File and it gets corrupted because the way that copyUrlToFile() works. By the way, this looks like a duplicate of JAVA - Download Binary File (e.g. PDF) file from Webserver
Try this custom binary download method out -
public void downloadBinaryFile(String path) {
URL u = new URL(path);
URLConnection uc = u.openConnection();
String contentType = uc.getContentType();
int contentLength = uc.getContentLength();
if (contentType.startsWith("text/") || contentLength == -1) {
throw new IOException("This is not a binary file.");
}
InputStream raw = uc.getInputStream();
InputStream in = new BufferedInputStream(raw);
byte[] data = new byte[contentLength];
int bytesRead = 0;
int offset = 0;
while (offset < contentLength) {
bytesRead = in.read(data, offset, data.length - offset);
if (bytesRead == -1)
break;
offset += bytesRead;
}
in.close();
if (offset != contentLength) {
throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes");
}
String filename = u.getFile().substring(filename.lastIndexOf('/') + 1);
FileOutputStream out = new FileOutputStream(filename);
out.write(data);
out.flush();
out.close();
}
EDIT: It actually sounds as if you are not on the page that you think you are.. instead of doing
driver.getCurrentUrl()
Have your script take the Url from the link to the PDF. Assuming there is a link like <a href='http://mysite.com/my.pdf' /> Instead of clicking it, then getting the url, just take the href from that link, and download it.
String pdfPath = driver.findElement(By.id("someId")).getAttribute("href");
downloadBinaryFile(pdfPath);

The server may be compressing the pdf. You can use this code, stolen from this answer to detect and decompress the response from the server,
InputStream is = driver.getCurrentUrl().openStream();
try {
InputStream decoded = decompressStream(is);
FileOutputStream output = new FileOutputStream(
new File("C:\\Users\\myDocs\\myfolder\\myFile.pdf"));
try {
IOUtils.copy(decoded, output);
}
finally {
output.close();
}
} finally {
is.close();
}
public static InputStream decompressStream(InputStream input) {
PushBackInputStream pb = new PushBackInputStream( input, 2 ); //we need a pushbackstream to look ahead
byte [] signature = new byte[2];
pb.read( signature ); //read the signature
pb.unread( signature ); //push back the signature to the stream
if( signature[ 0 ] == (byte) 0x1f && signature[ 1 ] == (byte) 0x8b ) //check if matches standard gzip maguc number
return new GZIPInputStream( pb );
else
return pb;
}

When I try to save the file manually using CTRL+Shift+S , the file
gets saved OK.
While I advocate using Java to download the file, there is a not-so-recommended workaround that presses Ctrl+Shift+S programatically: The Robot class.
It sucks to use a workaround, but it works reliably as far as I can tell in the browsers and OSes I tried. This code should not get into any serious application. But it's OK for tests if you won't be able to solve your issue the right way.
Robot robot = new Robot();
Press Ctrl+Shift+S
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_S);
robot.keyRelease(KeyEvent.VK_S);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.keyRelease(KeyEvent.VK_CONTROL);
In browsers and OSes I know, you should be in the Save file dialogue in the File name input. You can type in your absolute path:
robot.keyPress(KeyEvent.VK_C); // C
robot.keyRelease(KeyEvent.VK_C);
robot.keyPress(KeyEvent.VK_COLON); // : (colon)
robot.keyRelease(KeyEvent.VK_COLON);
robot.keyPress(KeyEvent.VK_SLASH); // / (slash)
robot.keyRelease(KeyEvent.VK_SLASH);
// etc. for the whole file path
robot.keyPress(KeyEvent.VK_ENTER); // confirm by pressing Enter in the end
robot.keyRelease(KeyEvent.VK_ENTER);
To get the keycodes, you can use KeyEvent#getExtendedKeyCodeForChar() (Java 7+ only), or How can I make Robot type a `:`? and Convert String to KeyEvents.

Related

getting Russian input from web into java applcation

I obviously am missing something here. I have a web app where the input for a form may be in English or, after a keyboard switch, Russian. The meta tag for the page is specifying that the page is UTF-8. That does not seem to matter.
If I type in "вв", two of the unicode character: CYRILLIC SMALL LETTER VE
What do I get? A string. I call getCodePoints().toArray() and I get:
[208, 178, 208, 178]
If I call chars().toArray[], I get the same.
What the heck?
I am completely in control of the web page, but of course there will be different browsers. But how can I get something back from the web page that will let me get the proper cyrillic characters?
This is on java 1.8.0_312. I can upgrade some, but not all the way to the latest java.
The page is this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Cards</title>
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity = "sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin = "anonymous" />
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity = "sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin = "anonymous" />
<script src = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity = "sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin = "anonymous">
</script>
<meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" />
<style>.table-nonfluid { width: auto !important; }</style>
</head>
<body>
<div style = "padding: 25px 25px 25px 25px;">
<h2 align = "center">Cards</h2>
<div style = "white-space: nowrap;">
Home
<div>
<form name="f_3_1" method="post" action="/cgi-bin/WebObjects/app.woa/wo/ee67KCNaHEiW1WdpdA8JIM/2.3.1">
<table class = "table" border = "1" style = "max-width: 50%; font-size: 300%; text-align: center;">
<tr>
<td>to go</td>
</tr>
<tr>
<td><input size="25" type="text" name="3.1.5.3.3" /></td>
</tr>
<td>
<input type="submit" value="Submit" name="3.1.5.3.5" /> Skip
</td>
</table>
<input type="hidden" name="wosid" value="ee67KCNaHEiW1WdpdA8JIM" />
</form>
</div>
</div>
</div>
</body>
</html>
Hm. Well, here is at least part of the story.
I have this code:
System.out.println("start: " + start);
int[] points = start.chars().toArray();
byte[] next = new byte[points.length];
int idx = 0;
System.out.print("fixed: ");
for (int p : points) {
next[idx] = (byte)(p & 0xff);
System.out.print(Integer.toHexString(next[idx]) + " ");
idx++;
}
System.out.println("");
The output is:
start: вв
fixed: ffffffd0 ffffffb2 ffffffd0 ffffffb2
And the UTF-8 value for "В", in hex, is d0b2.
So, there it is. The question is, why is this not more easily accessible? Do I really have to put this together byte-pair by byte-pair?
If the string is already in UTF-8, as I think we can see it is, why does the codePoints() method not give us, you know, the codePoints?
Ok, so now I do:
new String(next, StandardCharsets.UTF_8);
and I get the proper string. But it still seems strange that codePoints() gives me an IntStream, but if you use these things as int values, it is broken.
It was a problem with the frameworks I was using. I thought I was setting the request and response content type to utf-8 but I was not.

Character Encoding not working for Japanese ,Chinese and Korean

I have Unicode characters for all the European countries and for a few Asian countries like Japan, China, Korean. All the Unicodes are working fine for European countries except for Japan, China, Korean.
Example for Japan:
dear_name=\u30c7\u30a3\u30fc\u30e9\u30fc
Example for China:
dear_name=\u4eb2\u7231\u7684
Example for Korean:
dear_name=\uce5c\uc560\ud558\ub294
Example for Sweden (this one is working fine):
dear_name=Till
Default character encoding is UTF-8.
Template template = VelocityFactory.getTemplate("test.vm", "UTF-8");
String messageText = VelocityFactory.merge(context, template, charset);
While debuging the merge method I found out that the merged result is getting grabled here itself for chinese,Japanese,korean.
public static String merge(VelocityContext context, Template template, String charset) throws Exception {
String newResult = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
OutputStreamWriter streamWriter;
if(charset != null && charset.length() > 0) {
streamWriter = new OutputStreamWriter(outputStream, charset);
} else {
streamWriter = new OutputStreamWriter(outputStream);
}
template.merge(context, streamWriter);
streamWriter.close();
mergedResult = outputStream.toString();
outputStream.close();
return newResult;
}
}
Below is the mail template and only for header it is displaying in correct format for Japanese, Chinese, and Korean, but not for the body:
<html>
<head>
<meta http-equiv="Content-Type" content="$contentType">
</head>
<body>
<div id="content">
<table border="0" cellpadding="0" cellspacing="0" style="margin-left: 0px;">
<tr>
<td>
<table border="0" cellpadding="0" cellspacing="0" class="textBody" style="margin-bottom: 120px;">
<tr>
<td valign="bottom" class="mainHeader" nowrap>
$velocityUtils.getMessage("test")
</td>
</tr>
<tr>
<td colspan="2">
<img src="$imageBar" class="clipped">
</td>
</tr>
</table>
<div id="info" class="textBody">$velocityUtils.getMessage("test1")<br><br></div>
</td>
</tr>
</table>
</div>
</body>
</html>
Any information how to fix this? How do i encode correctly??
try adding this to the top of your JSP
<%# page language="java" pageEncoding="UTF-8"%>
you need to specify the character sets for japanese, korean and chinese
For japanese try: charset=iso-2022-jp
For korean try: charset=iso-2022-kr
For chinese try: charset=big5

How to update a specific section of html/jsp page on click of button?

i has been stuck at a point.
I will try to explain my problem in the simple way-
This is my jsp page -
This is my jsp code -
<%#page import="org.w3c.dom.Document"%>
<%#page import="com.Search.Struts2.DataEnterActionClass"%>
<%# page contentType="text/html; charset=UTF-8" %>
<%# page import="javax.servlet.http.HttpServletResponse"%>
<%-- <%# page import="com.Search.Struts2.AccessCheckComponent"%> --%>
<jsp:include page="SessionCheckout.jsp"></jsp:include>
<html>
<head>
<%
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
%>
<div id="nav" style="width:150px; float:left;">
<table>
<%
String StrParentObjectName = "";
StrParentObjectName = (String) DataEnterActionClass.getDocumentName(strObjectId) ;
String hidingRowL1 = HidingRows(strObjectId, ConnectedData, "L1");
String StrGlobal3dXML = (String) DataEnterActionClass.getFile(strObjectId);
%>
<tr>
<td width="25px"><b><a style="text-decoration: none;"
href="javascript:toggle_visibility('tbl1', '<%=strObjectId.toString()%>' , '<%=true%>', '<%= hidingRowL1 %>');">
<div id="<%=strObjectId + "plus" %>" name="lnk1">+</div> </a></b></td>
<td align="left" style="font-size: 120%;">
<a onclick="Here i will have to set value for param tag using javascript">
<%=StrParentObjectName%> </a>
</td>
</tr>
<%
if(ConnectedData.keySet().contains(strObjectId))
{
ArrayList childList = (ArrayList) ConnectedData.get(strObjectId);
Collections.sort(childList);
for(int i=0; i<childList.size(); i++)
{
String childObjectId = (String) childList.get(i);
String hidingRowL2 = HidingRows(childObjectId, MapAll5thLevelChild, "L2"); // 2
String prientedData = (String) DataEnterActionClass.getDocumentName(childObjectId) ;
String RowIdCreationL1 = strObjectId + childObjectId + "L1"; // 1
StrGlobal3dXML = (String) DataEnterActionClass.getFile(childObjectId) ;
%>
<tr id="<%= RowIdCreationL1 %>" >
<td><b><a style="text-decoration: none;"
href="javascript:toggle_visibility('tbl1', '<%=childObjectId.toString()%>' , '<%=true%>', '<%= hidingRowL2 %>');">
<div id="<%=childObjectId + "plus" %>" name="lnk1">+</div> </a></b></td>
<td align="left" height="10" style="font-size: 90%;">
<a onclick="Here i will have to set value for param tag using javascript">
<%=prientedData%> </a> <sup>1</sup> </td>
</tr>
<script>
window.onload = VisibleFalse('<%=RowIdCreationL1%>');
</script>
<%
}
}
%>
</table>
</div>
<div id="section" style = "width:800px; height:700px; float:left;" >
<object type='application/x-3dxmlplugin' id='3DXMLPluginId' style="width: 600px; height: 500px;">
<!-- <param name='DocumentFile' value='D:\IETM\CheckedInFiles\Model\Compart_Two\watch.3dxml'>
-->
<param name='DocumentFile' id="fileId" value= " This i want to change dynamically ">
</object>
</div>
</html>
Here simply I am using two div's one with id='nav' & other with id='section'.
In image if i click on Boat hyperlink(left side), then 3dxml image attached with boat should be displayed in right side.
For this i am calling javascript on boat hyperlink & try to update param tag value (like hard-coded) & that div 'section' too. I am getting this value in java 'StrGlobal3dXML' string variable.
I tried to achieve by so many ways, like by js, by ajax, but unsuccessful.
This is very crucial for me. Any way to achieve this or any suggestion, hint will be very very helpful.
Please try to give the solution in javascript or any other way excepting jQuery. i don't know even abc of jQuery.
Thank you !!
Finally I got the answer.
In the Ajax, You call your object tag like this -
<object type='application/x-3dxmlplugin' id='3DXMLPluginId' style="width: 800px; height: 700px; ">
<param name='DocumentFile' value="\\10.60.3.47/IETM_CheckedInFiles/Model/Deck_One/watch.3dxml">
</object>
Now in TreeView.jsp -
function Print3dXML()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","IETMAjaxCall_getFile.jsp?q=",true);
xmlhttp.send();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("section").innerHTML = xmlhttp.responseText;
}
}
}
I think , this may complete your requirement.

Looping through a list of images in JSP and calling a servlet to display each one in a table, but the final output displays same image

I am working on an assignment in which I have to provide a user login after which he will be directed to a page where he can upload images and all of his previous + new images will be displayed below in a table. So the structure of my application is like this...
(trimmed most of the code for clarity)
JSP file that allows upload and displays the image
<p>Please select an image file to upload(Max file size 1 MB)</p>
<%
Integer userId = 0;
userId = (Integer) session.getAttribute("userId");
%>
<%
String errorMessage = (String) request.getAttribute("error");
if (errorMessage != null) {
out.print("<h4> " + errorMessage + "</h4>");
}
%>
<form action="imageupload" enctype="multipart/form-data" method="post">
<br /> <input type="file" name="uploader" id="uploader" /> <br /> <br />
<input type="submit" /> <input type="button"
value="clear" onClick="clear()" />
</form>
<br />
<h4>Uploaded Images</h4>
<br />
<table width="80%">
<tr>
<th>S No.</th>
<th>Name</th>
<th>size</th>
<th>Preview</th>
<th>Actions</th>
</tr>
<%
UserImagesDAOImplementation userImages = new UserImagesDAOImplementation();
List<Image> images = (List<Image>) userImages.getUserImages(userId);
for (Image image : images) {
%>
<tr>
<td><%=image.getSn()%></td>
<td><%=image.getImageName()%></td>
<td><%=image.getSize()%></td>
<td><% session.setAttribute("image",image.getImage() ); %><img src="toimage" height="100px" width="100px" /></td>
<td><img src="img/edit.png" /> <img src="img/url.png" /></td>
</tr>
<%
}
%>
</table>
<br />
Total space used: <%= (userImages.getSizeUsage(userId)/1024) %> KB / 10 MB
the "toimage" servlet that returns the image
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Byte[] image = (Byte[]) session.getAttribute("image");
int len = image.length;
byte[] imageData = new byte[len];
for(int i=0; i < len; i++) {
imageData[i] = image[i];
}
response.setContentType("image/jpg");
response.getOutputStream().write(imageData);
response.getOutputStream().flush();
response.getOutputStream().close();
}
My problem is that it displays the last image in the list in all the table rows and after uploading some other image it displays that new image in every row.
I am not very confident about my design for the site but this is the first time I am working with JSP. I decided to get the image list inside JSP as I will have to perform some more operations on it later on. I guess the problem is either in setting the session variable or the src servlet being called in the end. Whatever it is, can someone please explain the typical flow of events in this design.
Edit:
Putting a print statement inside the "toimage" servlet proves that it is being called just once. So how can I make the JSP loop to call the image src every time ??
You use a single session attribute to store every image. So, at the end of the loop, this session attribute contains the last one.
You shouldn't use the session at all. Instead, you should pass the ID or name or whatever identifies the image as a URL parameter:
<img src="toimage?imageId=<%= image.getId() %>" height="100px" width="100px" />
And the servlet should use this parameter to now which image it must oad and send to the browser.
Also, learn the JSTL and the EL. Scriptlets sould not be used.

Geocortext IMF framework Null reference exception

Still having issues with this problem. Please help if you can.
So I am trying to fix a piece of code using the Geocortex IMF framework. I get an error on line 40 which is basically pulling a null exception. It is a mix of java and html. For some reason I can't seem to find out why the error is pulling up a null. Even if I load the variable with data, it still stops at rs = activeLayer.getRecordset();
Here is the Address Form they fill out and submit
<%# page errorPage="imfError.jsp" %>
<%
/*
Program: afoAddressForm.jsp
Purpose: Displays a page to the user to input address values for a
USAddress type of geocoding query.
Usage: </>
History:
*/
String layerId = request.getParameter("layerid");
String scale = request.getParameter("scale");
if (layerId == null) {
throw new Exception("Missing layerid parameter.");
}
if (scale == null) {
throw new Exception("Missing scale parameter.");
}
%>
<jsp:include page="/imfCopyright.jsp"/>
<html>
<head>
<title></title>
<meta http-equiv="Content-Style-Type" content="text/css">
<link href="../../../imfStyle.css" rel="stylesheet" type="text/css">
<script language="JavaScript" type="text/javascript">
function doNothing() {
}
function submitForm() {
var strStreetName = document.frm.streetName.value;
if (strStreetName == "") {
alert("Please enter street name." );
document.frm.streetNumber.focus();
} else {
document.frm.action = "afoAddress.jsp?streetName="+strStreetName;
document.frm.submit();
}
}
</script>
</head>
<body bgcolor="#FFFFFF" alink="#ff0000" link="#ff0000" vlink="#ff0000">
<form name="frm" action="JavaScript:doNothing()" method="post">
<input type="hidden" name="layerid" value="<%= layerId %>">
<input type="hidden" name="scale" value="<%= scale %>">
<table width="95%" border="0" cellspacing="0" cellpadding="0">
<center>
<tr><td align="left" class="bb11">Zoom To Street<hr></td></tr>
<tr><td height="10"></td></tr>
<tr>
<td align="left" valign="top" class="bn8">
Enter the street name where you wish to centre the map.
If matching streets are found, you will be shown a list
of matching street names for you to choose where to
zoom the map to.
</td>
</tr>
<tr><td height="10"></td></tr>
<tr><td align="center" class="bb8">Street Name</td></tr>
<tr><td align="center" class="bb8"><input name="streetName" size="15" maxLength=40 value=""></td></tr>
<tr><td height="10"></td></tr>
<tr><td align="center" ><input name="btn" type="button" value="Submit" onclick="JavaScript:submitForm()"></td></tr>
<tr><td height="10"></td></tr>
</center>
</table>
</form>
</body>
</html>
Here is what the address form submits to
<%# page import="com.moximedia.aims.*" %>
<%
/*
Program: imfGeocodeUSAddress.jsp
An Internet Mapping Framework (IMF) system script
Copyright 2002 Province of British Columbia - all rights reserved
Purpose: Displays a page of positions matching the address
input by the user for USAddress geocoding styles.
History: 20020610 Cates: original coding
20030724 Cates: send user selection to separate script for labelling.
20040525 Cates: changed frame reference top to parent
20050103 Cates: added type to stylesheet link.
*/
String layerId = request.getParameter("layerid");
String scale = request.getParameter("scale");
String StreetName = request.getParameter("streetName");
AimsMap map = (AimsMap) (session.getAttribute("map"));
AimsFeatureLayer activeLayer = (AimsFeatureLayer) map.getLayers().getLayer(layerId);
AimsRecordset rs = null;
AimsFilter streetFilter = new AimsFilter();
if (activeLayer != null && activeLayer.getFilter()!= null) {
streetFilter = (AimsFilter) activeLayer.getFilter();
}
String query_String="";
if (StreetName == null) {
return;
}else{
StreetName = StreetName.toUpperCase();
query_String = "upper(FENAME) = '" + StreetName +"'";
//query_String = "FENAME like '%" + StreetName +"%'";
streetFilter.setWhereExpression(query_String);
}
// do the query, and whatever we need to do with the data
rs = activeLayer.getRecordset();
rs.clear();
rs.clearFilter();
rs.setMaximumResults(100);
rs.setBufferSize(rs.getMaximumResults());
rs.setFilter(streetFilter);
rs.query();
int count = 0;
rs.moveFirst();
while(!rs.EOF()) {
count++;
rs.moveNext();
}
%>
<jsp:include page="/imfCopyright.jsp"/>
<html>
<head>
<title></title>
<meta http-equiv="Content-Style-Type" content="text/css">
<link href="imfStyle.css" rel="stylesheet" type="text/css">
<script language="JavaScript" type="text/javascript">
function submitForm() {
document.query.submit();
}
</script>
</head>
<body onload="submitForm();">
<form name="query" method="post" action="afoSelectDefaultFind.jsp">
<input type="hidden" name="layerid" value="<%= layerId%>" >
<input type="hidden" name="rec" value="1" >
<input type="hidden" name="total" value="<%=count%>" >
<input type="hidden" name="query_String" value="<%=query_String%>" >
</form>
</body>
</html>
The error is when you hit submit on the form the java.lang.NullPointerException error pops up and put it on line 40 which is rs = activeLayer.getRecordset();. Any help with this would be great.
Well, my guess is that activeLayer is null and then you are calling getRecordset() on a null object reference. Can you try to debug
map.getLayers().getLayer(layerId);
To make sure that it is returning something?
As Chris Thompson points out, the issue is almost certainly that the layer is null. Check that your AXL file has the right layers and layerIds. (Sorry, I know ArcIMS, but I'm not familiar with the Geocortex framework.)
Also, you should add code to check if activeLayer is null and throw a different exception than NullPointerException, since that will make the error that much more obvious to the next programmer that comes along. Interesting that the streetFilter isn't applied if activeLayer is null, so somebody thought about this at some point.

Categories

Resources