Salve a tutti, spero di aver scelto la sezione corretta per farvi questa domanda.
Ho un problema con un web service che legge alcune informazioni da un file xml e le stampa. Vi mostro il codice e alla fine vi spiego quale penso sia il problema, nella speranza che qualcuno mi aiuti a comprendere cosa sto sbagliando.
Questo è un frammento del file xml (per farvi comprendere la maniera in cui è strutturato:
Per prima cosa ho creato due bean per gestire il tipo di oggetti che dovranno essere estrapolati dal file xml.codice:<?xml version="1.0" encoding="UTF-8"?> <prodotti> <prodotto id="01"> <nome>Navel</nome> <categoria>Arance</categoria> <pezzatura> <confezione tipo = "cassa" peso = "15" prezzo= "15"/> <confezione tipo = "sacchetto" peso = "3" prezzo="6"/> <confezione tipo = "plateau" peso = "10" prezzo="12"/> </pezzatura> </prodotto> <prodotto id="03"> <nome>Limoni_di_Sorrento</nome> <categoria>Limoni</categoria> <pezzatura> <confezione tipo = "sacchetto" peso = "3" prezzo="7.50"/> <confezione tipo = "plateau" peso = "7" prezzo="14"/> </pezzatura> </prodotto> </prodotti>
Prodotto.java:
Confezione.java:codice:public class Prodotto { private int id; private String nome; private String categoria; private Confezione[] confezioni; public int getID() { return id; } public void setID(int i) { id = i; } public String getNome() { return nome; } public void setNome(String n) { nome = n; } public String getCategoria() { return categoria; } public void setCategoria(String c) { categoria = c; } public Confezione[] getConfezione() { return confezioni; } public void setConfezioni(Confezione[] conf) { confezioni = conf; } }
A questo punto ho creato una classe che eseguisse concretamente le operazioni:codice:public class Confezione { String tipo; int peso; float prezzo; public String getTipo() { return tipo; } public void setTipo(String t) { tipo = t; } public int getPeso() { return peso; } public void setPeso(int p) { peso = p; } public float getPrezzo() { return prezzo; } public void setPrezzo(float pr) { prezzo = pr; } }
Lato server il codice dovrebbe essere il seguente:codice:public class ProdottoDB { Prodotto[] prodotti; Confezione[] confezioni; public ProdottoDB(Document doc) throws Exception { NodeList list = doc.getElementsByTagName("prodotto"); int length = list.getLength(); prodotti = new Prodotto[length]; Prodotto p = null; for (int i = 0; i < length; i++) { Element elem = (Element)list.item(i); p = new Prodotto(); p.setID(Integer.parseInt(elem.getAttribute("id"))); p.setNome(getValue(elem, "nome")); p.setCategoria(getValue(elem, "categoria")); NodeList listConf = elem.getElementsByTagName("confezione"); confezioni = new Confezione[listConf.getLength()]; for (int j = 0; j < listConf.getLength(); j++) { Element elemConf = (Element)listConf.item(j); Confezione c = new Confezione(); c.setTipo(elemConf.getAttribute("tipo")); c.setPrezzo(Float.parseFloat(elemConf.getAttribute("prezzo"))); c.setPeso(Integer.parseInt(elemConf.getAttribute("peso"))); confezioni[j] = c; System.out.println("confezioni"); } p.setConfezioni(confezioni); prodotti[i] = p; } } public Prodotto[] getProdotti() { return prodotti; } public float getPrezzo(int id, String categoria) { for (int i = 0; i < prodotti.length; i++) { if (id == prodotti[i].getID()) { Confezione[] c = prodotti[i].getConfezione(); for (int j=0; j<c.length; j++) { if (categoria.equals(c[j].getTipo())) return c[j].getPrezzo(); } } } return -1; } /* * Legge il valore di un nodo Element */ private String getValue(Element elem, String name) { NodeList l = elem.getElementsByTagName(name); if (l == null || l.getLength() == 0) return null; elem = (Element)l.item(0); return elem.getFirstChild().getNodeValue(); } }
Mentre il client è questo:codice:public class TerramicaService { private static String file = "Terramica/ProdottiTerramica.xml"; public static Prodotto[] elenco() throws Exception { MessageContext msgCtx = MessageContext.getCurrentMessageContext(); ServletContext ctx = (ServletContext) msgCtx.getProperty(HTTPConstants.MC_HTTP_SERVLETCONTEXT); String rpath = ctx.getRealPath(file); BufferedInputStream in = new BufferedInputStream(new FileInputStream(rpath)); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(in); ProdottoDB db = new ProdottoDB(doc); Prodotto[] prod = db.getProdotti(); return prod; } public float prezzo(int id, String tipo) throws Exception { MessageContext msgCtx = MessageContext.getCurrentMessageContext(); ServletContext ctx = (ServletContext) msgCtx.getProperty(HTTPConstants.MC_HTTP_SERVLETCONTEXT); String rpath = ctx.getRealPath(file); BufferedInputStream in = new BufferedInputStream(new FileInputStream(rpath)); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(in); ProdottoDB db = new ProdottoDB(doc); float prezzo = db.getPrezzo(id, tipo); return prezzo; } }
Purtroppo il risultato non è quello corretto anche se eclipse non segnala errori nel codice. Il messaggio che compare è il seguente:codice:public class TerramicaClient { public static void main(String[] args) throws Exception { BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Scegliere l'operazione da eseguire: "); System.out.println("1 - Elenco prodotti: "); System.out.println("2 - Ricerca prezzo: "); int sel = Integer.parseInt(console.readLine()); // //System.out.println("I prodotti non sono disponibili"); if (sel==1) { ArrayList<Prodotto> prods = elenca(); for (Prodotto p : prods) { System.out.println("ID: " + p.getID()); System.out.println("Categoria: " + p.getCategoria()); System.out.println("Nome: " + p.getNome()); Confezione[] confs = p.getConfezione(); for (int i=0; i<confs.length; i++) { System.out.println("Tipo confezione: " + confs[i].getTipo()); System.out.println("Peso confezione: " + confs[i].getPeso()); System.out.println("Prezzo confezione: " + confs[i].getPrezzo()); } } } if (sel==2) { System.out.println("ID?: "); int id = Integer.parseInt(console.readLine()); System.out.println("Tipo?: "); String tipo = console.readLine(); float res = prezzo(id, tipo); System.out.println("Prezzo: " + res); } } private static ArrayList<Prodotto> elenca() throws Exception { ArrayList<Prodotto> prs = new ArrayList<Prodotto>(); ServiceClient serviceClient = new ServiceClient(); OMFactory fac = OMAbstractFactory.getSOAP12Factory(); OMNamespace omNs = fac.createOMNamespace("http://www.terramica.it", "tns"); OMElement method = fac.createOMElement("elenco", omNs); Options options = serviceClient.getOptions(); EndpointReference targetEPR = new EndpointReference("http://localhost:8081/axis2/services/TerramicaService"); options.setSoapVersionURI(Constants.URI_SOAP12_ENV); options.setTo(targetEPR); // invocazione del servizio utilizzando la MEP in-out OMElement result = serviceClient.sendReceive(method); // recupera il risultato Iterator values = result.getChildrenWithName(new QName("http://service.terramica.it", "return")); while (values.hasNext()) { OMElement omElement = (OMElement) values.next(); Prodotto prod = (Prodotto) BeanUtil.deserialize(Prodotto.class, omElement, new DefaultObjectSupplier(), "prodotto"); prs.add(prod); } return prs; } private static float prezzo(int id, String categoria) throws Exception { ServiceClient serviceClient = new ServiceClient(); OMFactory fac = OMAbstractFactory.getSOAP12Factory(); OMNamespace omNs = fac.createOMNamespace("http://service.terramica.it", "tns"); OMElement method = fac.createOMElement("prezzo", omNs); OMElement arg0 = fac.createOMElement("id", omNs); arg0.addChild(fac.createOMText(arg0, String.valueOf(id))); method.addChild(arg0); OMElement arg1 = fac.createOMElement("tipo", omNs); arg1.addChild(fac.createOMText(arg1, categoria)); method.addChild(arg1); Options options = serviceClient.getOptions(); EndpointReference targetEPR = new EndpointReference("http://localhost:8081/axis2/services/TerramicaService"); options.setSoapVersionURI(Constants.URI_SOAP12_ENV); options.setTo(targetEPR); // invocazione del servizio utilizzando la MEP in-out OMElement result = serviceClient.sendReceive(method); // recupera il risultato float response = Float.parseFloat(result.getFirstElement().getText()); return response; } }
Facendo un po' di debug quello che mi sembra di capire è che per qualche motivo gli oggetti di tipo confezione non vengano salvati nella struttura dati corrispondente. Tramite TCPMon però ho verificato che il messaggio di risposta contiene tutti i dati necessari. A questo punto mi sono bloccato perchè non riesco a capire come risolvere la situazione... spero che qualcuno possa darmi una mano a capire dov'è l'errore!codice:ID: 1 Categoria: Arance Nome: Navel Exception in thread "main" java.lang.NullPointerException at it.terramica.client.TerramicaClient.main(TerramicaClient.java:46)![]()

Rispondi quotando