Unexpected token B in JSON result from Java web service - java

I created a web service that returns a JSON formatted string in output but I have an error with the JSON parsing:
Unexpected token B in JSON at position 46
I tried to debug the program but I didn't find the error.
Here's the method that returns the JSON:
public String executeQueryTOJSON(String sql) // metodo utilizzato per eseguire i servizi di GET
{
String error = "";
StringBuilder json = new StringBuilder("[ ");
if (_Connected) // controllo l'avvenuta connessione
{
try {
stmt = _conn.createStatement();
ResultSet rs = stmt.executeQuery(sql); // executeQuery è un comando che permette di eseguire le query di
// selezione e restituisce le righe del risultato della query
// System.out.println("query fatta");
// a= rs.getString("accountname");
java.sql.ResultSetMetaData rsmd = rs.getMetaData(); // oggetto rsmd con il comando getMetaData() viene
// utilizzato per scoprire le colonne dell'oggetto
// rs
int cols = rsmd.getColumnCount(); // il comando getColumnCount() serve per calcolare il numero di
// colonne dell'oggetto rsmd
int count = 0; // variabile di appoggio per controllare se si trasferisce un valore nullo
while (rs.next()) { // ciclo che si ripette in base alle righe di rs{
// String foundType = rs.getString(1);
// System.out.println(foundType);
count++;
json.append("{ ");
// errore precedente -> "< cols" non faceva il giusto ciclo di parsing
for (int i = 1; i <= cols; i++) // ciclo che si ripete per il numero oggetti situati nella tabella
{
boolean check = false;
json.append("\"" + rs.getMetaData().getColumnLabel(i) + "\":");
switch (rsmd.getColumnType(i)) // switch per il controllo del valore da andar a prendere
{
case java.sql.Types.VARCHAR: {
String tmp = rs.getString(i);
// System.out.println(tmp);
if (tmp == null)// confronto per vedere se il valore è uguale a null
{
json.append("null");
} else
// modifica effettuata con .replace per sostiruire i caratteri errati
json.append("\"" + rs.getString(i).replace("\"", "'") + "\"");// replace usata per fare
// il giusto parsing
}
break;
case java.sql.Types.CHAR: {
// System.out.println(json.toString());
String tmp = rs.getString(i);
if (tmp == null)// confronto per vedere se il valore è uguale a null
{
json.append("null");
} else
json.append("\"" + rs.getString(i).replace("\"", "'") + "\"");
}
break;
case java.sql.Types.NULL: {
json.append("null");
}
break;
case java.sql.Types.DATE: {
try {
rs.getDate(i);
// json.append("\"" + rs.getDate(i) + "\"");
// check = true;
} catch (SQLException e) {
} finally {
json.append("\"\"");
}
}
break;
case java.sql.Types.INTEGER: {
json.append(rs.getInt(i));
check = true;
}
break;
default: {
if (check == false)
json.append(rs.getObject(i).toString());
// System.out.println(json);
}
break;
}
json.append(" , ");
}
json.setCharAt(json.length() - 2, '}');
json.append(" , ");
if (count == 0) {
json.append("\"risultato\":\"errore valore nullo\" } ");
}
}
json.setCharAt(json.length() - 2, ']');
rs.close();
stmt.close();
_conn.close();// chiusura connessione con database
} catch (SQLException e) {
e.printStackTrace();
return error = ("{ \"risultato\":\"errore query\" } ]");
}
// System.out.println(json.toString());
return json.toString(); // output della Stringa JSON
} else {
return error = ("{ \"risultato\":\"errore connessione\" } ]");
}
}
The JSON output looks like this:
[
{
"account_no": 77,
"data": "",
"quote_no": [B#7a9e5ed5,
"codpag": " 56",
"pag": "( 56) BONIFICO BANCARIO 120 GG DF",
"codage": " 150",
"agente": "( 150) 150 STRUTTURA PROVA"
}
]
But it should return this:
[
{
"account_no": 77,
"data": "",
"quote_no": "PREV1400001",
"codpag": " 56",
"pag": "( 56) BONIFICO BANCARIO 120 GG DF",
"codage": " 150",
"agente": "( 150) 150 STRUTTURA PROVA"
}
]

i think in this section:
default:
(check == false)
json.append(rs.getObject(i).toString());
//System.out.println(json);
}
you are trying to turn object in string. unless you override the toString method to print values , it will always print [B#7a9e5ed5 . this code is the string value of object.
you cannot turn object into string directly.

You see, B#7a9e5ed5 is the address of the value which you want to show.
json.append(rs.getObject(i).toString()); In this line, the to string method must be overriden for your type of object.
For example, If I have an object student of Class Student and if I have not overridden the toString() method. If I use student.toString(); It would print the address value where the object student is saved in the memory.
If for example I wanted to see the values of the student, I would have to override toString method in the class.
#Override
public String toString(){
return this.getName() + " " + this.getClass();
}
The above is just an example, in your code, you need to know which type of object you are getting from the result set, and you need to override the method of toString in that class.
Hope this makes sense.

check flag is true only for integer .
For other type in the default block , you are directly converting object to String for non-character values you would need to override the toString method to have a accurate conversion .Make sure you override toString or provide String.valueOf with appropriate exception catching mechanisms

Related

Method does not exist or incorrect signature: void newInstance(System.Location, System.Location) from the type System.Location

I'm trying to do a geolocation, but I keep having this error ~Method does not exist or incorrect signature: void newInstance(System.Location, System.Location) from the type System.Location~
Here's the code:
try{
for(Lead_2__c ld : records){
List<Double> distancias = new List<Double>();
Map<Double,Id> mapDistUd = new Map<Double,Id>();
for(Account ud : accs){
Location locleads = Location.newInstance(ld.Latitude__c,ld.Longitude__c);
Location locUD = Location.newInstance(ud.BillingLatitude,ud.BillingLongitude);
Double dist = Location.getDistance(locleads, locUD, 'km');
mapDistUd.put(dist, ud.Id);
distancias.add(dist);
}
distancias.sort();
System.debug('Unidade distribuidora mais próxima a ' + distancias.get(0) + ' Km');
Id IdConta = mapDistUd.get(distancias.get(0));
System.debug('Id da Unidade Distribuidora que será relacionada ao Lead: ' + IdConta);
if(IdConta != null){
ld.Conta__c = IdConta;
}
}
update records;
} catch (Exception e){
System.debug('ERROR: ' + e.getMessage()+'. In line: ' + e.getLineNumber());
}
}

How to check if an array is not empty and some specific values of it are numeric?

I have two declared arrays with some parameters. First of all I need to check if the array is not empty and then if specific parameters of the first array are numeric.
Now I have two arrays. One of them has all parameters and the second has only the parameters thas have to be numeric (that are included in the first array too)
I want to do both checks in a method because I have them in two differents ones.
This is what I have
/** Array con parametros no obligatorios Array con los parametros obligatorios. */
private static final String[] PARAMETROS_OBLIGATORIOS = new String[] {
"idFichero","nombreFichero","qnuOrdest","idHsc","timCamestad","codGrupoest","qnuOrdestRcvd"
};
/** Array con los parametros que deben ser numericos. */
private static final String[] PARAMETROS_NUMERICOS = new String[] {
"idFichero","idHsc","qnuOrdest","qnuOrdestRcvd"
};
private void validarObligatorios(final JobParameters parameters) throws JobParametersInvalidException {
for (String nombre : PARAMETROS_OBLIGATORIOS) {
if (StringUtils.isBlank(parameters.getString(nombre))) {
String error ="El parametro " + nombre + " es obligatorio";
LOGGER.error(error);
throw new JobParametersInvalidException(error);
}
}
}
private void validarNumericos(final JobParameters parameters) throws JobParametersInvalidException {
for (String nombre : PARAMETROS_NUMERICOS) {
if (!StringUtils.isNumeric(parameters.getString(nombre))) {
String error = "El parametro " + nombre + " debe ser numerico";
LOGGER.error(error);
throw new JobParametersInvalidException(error);
}
}
}
What can I do to do both steps in a unique method?
Thanks in advance!
Would replacing your 2 methods validarObligatorios and validarNumericas by the following single function answer your question??
private void validarObligatoriosYNumericos(final JobParameters parameters) throws JobParametersInvalidException {
for (String nombre : PARAMETROS_OBLIGATORIOS) {
if (StringUtils.isBlank(parameters.getString(nombre))) {
String error ="El parametro " + nombre + " es obligatorio";
LOGGER.error(error);
throw new JobParametersInvalidException(error);
}
}
for (String nombre : PARAMETROS_NUMERICOS) {
if (!StringUtils.isNumeric(parameters.getString(nombre))) {
String error = "El parametro " + nombre + " debe ser numerico";
LOGGER.error(error);
throw new JobParametersInvalidException(error);
}
}
}
HTH!
Copy the numeric columns array into a list and use contains to see if a value should be checked. This solution assumes that the numeric column array is a sub-set of the mandatory column array but it looks like that is a safe assumption.
private void validarObligatorios(final JobParameters parameters) throws JobParametersInvalidException {
List<String> numericColumns = Arrays.asList(PARAMETROS_NUMERICOS );
String error = null;
for (String nombre : PARAMETROS_OBLIGATORIOS) {
if (StringUtils.isBlank(parameters.getString(nombre))) {
error ="El parametro " + nombre + " es obligatorio";
} else if (numericColumns.contains(nombre) {
if (!StringUtils.isNumeric(parameters.getString(nombre))) {
error = "El parametro " + nombre + " debe ser numerico";
}
}
if (error != null) {
LOGGER.error(error);
throw new JobParametersInvalidException(error);
}
}
}

Can't show arrayList elements in a method

I've got the following code:
It's a class used to store a monthly summary of expenses. voci is an arraylist used to store the expenses (name and cost). mese is the month of the summary, anno the year of summary. My problem is that when I call the showRiepilogo() method i must see the list of the expenses of that month but i can't see nothing. Someone can tell me why please?
class RiepilogoMensile extends Riepilogo {
private ArrayList<Voce> voci = new ArrayList<Voce>();
private int mese;
private int anno;
public RiepilogoMensile(int mese, int anno, String autore, ArrayList<Voce> voci) {
super(autore);
this.mese = mese;
this.anno = anno;
// il blocco successivo è necessario???in teoria il costruttore viene invocato solo una volta.. bisogna cambiare solo la set e la get?.. provo!
// aggiunta delle voci
boolean voceExist = false;
// variabile temporanea che contiene gli anni da aggiungere
ArrayList<Voce> oldVoci = new ArrayList<Voce>();
oldVoci.addAll(this.voci);
ArrayList<Voce> newVoci = new ArrayList<Voce>();
newVoci.addAll(voci);
// controllo se le voci da aggiungere sono già presenti
for (Voce a : oldVoci) {
voceExist = false;
for (int i = 0; i < newVoci.size(); i++) {
if (a.equals(newVoci.get(i))) {
voceExist = true;
break;
}
}
if (!voceExist)
voci.add(a);
}
// test costruttore
System.out.println("Test costruttore voci--> INIZIO");
for(Voce v:voci)
System.out.println(v.getNome()+" "+v.getSpesa());
System.out.println("Test costruttore voci--> FINE");
}
public ArrayList<Voce> getVoci() {
ArrayList<Voce> temp = new ArrayList<Voce>();
temp.addAll(this.voci);
return (temp);
}
public void setVoci(ArrayList<Voce> voci) {
// aggiunta delle voci
boolean voceExist = false;
// variabile temporanea che contiene gli anni da aggiungere
ArrayList<Voce> oldVoci = new ArrayList<Voce>();
oldVoci.addAll(this.voci);
ArrayList<Voce> newVoci = new ArrayList<Voce>();
newVoci.addAll(voci);
// controllo se le voci da aggiungere sono già presenti
for (Voce a : oldVoci) {
voceExist = false;
for (int i = 0; i < newVoci.size(); i++) {
if (a.equals(newVoci.get(i))) {
voceExist = true;
break;
}
}
if (!voceExist)
this.voci.add(a);
}
}
#Override
public void showRiepilogo() {
String messaggio = "\nRiepilogo del " + anno + " di " + Voce.intToString(mese) + " creato da " + getAutore()
+ ": ";
System.out.println(messaggio);
utils.showRow(messaggio.length() - 2, '-'); // tolgo 2 perchè non devo considerare \n
System.out.println();
System.out.println("Test stampa voci in showRiepilogo() voci--> INIZIO");
// stampa voci
for (Voce v : voci)
System.out.println(v.getNome() + " " + v.getSpesa() + " EURO " + (v.getSpesa() > 0 ? "<--ENTRATA" : "USCITA-->"));
for(int i=0;i<voci.size();i++) {
System.out.println(voci.get(i).getNome() + " " + voci.get(i).getSpesa() + " EURO " + (voci.get(i).getSpesa() > 0 ? "<--ENTRATA" : "USCITA-->"));
}
System.out.println("Test stampa voci in showRiepilogo() voci--> FINE");
}
}
When I call showRiepilogo() from main i can't see nothing instead i could see the content of voci ArrayList.
riepiloghiMensili.get(index).showRiepilogo();
Someone know why?
Thanks in advice, Elias.
You have a very weird constructor, you try to loop over the member this.voci but since your doing this in the constructor this.voci will always be an empty array. Look at the declaration:
private ArrayList<Voce> voci = new ArrayList<Voce>();
Your setVoci(...) method will fail for the same reason, this.voci is empty and the for loop will never be entered and no objects added to the array.
Change your constructor to just set the array to the given parameter
this.voci = voci
I would also recommend to do the same for the setVoci method or to rename it because a set... method is expected to set a member to the given parameter.
the reference of the ArrayList I've tried and it doesn't works well!Doing as what you tell to do assigns the same ArrayList to all the istances of RiepilogoMensile.
I've done that and all works fine:
class RiepilogoMensile extends Riepilogo {
private ArrayList<Voce> voci = new ArrayList<Voce>();
private int mese;
private int anno;
public RiepilogoMensile(int mese, int anno, String autore, ArrayList<Voce> voci) {
super(autore);
this.mese = mese;
this.anno = anno;
this.voci.addAll(voci);
}
public ArrayList<Voce> getVoci() {
ArrayList<Voce> temp = new ArrayList<Voce>();
temp.addAll(this.voci);
return (temp);
}
public void setVoci(ArrayList<Voce> voci) {
this.voci.addAll(voci);
// aggiunta delle voci
boolean voceExist = false;
// variabile temporanea che contiene gli anni da aggiungere
ArrayList<Voce> oldVoci = new ArrayList<Voce>();
oldVoci.addAll(this.voci);
ArrayList<Voce> newVoci = new ArrayList<Voce>();
newVoci.addAll(voci);
// controllo se le voci da aggiungere sono già presenti
for (Voce a : oldVoci) {
voceExist = false;
for (int i = 0; i < newVoci.size(); i++) {
if (a.equals(newVoci.get(i))) {
voceExist = true;
break;
}
}
if (!voceExist)
this.voci.add(a);
}
}
Thanks insted!
Bye, Elias.

PSQLException index out of bound

I can't figure out why my PreparedStatement is throwing an error.
Here is my function:
public boolean updateMail(int id, String new_mail, boolean showMail) {
String login = "";
String toUpdate = "";
boolean ret = false;
try {
req = cnx.prepareStatement("SELECT login FROM compte WHERE id = ?");
req.setInt(1, id);
ResultSet rs = req.executeQuery();
if (rs.next()) login = rs.getString(1);
} catch (SQLException e) {
e.printStackTrace();
}
if (!getDestinataire(login).equals(new_mail))
toUpdate = ", new_mail=?";
String reqq = "UPDATE compte SET show_mail=?" + toUpdate + " WHERE id=?";
System.out.println("Dest : " + getDestinataire(login) + "\nnew_mail : " + new_mail + "\ntoUpdate : " + toUpdate
+ "\nreqq : " + reqq);
try {
req = cnx.prepareStatement(reqq);
req.setBoolean(1, showMail);
if (!getDestinataire(login).equals(new_mail)) {
req.setString(2, new_mail);
}
req.setInt(2 + (getDestinataire(login).equals(new_mail) ? 0 : 1), id);
req.executeUpdate();
ret = true;
} catch (SQLException e) {
e.printStackTrace();
}
return ret;
}
The getDestinataire() method is working well. The trace I'm printing out looks like this:
Dest : example#example.com new_mail : example2#example2.com toUpdate : ,
new_mail=? reqq : UPDATE compte SET show_mail=?, new_mail=? WHERE id=?
So basically I have 3 columns: show_mail, new_mail and id.
But I have an error at req.setString(2, new_mail);:
org.postgresql.util.PSQLException: L'indice de la colonne est hors limite : 2, nombre de colonnes : 1.
I tried with and without the req.close() because I usually don't use it and it always worked great.
Also, this is the variable definition:
private Connection cnx;
private PreparedStatement req;
I already wrote a hundred database calls. Is this a stupid mistake that I'm too blind to see or is there a lib bug?

Reading a cell from Excel using Apache POI

I'm new to the Apache POI, so I'm having some trouble to use it.
I need to read an Excel file, but I don't need all the rows, because my final goal with this code is to shrink the file (that have over 900 lines) to have only the information I'll use later.
So I tried to use the following code:
public static void main(String[] args) {
List<Planejado> planejados = new ArrayList<Planejado>();
int i = 0;
int linha = 5;
try{
FileInputStream fis = new FileInputStream("C:\\Users\\fs0234\\Desktop\\Projetos\\Realizado X Planejado\\Planej. Semanal por CC do Funcionário (20).xls");
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet sheet = wb.getSheetAt(0);
int rowMax = sheet.getLastRowNum();
while (i <= rowMax) { // interação do excel validando pela coluna I
Row row = sheet.getRow(linha);
Cell cell = row.getCell(9);
if (cell.equals("")){ // Line 38
Planejado planejado = new Planejado();
planejado.setCentroCusto("CC - " + i); // obter valor da celula j + contador
planejado.setNomeRecurso("Recurso " + i); // obter valor da celula k + contador
for(int j = 1; j < 53; j++) { //interação das colunas w até bw
planejado.getTimecard().put("Semana" + j, 40 + j);//obter o valor das horas
}
planejados.add(planejado);
}
linha++;
i++;
}
for(Planejado planejado : planejados) {
//gravar no banco todos os objetos dentro da lista
System.err.println(planejado.getCentroCusto() + " | " + planejado.getNomeRecurso() + " | " + planejado.getTimecard().get("Semana6"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Where I need only the rows where the column 9 is empty.
But I get the Error
"Exception in thread "main" java.lang.NullPointerException
at main.PopulaPlanejado.main(PopulaPlanejado.java:38)"
Don't know if it's clear what I need to do, but I hope some of you can help me.
Instead Of using
if (cell.equals("")){
...
}
Try using this
if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK){
....
}
While using equals() for object comparison be careful otherwise you'll end up throwing NullPointerException. Do remember that calling any method on a null resulting object will throw a NPE.
You should remember some best practice to avoid NullPointerException.
Bad comparison
if (state.equals("OK")) {
...
}
Better comparison
if ("OK".equals(state)) {
...
}
So in the later case you don't have a chance to end up with NPE.
Hope it will help you. :)
Thank's to you and some other friend I'm was able to solve the problem.
Here is the code without bugs
List<Planejado> planejados = new ArrayList<Planejado>();
int i = 0;
int linha = 5;
try {
FileInputStream fis = new FileInputStream("C:\\Users\\fs0234\\Desktop\\Projetos\\Realizado X Planejado\\Planej. Semanal por CC do Funcionário (20).xls");
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet sheet = wb.getSheetAt(0);
int rowMax = sheet.getLastRowNum();
while (i <= rowMax) { // Loop até a última linha da planilha
Row row = sheet.getRow(linha);
if (row != null) { // Apenas linhas "não nulas"
Cell cell = row.getCell(8); // obter valor da celula I
if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) { //Verifica se a coluna I é nula
Cell CC = row.getCell(6); // obter valor da celula G
Cell nome = row.getCell(10); // obter valor da celula K
Planejado planejado = new Planejado();
planejado.setCentroCusto("CC - " + CC);
planejado.setNomeRecurso("Recurso - " + nome);
for (int j = 1, weekCol = 22; j <= 53; j++, weekCol++) { // Loop para pegar todas as semanas
Cell week = row.getCell(weekCol); // Obter valor da coluna da semana
if (week != null) {
planejado.getTimecard().put("Semana" + j, week.getNumericCellValue());
} else {
planejado.getTimecard().put("Semana" + j, Double.valueOf(0));
}
}
planejados.add(planejado);
}
}
linha++;
i++;
}
for (Planejado planejado : planejados) {
StringBuffer timecard = new StringBuffer();
for (int k = 1; k < 53; k++) {
timecard.append("Semana " + k);
timecard.append(": ");
timecard.append(planejado.getTimecard().get("Semana" + k));
timecard.append(", ");
}
System.err.println(planejado.getCentroCusto() + " | " + planejado.getNomeRecurso() + " | " + timecard.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

Categories

Resources