In this code I want to search in an ArrayList but my code returns an incorrect result and I can not resolve this problem.
ReceivedItemStructure structure:
public class ReceivedItemStructure {
public String mLastID;
public String mUserID;
public String mSmsBody;
public String mMobileNumber;
public String mDate;
public String mSenderName;
public String mSmsNumber;
public String mContactName;
public String getmLastID() {
return mLastID;
}
}
My Code:
int countSMS = 0;
String smsReceivedSender = "";
String r = new JsonService(config_username, config_password, 0, 20, G.F_RECEIVE_SMS).request();
JSONArray data_array = new JSONArray(r);
for (int i = 0; i < data_array.length(); i++) {
JSONObject json_obj = data_array.getJSONObject(i);
String mId = json_obj.getString("id_recived_sms");
for (ReceivedItemStructure rf:items){
if( ! mId.equals(rf.getmLastID()) ) {
countSMS++;
}
}
}
My problem is this line :
if( ! mId.equals(rf.getmLastID()) ) {
if mId = 2000 and rf.getmLastID() = 1000 then count must be ++
Loop through your list and do a contains or startswith.
ArrayList<String> resList = new ArrayList<String>();
String searchString = "man";
for (String curVal : list){
if (curVal.contains(searchString)){
resList.add(curVal);
}
}
You can wrap that in a method. The contains checks if its in the list. You could also go for startswith.
Ok so to clarify please try to debug your code like this:
int countSMS = 0;
String TAG = "Debugger";
String smsReceivedSender = "";
String r = new JsonService(config_username, config_password, 0, 20, G.F_RECEIVE_SMS).request();
JSONArray data_array = new JSONArray(r);
Log.i(TAG, "items size is " + items.size());
for (int i = 0; i < data_array.length(); i++) {
JSONObject json_obj = data_array.getJSONObject(i);
String mId = json_obj.getString("id_recived_sms");
Log.i(TAG, "Trying to compare " + mId);
for (ReceivedItemStructure rf:items){
Log.i(TAG, "iteration step of " + rf.getmLastID);
if( ! mId.equals(rf.getmLastID()) ) {
countSMS++;
Log.i(TAG, "they are equal, count is " + countSMS);
}
}
}
Related
I am adding data into the list from model class object still it is showing list size is zero:
apiService.getOrdersDateWise(dateFrom,dateTo).enqueue(new Callback<List<OrdersDateWiseModel>>() {
#Override public void onResponse(Call<List<OrdersDateWiseModel>> call, Response<List<OrdersDateWiseModel>> response) {
List<OrdersDateWiseModel> ordsList = response.body();
int ordsListSize = ordsList.size();
Log.i(TAG, "OrdersListSize 250 : " + ordsListSize);
if (ordsList.size() != 0) {
if (fromDateMillisecs <= toDateMillisecs) {
for (int i = 0;i<ordsList.size();i++){
String ordDate = ordsList.get(i).getOrder_date();
String ordNo = ordsList.get(i).getOrder_number();
String ordValue = ordsList.get(i).getOrder_value();
String retaId = ordsList.get(i).getRetailer_id();
String shopName1 = ordsList.get(i).getShop_name();
String retName1 = ordsList.get(i).getRetailer_name();
String area1 = ordsList.get(i).getArea();
String phone1 = ordsList.get(i).getPhone();
getOrdersList.add(
new OrdersDateWiseModel(
ordDate,
ordNo,
ordValue,
retaId,
shopName1,
retName1,
area1,
phone1
));
}
ordersDateWiseAdapter.notifyDataSetChanged();
I expected output is the size of the list:
I/OrdersDateWiseActivity: OrdersListSize 250 : 0
I have an arraylist in which I have ESSID, BSSID, Strenght of access Point on first three indexes, and from Index 4 to 6 I have again ESSID, BSSID, Strength of another AccessPoint. I want to store this list in database like first three values save in one row of table. and next three values save in 2nd row of table.
String[] namesArr = new String[arrayList2.size()]; //conver arraylist to array
for (int j = 0; j < arrayList2.size(); j++){
namesArr[j] = arrayList2.get(j);
int length = namesArr[j].length();
for (int k = 0; k < length; k += 3) {
ssid = namesArr[k];
bssid = namesArr[k + 1];
rssid = namesArr[k + 2];
}
insertValues(this);
}
public void insertValues(View.OnClickListener view){
SendData send = new SendData(this);
send.execute(bssid,ssid,rssid);}
I have made a class to store this data in database that works fine.
public class SendData extends AsyncTask<String, Void, String> {
AlertDialog dialog;
Context context;
public SendData(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
dialog = new AlertDialog.Builder(context).create();
dialog.setTitle("Message");
}
#Override
protected void onPostExecute(String s) {
dialog.setMessage(s);
dialog.show();
}
#Override
protected String doInBackground(String... voids) {
String data = "";
String result = "";
String MAC = voids[0];
String Name = voids[1];
String Strength = voids[2];
String con_Str = "http://10.5.48.129/Webapi/accesspoints_data/create.php";
try{
URL url = new URL(con_Str);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
OutputStream out_Stream = http.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out_Stream, "UTF-8"));
JSONObject obj = new JSONObject();
try {
obj.put("BSSID", MAC);
obj.put("ESSID", Name);
obj.put("RSSID", Strength);
} catch (JSONException e) {
e.printStackTrace();
}
data = obj.toString();
writer.write(data);
writer.flush();
writer.close();
out_Stream.close();
InputStream in_Stream = http.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in_Stream, "ISO-8859-1"));
String line = "";
while ((line = reader.readLine()) != null)
{
result += line;
}
reader.close();
in_Stream.close();
http.disconnect();
return result;
} catch (MalformedURLException e){
result = e.getMessage();
} catch (IOException e){
result = e.getMessage();
}
return result;
}
}
SendData class is perfectly working but problem is with for loop.
I think this is result that you are expecting :
List<String> arrayList2 = new ArrayList<>();
arrayList2.add("1");
arrayList2.add("2");
arrayList2.add("3");
arrayList2.add("4");
arrayList2.add("5");
arrayList2.add("6");
arrayList2.add("6");
arrayList2.add("7");
arrayList2.add("8");
arrayList2.add("9");
arrayList2.add("10");
List<String[]> sarrayList = new ArrayList<>();
String[] arr = new String[3];
int i = 0;
for (int j = 0; j < arrayList2.size(); j++)
{
arr[i] = arrayList2.get(j);
i++;
if((j+1)%3==0)
{
sarrayList.add(arr);
i = 0;
arr = new String[3];
}
}
for(String [] sa:sarrayList)
{
for(String s:sa)
{
System.out.println(s);
}
System.out.println("=========");
}
This might not be the most efficient way of doing it. But it splits the ArrayList in to String arrays of length=3 and stores them in a new ArrayList named sarrayList
I would advise to use a datastructure to hold the record. See the code below this is a small example how you could do it
ArrayList<Record> records;
for (int i = 2; i < inputArrayList.size(); i = i + 3){
string ssid = namesArr.get(i - 2);
string bssid = namesArr.get(i - 1);
string rssid = namesArr.get(i);
records.add(new Record(ssid, bssid, rssid));
}
class Record{
string ssid;
string bssid;
string rssid;
// Constructor...
// Getter and setter to be implemented...
}
ok from what i understand you want to divide the arraylist each 3 elements thats how you do it with streams and it will return an a collection of arraylists each one has 3 elements
final int chunkSize = 3;
final AtomicInteger counter = new AtomicInteger();
//arrayList here us your array list
final Collection<List<String>> result = arrayList.stream()
.collect(Collectors.groupingBy(it -> counter.getAndIncrement() / chunkSize))
.values();
and mentioning supermar10 answer you code make a class to map the strings to it like that
class Record{
string ssid;
string bssid;
string rssid;
Record(String ssid,String bssid,String rssid){
this.ssid=ssid;
this.bssid=bssid;
this.rssid=rssid;
}
}
now you have a class to map to now save the records in a list of Record
create a a list in the main class
static List<Record> lists=new ArrayList<>();
then map the data like that
result.stream().forEach(nowList -> saveRecord(nowList));
and thats the save method
static void saveRecord(List<String> list){
lists.add(new Record(list.get(0),list.get(1),list.get(2)));
}
I have simplified it to one loop and also modified insertValues so that it takes 3 more parameters. This
int size = arrayList2.size();
for (int j = 0; j < size; j += 3) {
if (size - j < 3 ) {
break;
}
String ssid = arrayList2.get(j);
String bssid = arrayList2.get(j + 1);
String rssid = arrayList2.get(j + 2);
insertValues(this, ssid, bssid, rssid);
}
if one the other hand ssid and so on are class variables the inside of the loop can be changed to
ssid = arrayList2.get(j);
bssid = arrayList2.get(j + 1);
rssid = arrayList2.get(j + 2);
insertValues();
I have a file that contains more than one value in one column. I was trying to read this file using java with this code:
ArrayList<String> linesList1 = new ArrayList<>();
ArrayList<String> roadlinkid = new ArrayList<>();
ArrayList<String> road_name_orignal = new ArrayList<>();
ArrayList<String> road_name_copy = new ArrayList<>();
ArrayList<String[]> networkmember_href = new ArrayList<>();
ArrayList<String> road_fid = new ArrayList<>();
// Input of file which needs to be parsed
String csvFile1 = "RoadData.csv";
BufferedReader csvReader1;
// Data split by ',' in CSV file
String csvSplitBy = ",";
try {
String line;
csvReader1 = new BufferedReader(new FileReader(csvFile1));
while ((line = csvReader1.readLine()) !=null) {
linesList1.add(line);
}
csvReader1.close();
}
catch (IOException e) { e.printStackTrace(); }
for (int i = 0; i < linesList1.size(); i++) {
String[] data = linesList1.get(i).split(csvSplitBy);
road_fid.add( data[1]);
road_name_orignal.add( data[9]);
if (data[9].contains("{")) {
String[] xy = data[9].replaceAll("\\{|\\}", "").split(",");
int leng = xy.length;
String[] networkmember = new String [leng];
for ( int n = 0 ; n < leng ; n++) {
networkmember[n] = xy [n];
}
networkmember_href.add(networkmember);
}
}
This code works well, but the problem is that the code deals with each value in the column as a separate column. Therefore, it returns wrong data.
Files:
http://s000.tinyupload.com/?file_id=47090134488569683648
The idea is Finding the road name from RoadData.csv and write it in RoadLink.csv by comparing road_fid in RoadData.csv and roadlink_fid in RoadLink.csv. Unfortunately, I could find a way to deal with a column with multi-values. Any advice, please.
Thanks in advance.
Below is some code to parse the file, you can add additional processing to parse the fields that have lists in them or to combine the lists like changedate and reasonforchange into a list of Objects containing both pieces of data. For example a List<ChangeInfo> where ChangeInfo holds both the changedate and reasonforchange.
I still would recommend using a csv parser but this code should work well enough for this specific use case. Test thoroughly..
Main:
public static void main(String[] args){
List<RoadLinkRecord> records = parse("path\\to\\RoadLink.csv");
// display all the records
for (RoadLinkRecord record : records) {
System.out.println(record);
}
}
CSV Parsing:
private static final Pattern csvFieldPattern =
Pattern.compile("(?<=[$,])(\"(\"\"|[^\"])*\"|[^,]*)");
/** This parse method requires the CSV file to have a header row */
public static List<RoadLinkRecord> parse(String csvFilePath) {
// TODO accept Reader or maybe InputStream rather than file path
File f = new File(csvFilePath);
List<RoadLinkRecord> records = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(f));) {
// get the header fields
String line = br.readLine();
List<String> headers = new ArrayList<>();
{
Matcher matcher = csvFieldPattern.matcher(line);
while (matcher.find())
headers.add(matcher.group());
}
// iterate through record fields
int recordNum = 0;
while ((line = br.readLine()) != null) {
recordNum++;
// allocate array to hold the fields
String[] fields = new String[headers.size()];
// use matcher to get each of the fields
Matcher matcher = csvFieldPattern.matcher(line);
for (int i = 0; i < headers.size(); i++) {
if (!matcher.find()) {
throw new IllegalArgumentException(
"Couldn't find field '" + headers.get(i) + "' for record " + recordNum);
}
fields[i] = matcher.group();
}
if (matcher.find()) {
throw new IllegalArgumentException("Found excess fields in record " + recordNum);
}
// add the record from this line
records.add(new RoadLinkRecord(recordNum, fields));
}
} catch (IOException e) {
// TODO trouble reading the file
} catch (IllegalArgumentException e) {
// TODO error while parsing the file
}
return records;
}
Data Container:
public class RoadLinkRecord {
private final int recordNumber;
private final String roadlink_fid;
private final String version;
private final String versiondate;
private final String changedate;
private final String reasonforchange;
private final String descriptivegroup;
private final String descriptiveterm;
private final String natureofroad;
private final String length;
private final String directednode_href;
private final String directednode_orientation;
private final String directednode_gradeseparation;
private final String referencetotopographicarea_href;
private final String theme;
private final String filename;
private final String wkb_geometry;
private final String roadnumber;
private final String dftname;
private final String fid;
private final String roadname;
public RoadLinkRecord(final int recordNumber, final String[] csvFields) {
if (csvFields.length != 20) {
throw new IllegalArgumentException(
"Wrong number of fields for a RoadLinkRecord! Expected 20, found "
+ csvFields.length);
}
this.recordNumber = recordNumber;
this.roadlink_fid = processStringField(csvFields[0]);
this.version = processStringField(csvFields[1]);
this.versiondate = processStringField(csvFields[2]);
this.changedate = processStringField(csvFields[3]);
this.reasonforchange = processStringField(csvFields[4]);
this.descriptivegroup = processStringField(csvFields[5]);
this.descriptiveterm = processStringField(csvFields[6]);
this.natureofroad = processStringField(csvFields[7]);
this.length = processStringField(csvFields[8]);
this.directednode_href = processStringField(csvFields[9]);
this.directednode_orientation = processStringField(csvFields[10]);
this.directednode_gradeseparation = processStringField(csvFields[11]);
this.referencetotopographicarea_href = processStringField(csvFields[12]);
this.theme = processStringField(csvFields[13]);
this.filename = processStringField(csvFields[14]);
this.wkb_geometry = processStringField(csvFields[15]);
this.roadnumber = processStringField(csvFields[16]);
this.dftname = processStringField(csvFields[17]);
this.fid = processStringField(csvFields[18]);
this.roadname = processStringField(csvFields[19]);
}
private static String processStringField(String field) {
// consider empty fields as null
if (field.isEmpty()) {
return null;
}
// strip double quotes and replace any escaped quotes
final int endIndex = field.length() - 1;
if (field.charAt(0) == '"' && field.charAt(endIndex) == '"') {
return field.substring(1, endIndex).replace("\"\"", "\"");
}
return field;
}
public int getRecordNumber() { return recordNumber; }
public String getRoadlink_fid() { return roadlink_fid; }
public String getVersion() { return version; }
public String getVersiondate() { return versiondate; }
public String getChangedate() { return changedate; }
public String getReasonforchange() { return reasonforchange; }
public String getDescriptivegroup() { return descriptivegroup; }
public String getDescriptiveterm() { return descriptiveterm; }
public String getNatureofroad() { return natureofroad; }
public String getLength() { return length; }
public String getDirectednode_href() { return directednode_href; }
public String getDirectednode_orientation() { return directednode_orientation; }
public String getDirectednode_gradeseparation() { return directednode_gradeseparation; }
public String getReferencetotopographicarea_href() { return referencetotopographicarea_href; }
public String getTheme() { return theme; }
public String getFilename() { return filename; }
public String getWkb_geometry() { return wkb_geometry; }
public String getRoadnumber() { return roadnumber; }
public String getDftname() { return dftname; }
public String getFid() { return fid; }
public String getRoadname() { return roadname; }
#Override
public String toString() {
return "roadlink_fid= " + roadlink_fid + "; version= " + version + "; versiondate= "
+ versiondate + "; changedate= " + changedate + "; reasonforchange= "
+ reasonforchange + "; descriptivegroup= " + descriptivegroup + "; descriptiveterm= "
+ descriptiveterm + "; natureofroad= " + natureofroad + "; length= " + length
+ "; directednode_href= " + directednode_href + "; directednode_orientation= "
+ directednode_orientation + "; directednode_gradeseparation= "
+ directednode_gradeseparation + "; referencetotopographicarea_href= "
+ referencetotopographicarea_href + "; theme= " + theme + "; filename= " + filename
+ "; wkb_geometry= " + wkb_geometry + "; roadnumber= " + roadnumber + "; dftname= "
+ dftname + "; fid= " + fid + "; roadname= " + roadname + ";";
}
}
I have a sentence that contains message to be posted to the server like wow! superb pic #superb #pic #111 #222 enjoyed the pic
I want to extract the hastags and make them colored and leaving the rest of the text intact.
I tried the following code but not working.
private void spannableOperationOnHastag() {
mPostMessage = edPostMessage.getText().toString().trim();
String strPreHash = null;
String strHashText = "";
if (mPostMessage.contains("#")) {
try {
int index = mPostMessage.indexOf("#");
strPreHash = mPostMessage.substring(0, index);
SpannableString spannableString = new SpannableString(strPreHash);
String strHashDummy=mPostMessage.substring(index, mPostMessage.length());
int hashCount= StringUtils.countMatches(strHashDummy, "#"); // check for number of "#" occurrence and run forloop for getting the number of hastags in the string
int hasIndex=0;
for (int i = 0; i <hashCount ; i++) {
strHashText = strHashText+strHashDummy.substring(hasIndex, strHashDummy.indexOf(' '))+" ";
hasIndex =strHashText.indexOf(" "); // updating new space(" ") position in the index variable
}
SpannableString spannableStringBlue = new SpannableString(strHashText);
spannableStringBlue.setSpan(new ForegroundColorSpan(PublishPostActivity.this.getResources().getColor(R.color.blue)), 0, strHashText.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
edPostMessage.setText(null); // clearing old string
edPostMessage.append(spannableString); // setting extracted coloured text
edPostMessage.append(spannableStringBlue);
} catch (Exception e) {
Log.d(TAG, "validatePostMessage() called with " + "e = [" + e + "]");
}
}
}
I solved the problem my self . I any one needs it can refer this code :)
private void spannableOperationOnHastag() throws Exception{
mPostMessage = edPostMessage.getText().toString()+" "; // extra space for spannable operations
List<Integer> listStartPos = new ArrayList<>();
List<Integer> listEndtPos = new ArrayList<>();
if (mPostMessage.contains("#")){
for (int i = 0; i < mPostMessage.length(); i++) {
if (mPostMessage.charAt(i) == '#') {
listStartPos.add(i);
Log.d(TAG, "startIndex of # = " + i);
}
}
for (int i = 0; i < listStartPos.size(); i++) {
int endIndex = mPostMessage.indexOf(' ', listStartPos.get(i));
listEndtPos.add(endIndex);
Log.d(TAG, "endIndex of # " + (endIndex));
}
SpannableString spanned = SpannableString.valueOf(mPostMessage);
for (int i = 0; i < listStartPos.size(); i++) {
spanned = new SpannableString(spanned);
spanned.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.blue)), listStartPos.get(i), listEndtPos.get(i), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.d(TAG, "substring " + mPostMessage.substring(listStartPos.get(i), listEndtPos.get(i) + 1));
}
mPostMessage.trim(); // removing extra space.
edPostMessage.setText(null);
edPostMessage.setText(spanned);
}
}
I see you've just posted your own answer, but as I'd nearly finished typing this up I thought I'd go ahead and post this anyway :). I typed it just now without an IDE so it may not be perfect.
private static SpannableString convertTextColorsAtChar(char trigger, String inputText) {
SpannableString spannedText = new SpannableString(inputText);
if (!inputText.contains(trigger)) {
return spannedText;
}
ArrayList<int[]> indexArr = getIndexes(trigger, inputText.toCharArray());
for (int[] indexes : indexArr) {
spannedText.setSpan(new ForegroundColorSpan(Color.RED), indexes[0], indexes[1], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
returned spannedText;
}
private static ArrayList<int[]> getIndexes(char trigger, char[] inputText) {
ArrayList<int[]> values = new ArrayList<int[]>();
int firstIndex = -1;
int secondIndex; = -1
for (int i = 0; i < inputText.length; i++) {
if (firstIndex != -1 && inputText[i] == ' ') {
secondIndex = i;
values.add(new int[] { firstIndex, secondIndex });
firstIndex = secondIndex = -1;
}
if (trigger == inputText[i]) {
firstIndex = i;
}
}
return values;
}
You'd then call it with convertTextColorsAtChar('#', editText.getText().toString());
change your code as below
SpannableString spannableStringBlue = new SpannableString(strHashText);
spannableStringBlue.setSpan(new ForegroundColorSpan(new ForegroundColorSpan(Color.BLUE), 0, strHashText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
edPostMessage.setText(null); // clearing old string
edPostMessage.append(spannableString); // setting extracted coloured text
edPostMessage.append(spannableStringBlue);
SpannableStringBuilder builder = new SpannableStringBuilder();
String yourSentence = "Pic #superb #pic #111 #222 enjoyed the pic";
String [] newSent = yourSentence.split(" ");
for(int count = 0; count < newSent.length; count++){
if(newSent[count].contains("#")){
SpannableString redSpannable= new SpannableString(newSent[count]);
redSpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, newSent[count].length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.v("Test", "color_string" + newSent[count]);
builder.append(redSpannable+" ");
} else{
builder.append(newSent[count]+" ");
Log.v("Test", "normal_string" + newSent[count]);
}
}
holder.PhName.setText(builder, TextView.BufferType.SPANNABLE);
I have a JSP page that runs a database query and serializes the results to JSON. The object that I am serializing is this:
class DataObject {
private int iTotalRecords;
private int iTotalDisplayRecords;
private String sEcho;
private ArrayList<String> columns;
private ArrayList<ArrayList<String>> data;
//getter and setter methods
public void setColumns( ArrayList<String> cols ) {
columns = cols;
}
public void setTotalDisplayRecords( int _numrecs ) {
iTotalDisplayRecords = _numrecs;
}
public void setTotalRecords( int _numrecs ) {
iTotalRecords = _numrecs;
}
public void setData( ArrayList<ArrayList<String>> _data ) {
data = _data;
}
public void setEcho( String _echo ) {
sEcho = _echo;
}
#Override
public String toString() {
return "DataObject [iTotalRecords=" + iTotalRecords +
", iTotalDisplayRecords=" + iTotalDisplayRecords +
", sEcho=" + sEcho +
", columns=" + columns +
", data=" + data + "]";
}
public DataObject() {
this.sEcho = "1";
this.iTotalDisplayRecords = 0;
this.iTotalRecords = 0;
this.columns = new ArrayList<String>();
this.data = new ArrayList<ArrayList<String>>();
}
}
I have simplified the page, the JSP (which still produces blank JSON) is shown below:
String queryOvr = "select 'error' as Input_Parameters";
String sEcho = "0";
LOG.error("db_json_test.jsp - QUERY: " + queryOvr);
int rowCount=0;
int totalCount=0;
Statement stmt = null;
ResultSet returnData = null;
Connection conn = null;
try {
conn = DatabaseUtilities.getConnection(); //proprietary connection pool of host application
stmt = conn.createStatement();
returnData = stmt.executeQuery(queryOvr);
ResultSetMetaData rsmd = returnData.getMetaData();
DataObject dObj = new DataObject();
ArrayList<String> headerRow = new ArrayList<String>();
int colCount = rsmd.getColumnCount();
// write column names
for (int i=0; i<colCount; i++) {
String headerName = rsmd.getColumnName(i+1);
if ("".equals(headerName)) {
headerName = "Column-" + String.valueOf(i+1);
}
LOG.error("db_json_test.jsp - HEADER: " + headerName);
headerRow.add(headerName);
}
dObj.setColumns(headerRow);
// write data
ArrayList<ArrayList<String>> dataArray = new ArrayList<ArrayList<String>>();
while ( returnData.next() ) {
rowCount++;
ArrayList<String> dataRow = new ArrayList<String>();
for (int i=0; i<colCount; i++){
String dbData = returnData.getString(i+1);
LOG.error("db_json_test.jsp - DATA: row: " + headerRow.get(i) + ", value: " + dbData);
dataRow.add(dbData);
}
dataArray.add(dataRow);
totalCount++;
}
dObj.setData(dataArray);
dObj.setEcho(sEcho);
dObj.setTotalRecords(totalCount);
dObj.setTotalDisplayRecords(rowCount);
LOG.error("db_json_test.jsp - OBJ: " + dObj.toString());
Type typeResults = new TypeToken<DataObject>(){}.getType();
Gson gson = new Gson();
String json = gson.toJson(dObj, typeResults);
LOG.error("db_json_test.jsp - JSON: " + json);
//gson.toJson(dObj, typeResults, response.getWriter());
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().write(json);
response.getWriter().flush();
response.getWriter().close();
}
catch (Throwable t) {
LOG.error("db_json.jsp - Error: " + t.toString());
//t.printStackTrace();
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().write("{\"error\":\"" + t.toString() + "\"}");
response.getWriter().flush();
response.getWriter().close();
}
When I look in the logs I can see that the DataObject instance is getting properly populated:
783167943 30 Sep 2015 17:37:51,924 ERROR [http-8500-1] JSP - db_json_test.jsp - QUERY: select 'error' as Input_Parameters
783167959 30 Sep 2015 17:37:51,940 ERROR [http-8500-1] JSP - db_json_test.jsp - HEADER: Input_Parameters
783167959 30 Sep 2015 17:37:51,940 ERROR [http-8500-1] JSP - db_json_test.jsp - DATA: row: Input_Parameters, value: error
783167959 30 Sep 2015 17:37:51,940 ERROR [http-8500-1] JSP - db_json_test.jsp - OBJ: DataObject [iTotalRecords=1, iTotalDisplayRecords=1, sEcho=0, columns=[Input_Parameters], data=[[error]]]
783167959 30 Sep 2015 17:37:51,940 ERROR [http-8500-1] JSP - db_json_test.jsp - JSON:
However when I go to serialize it using gson.toJson(dObj) I get a blank string. I have tried specifying the type as shown in the example above to no different results. Outside of the argument that I probably shouldn't be doing this in a JSP file, what am I missing here?
Worth noting is that the catch routine does return the error message as valid JSON, so the contentType and charset are getting properly set in the headers.
The following Java code DOES produce the expected JSON...
public class gsonTest {
class DataObject {
private int iTotalRecords;
private int iTotalDisplayRecords;
private String sEcho;
private ArrayList<String> columns;
private ArrayList<ArrayList<String>> data;
// getter and setter methods
public void setColumns(ArrayList<String> cols) {
columns = cols;
}
public void setTotalDisplayRecords(int _numrecs) {
iTotalDisplayRecords = _numrecs;
}
public void setTotalRecords(int _numrecs) {
iTotalRecords = _numrecs;
}
public void setData(ArrayList<ArrayList<String>> _data) {
data = _data;
}
public void setEcho(String _echo) {
sEcho = _echo;
}
#Override
public String toString() {
return "DataObject [iTotalRecords=" + iTotalRecords
+ ", iTotalDisplayRecords=" + iTotalDisplayRecords
+ ", sEcho=" + sEcho
+ ", columns=" + columns
+ ", data=" + data + "]";
}
public DataObject() {
this.sEcho = "";
this.iTotalDisplayRecords = 0;
this.iTotalRecords = 0;
this.columns = new ArrayList<String>();
this.data = new ArrayList<ArrayList<String>>();
}
}
public static void main(String[] args) {
int totalCount = 0;
String sEcho = "1";
Gson gson = new Gson();
gsonTest tst = new gsonTest();
Type typeResults = new TypeToken<DataObject>(){}.getType();
DataObject obj = tst.new DataObject();
ArrayList<String> headerRow = new ArrayList<String>();
// write column names
int colCount = 2;
for (int i = 0; i < colCount; i++) {
headerRow.add("Column-" + String.valueOf(i));
}
obj.setColumns(headerRow);
// write data
ArrayList<ArrayList<String>> dataArray = new ArrayList<ArrayList<String>>();
int rowCount = 0;
while (rowCount < 20) {
ArrayList<String> dataRow = new ArrayList<String>();
for (int i = 0; i < colCount; i++) {
dataRow.add("Row-" + String.valueOf(rowCount) + ":Col-"
+ String.valueOf(i));
}
rowCount++;
dataArray.add(dataRow);
totalCount++;
}
obj.setData(dataArray);
obj.setEcho(sEcho);
obj.setTotalRecords(totalCount);
obj.setTotalDisplayRecords(rowCount);
String output = gson.toJson(obj,typeResults);
System.out.println(obj.toString());
System.out.println(output);
}
}
Here is the output:
DataObject [iTotalRecords=20, iTotalDisplayRecords=20, sEcho=1,
columns=[Column-0, Column-1], data=[[Row-0:Col-0, Row-0:Col-1],
[Row-1:Col-0, Row-1:Col-1], [Row-2:Col-0, Row-2:Col-1], [Row-3:Col-0,
Row-3:Col-1], [Row-4:Col-0, Row-4:Col-1], [Row-5:Col-0, Row-5:Col-1],
[Row-6:Col-0, Row-6:Col-1], [Row-7:Col-0, Row-7:Col-1], [Row-8:Col-0,
Row-8:Col-1], [Row-9:Col-0, Row-9:Col-1], [Row-10:Col-0,
Row-10:Col-1], [Row-11:Col-0, Row-11:Col-1], [Row-12:Col-0,
Row-12:Col-1], [Row-13:Col-0, Row-13:Col-1], [Row-14:Col-0,
Row-14:Col-1], [Row-15:Col-0, Row-15:Col-1], [Row-16:Col-0,
Row-16:Col-1], [Row-17:Col-0, Row-17:Col-1], [Row-18:Col-0,
Row-18:Col-1], [Row-19:Col-0, Row-19:Col-1]]]
{"iTotalRecords":20,"iTotalDisplayRecords":20,"sEcho":"1","columns":["Column-0","Column-1"],"data":[["Row-0:Col-0","Row-0:Col-1"],["Row-1:Col-0","Row-1:Col-1"],["Row-2:Col-0","Row-2:Col-1"],["Row-3:Col-0","Row-3:Col-1"],["Row-4:Col-0","Row-4:Col-1"],["Row-5:Col-0","Row-5:Col-1"],["Row-6:Col-0","Row-6:Col-1"],["Row-7:Col-0","Row-7:Col-1"],["Row-8:Col-0","Row-8:Col-1"],["Row-9:Col-0","Row-9:Col-1"],["Row-10:Col-0","Row-10:Col-1"],["Row-11:Col-0","Row-11:Col-1"],["Row-12:Col-0","Row-12:Col-1"],["Row-13:Col-0","Row-13:Col-1"],["Row-14:Col-0","Row-14:Col-1"],["Row-15:Col-0","Row-15:Col-1"],["Row-16:Col-0","Row-16:Col-1"],["Row-17:Col-0","Row-17:Col-1"],["Row-18:Col-0","Row-18:Col-1"],["Row-19:Col-0","Row-19:Col-1"]]}
After digging further I came to a workable solution. By combining the test Java class into the JSP as follows I got the correct output. I am unsure why this worked and the original did not
<%# page
language="java"
session="true"
contentType="application/json; charset=UTF-8"
%>
<%# page import="com.google.gson.Gson,
java.lang.reflect.Type,
com.google.gson.reflect.TypeToken,
java.util.ArrayList,
java.sql.*,
org.apache.log4j.Category,
com.foo.bar.*;"
%>
<%
final org.apache.log4j.Category LOG = org.apache.log4j.Category.getInstance ("JSP");
class db_json {
class DataObject {
private int iTotalRecords;
private int iTotalDisplayRecords;
private String sEcho;
private ArrayList<String> columns;
private ArrayList<ArrayList<String>> data;
// getter and setter methods
public void setColumns(ArrayList<String> cols) {
columns = cols;
}
public void setTotalDisplayRecords(int _numrecs) {
iTotalDisplayRecords = _numrecs;
}
public void setTotalRecords(int _numrecs) {
iTotalRecords = _numrecs;
}
public void setData(ArrayList<ArrayList<String>> _data) {
data = _data;
}
public void setEcho(String _echo) {
sEcho = _echo;
}
#Override
public String toString() {
return "DataObject [iTotalRecords=" + iTotalRecords
+ ", iTotalDisplayRecords=" + iTotalDisplayRecords
+ ", sEcho=" + sEcho
+ ", columns=" + columns
+ ", data=" + data + "]";
}
public DataObject() {
this.sEcho = "";
this.iTotalDisplayRecords = 0;
this.iTotalRecords = 0;
this.columns = new ArrayList<String>();
this.data = new ArrayList<ArrayList<String>>();
}
}
public String testJson(HttpServletRequest request){
String queryOvr = "select 'error' as Input_Parameters";
LOG.debug("db_json3.jsp - QUERY: " + queryOvr);
Gson gson = new Gson();
int rowCount=0;
int totalCount=0;
Statement stmt = null;
ResultSet returnData = null;
Connection conn = null;
try {
conn = DatabaseUtilities.getConnection();
stmt = conn.createStatement();
returnData = stmt.executeQuery(queryOvr);
ResultSetMetaData rsmd = returnData.getMetaData();
DataObject dObj = new DataObject();
ArrayList<String> headerRow = new ArrayList<String>();
int colCount = rsmd.getColumnCount();
// write column names
for (int i=0; i<colCount; i++) {
String headerName = rsmd.getColumnName(i+1);
if ("".equals(headerName)) {
headerName = "Column-" + String.valueOf(i+1);
}
LOG.debug("db_json3.jsp - HEADER: " + headerName);
headerRow.add(headerName);
}
dObj.setColumns(headerRow);
// write data
ArrayList<ArrayList<String>> dataArray = new ArrayList<ArrayList<String>>();
while ( returnData.next() ) {
if ( rowCount>=iDisplayStart && iDisplayLength>=0 && rowCount<iDisplayLength ) {
rowCount++;
ArrayList<String> dataRow = new ArrayList<String>();
for (int i=0; i<colCount; i++){
String dbData = returnData.getString(i+1);
LOG.debug("db_json3.jsp - DATA: row: " + headerRow.get(i) + ", value: " + dbData);
dataRow.add(dbData);
}
dataArray.add(dataRow);
}
totalCount++;
}
dObj.setData(dataArray);
dObj.setEcho(sEcho);
dObj.setTotalRecords(totalCount);
dObj.setTotalDisplayRecords(rowCount);
LOG.debug("db_json3.jsp - OBJ: " + dObj.toString());
Type typeResults = new TypeToken<DataObject>(){}.getType();
String json = gson.toJson(dObj, typeResults);
LOG.debug("db_json3.jsp - JSON: " + json);
return json;
}
catch (Throwable t) {
LOG.debug("db_json3.jsp - Error: " + t.toString());
return gson.toJson(t);
}
}
}
db_json dbjson = new db_json();
String json = dbjson.testJson();
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().write(json);
response.getWriter().flush();
response.getWriter().close();
%>