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.
Related
I am working on a project where the client's requirement is to add a dynamic text box. I made the dynamic text box but I'm not getting the unique name of the text box.
Here is my code:
<script type="text/javascript">
function addfieldset() {
var namefieldset = document.getElementById("name").cloneNode(true);
document.getElementById("names").appendChild(namefieldset);
}
function deletefieldset(e) {
var namefieldset = e.parentNode;
namefieldset.parentNode.removeChild(namefieldset);
}
</script>
<body>
<%! public static int i = 1;%>
<% if (i > 0) { %>
<div id="names"><div id="name"><% out.print(i);%>Name: <input name="namefield<%= i%>" type="text"/>delete</div></div>
<input id="addnamebtn" type="button" value="Add Name" onclick="addfieldset()"/>
<% i++;
}%>
</body>
You are mixing two different codes. The key is to realize, where and when each code is executed - JSP on the server when the page is requested and rendered (i.e. before the response is sent to the browser) and Javascript in the browser, after the browser receives the already generated response.
I.e. you have to change the name of the new text field in the addfieldset() function (which means you have to have a counter, how many text fields there already is).
The java code in scriptlet is executed on the server side. Hence, cloning it again through Javascript will not execute the scriptlet again.
An another approach of what you are trying to achieve will be to store the count variable in javascript.
var count = 1;
function addfieldset() {
count++;
var namefieldset = document.getElementById("name").cloneNode(true);
var textField = namefieldset.getElementsByTagName('input')[0];
textField.setAttribute("name", "namefield" + count);
textField.value = "";
document.getElementById("names").appendChild(namefieldset);
}
function deletefieldset(e) {
var namefieldset = e.parentNode;
namefieldset.parentNode.removeChild(namefieldset);
}
<body>
<div id="names">
<div id="name">
<span>Name:</span>
<input name="namefield1" type="text" />
delete
</div>
</div>
<input id="addnamebtn" type="button" value="Add Name" onclick="addfieldset()" />
</body>
try this JavaScript and HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<script type="text/javascript">
var i = 0;
function generateRow() {
i++;
var d = document.getElementById("div");
d.name = "food";
d.innerHTML += "<p>name"+i+" :<input type='text' name='name" + i + "' /> <a href='#' onclick='deletefieldset(this)'>delete</a></p>";
}
function deletefieldset(e) {
var namefieldset = e.parentNode;
namefieldset.parentNode.removeChild(namefieldset);
}
function onLoad() {
generateRow();
}
window.onload = onLoad;
</script>
<body>
<div id="div"></div>
<p>
<input type="button" id="addnamebtn" value="Add Name" onclick="generateRow()" />
</p>
</body>
</html>
I am having a problem catching or detecting a new line(\n) insert from my server side(java servlet) in my angular ng-repeat.
server side:
StringBuilder name = new StringBuilder();
name.append(getFirst(id)); //id - #param
name.append("\n"); //new line
name.append(getLast(id)); //id - #param
But on my client side, in my ng-repeat:
{{reporter.name}} //jhon doe
instead of:
jhon
doe
if there is more code needed I will post it.
You can use the css style for your requirement:
white-space: pre|pre-line|pre-wrap;
pre - Whitespace is preserved by the browser. Text will only wrap on line breaks. Acts like the <pre> tag in HTML
pre-line - Sequences of whitespace will collapse into a single whitespace. Text will wrap when necessary, and on line breaks
pre-wrap Whitespace is preserved by the browser. Text will wrap when necessary, and on line breaks
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example111-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-sanitize.js"></script>
<style>
table {
border-collapse: collapse;
}
table, td, th {
border: 1px solid black;
}
</style>
</head>
<body ng-app="sanitizeExample">
<script>
angular.module('sanitizeExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.friends = [
{name:'John\nDoe', age:25, gender:'boy'},
{name:'Jessie\nSimpson', age:30, gender:'girl'},
{name:'Johanna\nLN', age:28, gender:'girl'},
{name:'Joy\nLN', age:15, gender:'girl'},
{name:'Mary\nLN', age:28, gender:'girl'},
{name:'Peter\nLN', age:95, gender:'boy'},
{name:'Sebastian\nLN', age:50, gender:'boy'},
{name:'Erika\nLN', age:27, gender:'girl'},
{name:'Patrick\nLN', age:40, gender:'boy'},
{name:'Samantha\nLN', age:60, gender:'girl'}
];
}]);
</script>
<div ng-controller="ExampleController">
<table
class="table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="friend in friends">
<td style="white-space: pre;">{{friend.name}}</td>
<td>{{friend.age}}</td>
<td>{{friend.gender}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Replace all \n with < br>, do something like this
str = str.replace(/(?:\r\n|\r|\n)/g, '<br />');
Wrap it in <pre> tag
<pre>{{reporter.name}}</pre>
I am creating small web apps and I am facing the following problem. I have 2 JSPs and when I click the submit button, it repeats the value every time. What I want is that when I click on the submit button it should give only the corresponding value.
index.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#page import="java.io.*,java.util.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Class Video</title>
</head>
<body>
<form action="second.jsp" method="post">
<table>
<%
File f=new File("C:/Users/SHAKTI/Desktop/video");
File[] list=f.listFiles();
if(list.length!=0){
String s[]=new String[list.length];
for(int i=0;i<list.length;i++){
s[i]=list[i].toString();
String fi=list[i].getName();
%>
<tr><td><%=fi %></td>
<td><input type="text" name="file" value="<%=s[i] %>">
</td>
<td><input type="submit" name="play" value="Play"></td>
</tr>
<%}}
else{
%>
<tr>
<td>There is no any files in the database...</td>
</tr>
<%
}
%>
</table>
</form>
</body>
</html>
second.jsp
<form action="" method="post">
<%
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
response.setDateHeader ("Expires", 0);
String id=request.getParameter("file");
out.println("id = "+id);
%>
<input type="submit" name="submit" value="submit>
</form>
First Jsp : Set Value in First Page
request.setAttribute("name",somevalue);
Second Jsp : Retrieve it in Second page
request.getAttribute("name")
use queryString
URl: http://myaddress.com/xyz?name=jill&sex=f
String someName = request.getParameter("name") ;
String sex = request.getParameter("sex") ;
One way is to use session as described by javaBeginner.
you can also create a from on the fly and submit it.
write a function similar to this one and use it in your success:
function submitValues(url, params) {
var form = [ '<form method="POST" action="', url, '">' ];
for(var key in params)
form.push('<input type="hidden" name="', key, '" value="', params[key], '"/>');
form.push('</form>');
jQuery(form.join('')).appendTo('body')[0].submit();
}
There are many options to pass a value from one jsp to another, Here are some
1) Adding that as a hidden variable and specifying the value
<input name="file" type="hidden" value=""/>
2)Adding it to the session and retrieving the session variable
session.setAttribute("file", value);
3)Passing that as a queryParameter
http://......one.jsp?file=""
It is beacause you are iterating the loop here,
for(int i=0;i<list.length;i++){
s[i]=list[i].toString();
String fi=list[i].getName();
so it will print the last element from the loop, to get the name u clicked on the button try this .. Change this line as
<input type="text" name="file" value="<%=s[i] %>">
as,
<td><input type="button" class="btn" data-reqno=value="<%=s[i] %>" value="file name">
And handle it using jQuery like this , so that you can pass the value to next JSP,
<script type="text/javascript">
$(document).ready(function () {
$(".btn").click(
function() {
var selectedFileName = $(this).attr("data-reqno");
var urlToApprove = "/yourApp/req/filename?name=" + selectedFileName;
}
);
});
</script>
And also try to avoid Scriptlets in JSP , you can use JSTL or El for the same purpose .
Hope it helps !!
there are many method to pass variable such as
session.setAttribute()
session.getAttribute
action "xxx.jsp?variable=1"
that's going to be a long question so bear with me :)
My Application
I'm developing a Java (with JFrame GUI) desktop application that does the following:
Scan (.txt) files.
Parses some numbers from these
files, performs some calculations on
them and finally stores the results
in String variables.
Outputs these numbers in a special
(table) format. (Note: the format
includes some Unicode (Arabic)
Characters.)
Problem
The first two parts went smoothly. However when I came to the 3th part (the formatted output) I didn't know how to display this special format so,
What is the best way to display a special formatted output (table) in Java?
Note: Formatter is not going to help because it has no proper support for tables.
Solution One:
I did my research and found that I could use JEditorPane, since it can display special formats such as "html". So I decided to create an "html" page with the needed (table) format and then display this page on [JEditorPane][4]. I did that and it went smoothly until I wanted to change some html elements' values to the parsed numbers from those (.txt) files.
How can I have an access to an html
element(e.g. <td></td>) and change
its value?
Note that the (.html) is loaded inside JEditorPane using setPage(url).
The Unicode characters are displayed properly but I couldn't change some of the elements values (e.g. I want to change the value of <td> 000,000,000 </td> to <td> MainController.getCurrentTotalPayment() </td>
Solution Two:
I've found a workaround to this which involves using HTMLDocument and HTMLEditorKit, That way I can create the (.html) using HTMLEditorKit from scratch and display it on the JEditorPane using kit.insertHTML.
I have successfully added the content using the above method and I also was able to add the parsed numbers from (.txt) files because I have them stored in my (MainController) class. Unfortunately, the Unicode Arabic characters were not displayed properly.
How can I display these Unicode
characters properly?
So the first solution lacks the access to html elements and the second lacks the Unicode support!
My colleagues advised me to use JSP code in the html document that can have an access to my MainController.java class. Therefore, loading the page into JEditorPane with the html elements changed already. Isn't there a way to do that without the help of JSP?
Some other people recommended the use of JTidy but isn't there a way to do it within Java's JDK?
I'm open to all possible solutions. Please help.
My Code: Some code content were omitted because they are not relevant
MainController.java
class MainController
{
private static String currentTotalPayment;
public static void main(String[] args)
{
CheckBankFilesView cbfView = new CheckBankFilesView();
cbfView.setVisible(true);
}
public static void setCurrentTotalPayment(String totalPayment) {
MainController.currentTotalPayment = totalPayment;
}
public static String getCurrentTotalPayment() {
return currentTotalPayment;
}
}
MyFormattedOuputSolutionOne.java:
public class MyFormattedOuputSolutionOne extends javax.swing.JFrame {
private void MyFormattedOuputSolutionOne() {
jPanel1 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
myFormattedOuput = new javax.swing.JEditorPane();
myFormattedOuput.setContentType("text/html");
//myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work
myFormattedOuput.setEditable(false);
jScrollPane1.setViewportView(myFormattedOuput);
myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
try{
myFormattedOuput.setPage(getClass().getResource("resources/emailFormat2.html"));
//How can I edit/change html elements loaded in 'myFormattedOuput'?
}catch(Exception e){
}
}
}
MyFormattedOuputSolutionTwo.java:
public class MyFormattedOuputSolutionTwo extends javax.swing.JFrame {
private void MyFormattedOuputSolutionTwo() {
jPanel1 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
myFormattedOuput = new javax.swing.JEditorPane();
myFormattedOuput.setContentType("text/html");
//myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work
myFormattedOuput.setEditable(false);
jScrollPane1.setViewportView(myFormattedOuput);
HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument doc = new HTMLDocument();
myFormattedOuput.setEditorKit(kit);
myFormattedOuput.setDocument(doc);
myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
try{
// Tried to set the charset in <head> but it doesn't work!
//kit.insertHTML(doc, 1, "<meta http-equiv = \"Content-Type\" content = \"text/html; charset=UTF-8\">", 0, 0, HTML.Tag.META);
kit.insertHTML(doc, doc.getLength(), "<label> السلام عليكم ورحمة الله وبركاته ,,, </label>", 0, 0, null); //Encoding problem
kit.insertHTML(doc, doc.getLength(), "<br/>", 0, 0, null); // works fine
kit.insertHTML(doc, doc.getLength(), MainController.getCurrentTotalPayment(), 0, 0, null); // works fine
//How can I solve the Unicode problem above?
}catch(Exception e){
}
}
}
htmlFormatTable.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8">
</head>
<body>
<label> السلام عليكم ورحمة الله وبركاته ,,, </label>
<br/>
<label> الأخوة الكرام نفيدكم بتفاصيل المدفوعات لشهر </label> XX/143X </label> هـ كما هو موضح ادناه </label>
<br/>
<table align="right" border="1" width="600" cellpadding="5" cellspacing="0">
<tr char="utf-8" bgcolor="cccccc" align="center">
<td colspan="3"> <label> تفاصيل مدفوعات بنك الرياض </label> <img src="..\images\riyadh.gif" width="65" height="15"/> </td>
</tr>
<tr align="center">
<td></td>
<td id="cell1">0,000,000.00</td>
<td align="right"> معاشات </td>
</tr>
<tr align="center">
<td></td>
<td id="cell2">0,000,000.00</td>
<td align="right"> أخطار </td>
</tr>
<tr align="center">
<td bgcolor="cccccc"> المجموع </td>
<td bgcolor="cccccc"> 0,000,000.00 <label> ريال سعودي </label> </td>
<td></td>
</tr>
</table>
<br/>
<label> شاكرين لكم حسن تعاونكم ...... </label>
<br/>
<label> فريق العمليات بقسم الحاسب الآلي </label>
</body>
</html>
Thank you for reading my long multiple questions thread and cannot wait for your answer.
Update:
Thanks to #Howard for this insight, if I replace the arabic character with its corresponding unicode (e.g. ب = \u0628) it works fine but there must be a way to do it without the need to replace each character, right?
Solution One
It is possible to edit HTML loaded into JEditorPane. Here's the complete code based on your MyFormattedOuputSolutionOne.java:
import java.awt.ComponentOrientation;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JEditorPane;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
public class MyFormattedOuputSolutionOne extends javax.swing.JFrame {
private MyFormattedOuputSolutionOne() {
super("MyFormattedOuputSolutionOne");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
final JEditorPane myFormattedOuput = new javax.swing.JEditorPane();
getContentPane().add(jScrollPane1);
myFormattedOuput.setContentType("text/html");
//myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work
myFormattedOuput.setEditable(false);
jScrollPane1.setViewportView(myFormattedOuput);
myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
try{
myFormattedOuput.setPage(getClass().getResource("htmlFormatTable.html"));
myFormattedOuput.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("page".equals(evt.getPropertyName())) {
Document doc = myFormattedOuput.getDocument();
Element html = doc.getRootElements()[0];
Element body = html.getElement(1);
Element table = body.getElement(1);
try {
Element tr2 = table.getElement(1);
Element tr2td1 = tr2.getElement(0);
doc.insertString(tr2td1.getStartOffset(), "1: 123,456",
SimpleAttributeSet.EMPTY);
Element tr3 = table.getElement(2);
Element tr3td1 = tr3.getElement(0);
doc.insertString(tr3td1.getStartOffset(), "2: 765.123",
SimpleAttributeSet.EMPTY);
} catch (BadLocationException e) {
e.printStackTrace();
}
myFormattedOuput.removePropertyChangeListener(this);
}
}
});
//How can I edit/change html elements loaded in 'myFormattedOuput'?
} catch(Exception e){
e.printStackTrace();
}
pack();
setSize(700, 400);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MyFormattedOuputSolutionOne();
}
});
}
}
It loads document asynchronously and waits for page to be loaded. When page is loaded, it accesses the elements of the document to search for elements and inserts text into the first <td> in the 2nd and 3rd row of the table.
By the way your HTML is not valid! You should clean it up. When you do it, the indexes of the document elements will change and you'll have to adjust code which finds the insertion points.
The window looks this way:
Solution Two
I've found no issues with encoding. The characters display correctly. Yet I had to set the encoding of Java files to UTF-8 in the Eclipse project.
Solution Three
Have you considered using JTable to display table of results in the UI?
The HTML might look this way:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8">
</head>
<body>
<p> السلام عليكم ورحمة الله وبركاته ,,, </p>
<p> الأخوة الكرام نفيدكم بتفاصيل المدفوعات لشهر </p>
<p>XX/143X </p>
<p> هـ كما هو موضح ادناه </p>
<table align="right" border="1" width="600" cellpadding="5" cellspacing="0">
<tr bgcolor="cccccc" align="center">
<td colspan="3">تفاصيل مدفوعات بنك الرياض <img src="..\images\riyadh.gif" width="65" height="15"/></td>
</tr>
<tr align="center">
<td></td>
<td id="cell1">0,000,000.00</td>
<td align="right">معاشات</td>
</tr>
<tr align="center">
<td></td>
<td id="cell2">0,000,000.00</td>
<td align="right">أخطار</td>
</tr>
<tr align="center">
<td bgcolor="cccccc">المجموع</td>
<td bgcolor="cccccc">0,000,000.00 ريال سعودي</td>
<td></td>
</tr>
</table>
<p> شاكرين لكم حسن تعاونكم ...... </p>
<p> فريق العمليات بقسم الحاسب الآلي </p>
</body>
</html>
Since I don't understand a word, I cannot propose a better formatting. First of all, <label> elements are allowed only in <form>. You had a sequence of three <label>s above the table where only one of them had opening <label> tag, there were three closing </label> tags. I made them all into <p>; however if you meant them to be headers for table columns, you should have used a table row with three <th> elements.
With this structure of the HTML, <table> element in the HTML tree would be at index 4, i.e. you should change the line
Element table = body.getElement(1);
to
Element table = body.getElement(4);
The indexes 0–3 are now <p> elements.
As a side note, instead of editing HTML after loading it into JEditorPane, which loads it into text model of HTMLDocument, you could edit your HTML document before passing to setPage so that it already contains the correct data in <td> elements. Since JEditorPane.setPage method accepts only URL, then your choice would be read which accepts an InputStream and Object which describes the model (should be instance of HTMLDocument in your case). StringBufferInputStream is the best candidate for this task yet it was deprecated because it cannot correctly read UTF-8 characters. Having this in mind, you would rather use String.getBytes("UTF-8") function (since J2SE 6), and ByteArrayInputStream, your HTML declares the encoding and JEditorPane would respect it when reading.
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.