Visualizzazione dei risultati da 1 a 2 su 2
  1. #1

    Problema output di web service

    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:
    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>
    Per prima cosa ho creato due bean per gestire il tipo di oggetti che dovranno essere estrapolati dal file xml.

    Prodotto.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;
     	}
     }
    Confezione.java:
    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;
    	}
    	
    }
    A questo punto ho creato una classe che eseguisse concretamente le operazioni:

    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();
    	}
    }
    Lato server il codice dovrebbe essere il seguente:
    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;
    	}
    }
    Mentre il client è questo:
    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;
    	}
    }
    Purtroppo il risultato non è quello corretto anche se eclipse non segnala errori nel codice. Il messaggio che compare è il seguente:
    codice:
    ID: 1
    Categoria: Arance
    Nome: Navel
    Exception in thread "main" 
    java.lang.NullPointerException
    	at it.terramica.client.TerramicaClient.main(TerramicaClient.java:46)
    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!

  2. #2
    Per completezza questi sono i messaggi SOAP di richiesta e risposta:
    codice:
    POST /axis2/services/TerramicaService HTTP/1.1
    Content-Type: application/soap+xml; charset=UTF-8; action="urn:anonOutInOp"
    User-Agent: Axis2
    Host: 127.0.0.1:8081
    Transfer-Encoding: chunked
    
    d2
    <?xml version='1.0' encoding='UTF-8'?>
       <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
          <soapenv:Body>
             <tns:elenco xmlns:tns="http://www.terramica.it" />
          </soapenv:Body>
       </soapenv:Envelope>0
    codice:
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    Content-Type: application/soap+xml; action="urn:elencoResponse";charset=UTF-8
    Transfer-Encoding: chunked
    Date: Fri, 01 Jul 2011 14:52:46 GMT
    
    1094
    <?xml version='1.0' encoding='UTF-8'?>
       <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
          <soapenv:Body>
             <ns:elencoResponse xmlns:ns="http://service.terramica.it" xmlns:ax25="http://data.terramica.it/xsd">
                <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:Prodotto">
                   <ax25:ID>1</ax25:ID>
                   <ax25:categoria>Arance</ax25:categoria>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>15</ax25:peso>
                      <ax25:prezzo>15.0</ax25:prezzo>
                      <ax25:tipo>cassa</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>3</ax25:peso>
                      <ax25:prezzo>6.0</ax25:prezzo>
                      <ax25:tipo>sacchetto</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>10</ax25:peso>
                      <ax25:prezzo>12.0</ax25:prezzo>
                      <ax25:tipo>plateau</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezioni xsi:nil="true" />
                   <ax25:nome>Navel</ax25:nome>
                </ns:return>
                <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:Prodotto">
                   <ax25:ID>2</ax25:ID>
                   <ax25:categoria>Arance</ax25:categoria>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>15</ax25:peso>
                      <ax25:prezzo>17.0</ax25:prezzo>
                      <ax25:tipo>cassa</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>3</ax25:peso>
                      <ax25:prezzo>7.0</ax25:prezzo>
                      <ax25:tipo>sacchetto</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>10</ax25:peso>
                      <ax25:prezzo>14.0</ax25:prezzo>
                      <ax25:tipo>plateau</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezioni xsi:nil="true" />
                   <ax25:nome>Tarocco</ax25:nome>
                </ns:return>
                <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:Prodotto">
                   <ax25:ID>3</ax25:ID>
                   <ax25:categoria>Limoni</ax25:categoria>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>3</ax25:peso>
                      <ax25:prezzo>7.5</ax25:prezzo>
                      <ax25:tipo>sacchetto</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>7</ax25:peso>
                      <ax25:prezzo>14.0</ax25:prezzo>
                      <ax25:tipo>plateau</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezioni xsi:nil="true" />
                   <ax25:nome>Limoni_di_Sorrento</ax25:nome>
                </ns:return>
                <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:Prodotto">
                   <ax25:ID>4</ax25:ID>
                   <ax25:categoria>Mandarini</ax25:categoria>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>10</ax25:peso>
                      <ax25:prezzo>13.0</ax25:prezzo>
                      <ax25:tipo>cassa</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>5</ax25:peso>
                      <ax25:prezzo>7.5</ax25:prezzo>
                      <ax25:tipo>plateau</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezioni xsi:nil="true" />
                   <ax25:nome>Clementine</ax25:nome>
                </ns:return>
                <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:Prodotto">
                   <ax25:ID>5</ax25:ID>
                   <ax25:categoria>Limoni</ax25:categoria>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>3</ax25:peso>
                      <ax25:prezzo>5.0</ax25:prezzo>
                      <ax25:tipo>sacchetto</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>7</ax25:peso>
                      <ax25:prezzo>7.5</ax25:prezzo>
                      <ax25:tipo>plateau</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezioni xsi:nil="true" />
                   <ax25:nome>Limoni_sfusi</ax25:nome>
                </ns:return>
                <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:Prodotto">
                   <ax25:ID>6</ax25:ID>
                   <ax25:categoria>Mandarini</ax25:categoria>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>10</ax25:peso>
                      <ax25:prezzo>13.0</ax25:prezzo>
                      <ax25:tipo>cassa</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>5</ax25:peso>
                      <ax25:prezzo>7.5</ax25:prezzo>
                      <ax25:tipo>plateau</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezioni xsi:nil="true" />
                   <ax25:nome>Mandarini</ax25:nome>
                </ns:return>
                <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:Prodotto">
                   <ax25:ID>7</ax25:ID>
                   <ax25:categoria>Arance</ax25:categoria>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>15</ax25:peso>
                      <ax25:prezzo>15.0</ax25:prezzo>
                      <ax25:tipo>cassa</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezione xsi:type="ax25:Confezione">
                      <ax25:peso>3</ax25:peso>
                      <ax25:prezzo>5.0</ax25:prezzo>
                      <ax25:tipo>sacchetto</ax25:tipo>
                   </ax25:confezione>
                   <ax25:confezioni xsi:nil="true" />
                   <ax25:nome>Arance_da_giardino T</ax25:nome>
                </ns:return>
             </ns:elencoResponse>
          </soapenv:Body>
       </soapenv:Envelope>
    0
    Sono quasi sicuro che il problema sia in BeanUtil.deserialize(), come se non riuscisse a gestire i valori legati al tag confezione, però non so come gestire la cosa.
    Nessuno sa dirmi come correggere il problema o se esiste un'altra maniera per recuperare il risultato?
    Vi prego, non so più dove sbattere la testa!!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.