# XMLRPC-Schnittstelle. Einzelne Felder aus dem Object auslesen



## Babykin (27. Sep 2013)

Hallo zusammen,

über eine XMLRPC-Schnittstelle bekomme ich ein Object, das in eine Hashmap umgewandelt wird.
System.out.println(result) gibt folgendes aus:

{position=0, forum_title=[B@91520, can_subscribe=false, forum_id=30, posts=[Ljava.lang.Object;@4a0ac5, can_upl
oad=false, is_approved=true, topic_id=158308, total_post_num=7, topic_title=[B@1092447, can_reply=false}


Wie kann ich aus topic_title einen String gewinnen? Wie kann ich auf posts zugreifen? Leider habe ich in der Doku außer sehr einfachen Beispielen keine Infos gefunden. Hier die Doki [JAPI]http://ws.apache.org/xmlrpc/client.html[/JAPI]


```
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import java.net.*;
import java.util.*;
import java.io.Serializable;

public class XmlRpcTest implements Serializable
{
	public static void main(String[] args)
	{
		XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
		try
		{
			config.setServerURL(new URL("http://www.fachinformatiker.de/mobiquo/mobiquo.php"));
		}
		catch (MalformedURLException e)
		{
		}
		
		XmlRpcClient client = new XmlRpcClient();
		client.setConfig(config);
		
		Object[] params = new Object[]{new String("158308"), new Integer(0), new Integer(25)};
		try
		{
			
			HashMap thread = (HashMap) client.execute("get_thread", params);
		
			int forum_id = 0; 
			try
			{
				forum_id = Integer.parseInt((String)thread.get("forum_id"));
			}
			catch(Exception e)
			{
				System.out.println(e);
			}
			System.out.println(forum_id);
			
			Object posts;
			posts = thread.get("posts");
			
			System.out.println(thread);
			
		}
		catch(Exception e)
		{
			System.out.println(e);
		}
			
	}
}
```


----------



## kay73 (27. Sep 2013)

```
topic_title=[B@1092447
```
 ist ein byte-Array, das Du zurecht casten kannst und einem String als Konstruktor-Argument übergeben kannst. Ergibt 
	
	
	
	





```
Einzelne Felder aus dem Object auslesen.
```
 Umlaut-Probleme leider inklusive.

Entweder stellt Dir der Designer dieser Schnittstelle eine Doku zur Verfügung oder Du musst anhand der Objekte die Klassen erraten. Unten ist ein kleines Tool, das das macht. Ich sehe da alles Mögliche: String, Integer, Booleans, Date, byte[] und Listen von allem. 


```
(Map<?,?>): key: position, value: (class java.lang.Integer): 0
key: forum_title, value: (byte[]) Java
key: can_subscribe, value: (class java.lang.Boolean): false
key: forum_id, value: (class java.lang.String): 30
key: posts, value: (Map<?,?>): key: allow_smilies, value: (class java.lang.Boolean): true
key: post_author_id, value: (class java.lang.String): 84125
key: icon_url, value: (class java.lang.String): 
key: attachment_authority, value: (class java.lang.Integer): 4
key: post_id, value: (class java.lang.String): 1424018
key: post_content, value: (byte[]) Hallo zusammen,

Ã¼ber eine XMLRPC-Schnittstelle bekomme ich ein Object

Object result = client.execute("get_thread", params);

System.out.println(result) gibt folgendes aus:

[quote]
{forum_id=16, prefix=[B@34f445, forum_name=[B@90ed81, posts=[Ljava.lang.Object;@d8c3ee, can_upload=false, is_s
ubscribed=false, topic_id=3433, total_post_num=131, topic_title=[B@1277a30}
[/quote]

Wie kann ich auf einzelne Werte von forum_id , total_post_num etc zugreifen? 

Vielen Dank.
key: timestamp, value: (class java.lang.String): 1380198075
key: post_count, value: (class java.lang.Integer): 1
key: post_author_name, value: (byte[]) vinslave
key: is_approved, value: (class java.lang.Boolean): true
key: attachments, value: 
key: topic_id, value: (class java.lang.String): 158308
key: post_title, value: (byte[]) Einzelne Felder aus dem Object auslesen.
key: post_time, value: (class java.util.Date): Thu Sep 26 14:21:15 CEST 2013

(Map<?,?>): key: allow_smilies, value: (class java.lang.Boolean): true
key: post_author_id, value: (class java.lang.String): 84125
key: icon_url, value: (class java.lang.String): 
key: attachment_authority, value: (class java.lang.Integer): 4
key: post_id, value: (class java.lang.String): 1424019
key: post_content, value: (byte[]) ich habe folgendes mit HashMap gemacht:

[quote]
HashMap<String, Object> result = new HashMap<String, Object>();
result = (HashMap) client.execute("get_thread", params);
System.out.println(result.get("forum_id"));
[/quote]
es funktioniert zwar, aber gibt es eine bessere LÃ¶sung?
key: timestamp, value: (class java.lang.String): 1380199336
key: post_count, value: (class java.lang.Integer): 2
key: post_author_name, value: (byte[]) vinslave
key: is_approved, value: (class java.lang.Boolean): true
key: attachments, value: 
key: topic_id, value: (class java.lang.String): 158308
key: post_title, value: (byte[]) 
key: post_time, value: (class java.util.Date): Thu Sep 26 14:42:16 CEST 2013

(Map<?,?>): key: allow_smilies, value: (class java.lang.Boolean): true
key: post_author_id, value: (class java.lang.String): 88805
key: icon_url, value: (class java.lang.String): 
key: attachment_authority, value: (class java.lang.Integer): 4
key: post_id, value: (class java.lang.String): 1424023
key: post_content, value: (byte[]) Hat das zurÃ¼ckgegebene Objekt keine Getter, um auf die Member direkt zuzugreifen? Du kÃ¶nntest auch eine Unterklasse vom Objekt erstellen und die toString-Methode Ã¼berschreiben und dort die gewÃ¼nschten Member auflisten.
key: timestamp, value: (class java.lang.String): 1380200176
key: post_count, value: (class java.lang.Integer): 3
key: post_author_name, value: (byte[]) pr0gg3r
key: is_approved, value: (class java.lang.Boolean): true
key: attachments, value: 
key: topic_id, value: (class java.lang.String): 158308
key: post_title, value: (byte[]) 
key: post_time, value: (class java.util.Date): Thu Sep 26 14:56:16 CEST 2013

(Map<?,?>): key: allow_smilies, value: (class java.lang.Boolean): true
key: post_author_id, value: (class java.lang.String): 84125
key: icon_url, value: (class java.lang.String): 
key: attachment_authority, value: (class java.lang.Integer): 4
key: post_id, value: (class java.lang.String): 1424028
key: post_content, value: (byte[]) es geht hier um die Response einer XMLRPC-Abfrage. Also es gibt leider keine Getter. (ist doch nicht mÃ¶glich bei XMLRPC, oder?)
Ich kann toString Ã¼berschreiben, aber zu welchem Zweck? Und in der Ã¼berschriebenen Methode brauche ich auch die MÃ¶glichkeit auf die Members zuzugreifen. Ich habe die LÃ¶sung mit HashMap gefunden, allerdings bin ich damit nicht sehr zufrieden. Der Compiler sagt:

[QUOTE]Note: XmlRpcTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.[/QUOTE]

was ganz logisch ist. Und einige Members des Response-Objectes sind selbst Objekte. Also da brÃ¤chte ich wieder eine Hashmap. Ich habe keine andere Idee.
key: timestamp, value: (class java.lang.String): 1380204223
key: post_count, value: (class java.lang.Integer): 4
key: post_author_name, value: (byte[]) vinslave
key: is_approved, value: (class java.lang.Boolean): true
key: attachments, value: 
key: topic_id, value: (class java.lang.String): 158308
key: post_title, value: (byte[]) 
key: post_time, value: (class java.util.Date): Thu Sep 26 16:03:43 CEST 2013

(Map<?,?>): key: allow_smilies, value: (class java.lang.Boolean): true
key: post_author_id, value: (class java.lang.String): 84125
key: icon_url, value: (class java.lang.String): 
key: attachment_authority, value: (class java.lang.Integer): 4
key: post_id, value: (class java.lang.String): 1424031
key: post_content, value: (byte[]) und wie kann ich aus topic_title einen String gewinnen? System.out.println(result) liefert nur "topic_title=[B@1277a30}"
key: timestamp, value: (class java.lang.String): 1380205470
key: post_count, value: (class java.lang.Integer): 5
key: post_author_name, value: (byte[]) vinslave
key: is_approved, value: (class java.lang.Boolean): true
key: attachments, value: 
key: topic_id, value: (class java.lang.String): 158308
key: post_title, value: (byte[]) 
key: post_time, value: (class java.util.Date): Thu Sep 26 16:24:30 CEST 2013

(Map<?,?>): key: allow_smilies, value: (class java.lang.Boolean): true
key: post_author_id, value: (class java.lang.String): 24614
key: icon_url, value: (class java.lang.String): 
key: attachment_authority, value: (class java.lang.Integer): 4
key: post_id, value: (class java.lang.String): 1424041
key: post_content, value: (byte[]) Von welchem Typ ist den dein Client? Was fÃ¼r einen Typ erwartest du denn aus dem execute?
Nutzt du Standard Bibliotheken oder hast du weitere jars in deinen Klassenpfad aufgenommen. Wenn du weitere jars nutzt welche nutzt du. Denn so ist das hier ein wildes drauf los raten was du da versuchst zu machen.
key: timestamp, value: (class java.lang.String): 1380227721
key: post_count, value: (class java.lang.Integer): 6
key: post_author_name, value: (byte[]) Schiller256
key: is_approved, value: (class java.lang.Boolean): true
key: attachments, value: 
key: topic_id, value: (class java.lang.String): 158308
key: post_title, value: (byte[]) 
key: post_time, value: (class java.util.Date): Thu Sep 26 22:35:21 CEST 2013

(Map<?,?>): key: allow_smilies, value: (class java.lang.Boolean): true
key: post_author_id, value: (class java.lang.String): 84125
key: icon_url, value: (class java.lang.String): 
key: attachment_authority, value: (class java.lang.Integer): 4
key: post_id, value: (class java.lang.String): 1424062
key: post_content, value: (byte[]) es werden einige Klassen importiert.
[quote]
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
[/quote]

Die jars werden hier benutzt:

ws-commons-util.jar
xmlrpc-client.jar
xmlrpc-common.jar

Leider ist die Dokumentation dazu nicht wirklich hilfreich. [url=http://ws.apache.org/xmlrpc/client.html]ws-xmlrpc - The Apache XML-RPC Client[/url]

client wird so definiert: XmlRpcClient client = new XmlRpcClient(); und liefert ein Objekt. result kann man im Prinzip auch so definieren:

HashMap result = new HashMap();
result = (HashMap) client.execute("get_thread", params);
System.out.println(result.get("forum_id"));


Gibt es keine allgemein LÃ¶sung, wie man Objekte aus dem Objekt auslesen kann?
key: timestamp, value: (class java.lang.String): 1380270646
key: post_count, value: (class java.lang.Integer): 7
key: post_author_name, value: (byte[]) vinslave
key: is_approved, value: (class java.lang.Boolean): true
key: attachments, value: 
key: topic_id, value: (class java.lang.String): 158308
key: post_title, value: (byte[]) 
key: post_time, value: (class java.util.Date): Fri Sep 27 10:30:46 CEST 2013


key: can_upload, value: (class java.lang.Boolean): false
key: is_approved, value: (class java.lang.Boolean): true
key: topic_id, value: (class java.lang.String): 158308
key: total_post_num, value: (class java.lang.Integer): 7
key: topic_title, value: (byte[]) Einzelne Felder aus dem Object auslesen.
key: can_reply, value: (class java.lang.Boolean): false
```

Habe ich hiermit erzeugt:
	
	
	
	





```
package com.test;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

public class XmlRPCTest {

	static void dump(final Object o, StringBuilder b) {
		if(o == null) {
			b.append( "<null>");
		} else if(o instanceof byte []) {
			b.append(String.format("(byte[]) %s", new String((byte[]) o)));
		} else  if(o instanceof Object []) {
			for(final Object o2 : (Object[]) o) {				
				dump(o2, b);
				b.append("\n");
			}
		} else if(o instanceof Map<?,?>) {
			 b.append("(Map<?,?>): ");
			 for(final Map.Entry<?,?> entry : ((Map<?,?>)o).entrySet()) {			    	
			    	b.append(String.format("key: %s, value: ", entry.getKey()));
			    	dump(entry.getValue(), b);
			    	b.append("\n");	    
			    }
		} else {
			b.append("(").append(o.getClass()).append("): ").append(o.toString());
		}
	}

	public static void main(String[] args) throws MalformedURLException, XmlRpcException {

		final XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
	    config.setServerURL(new URL("http://www.fachinformatiker.de/mobiquo/mobiquo.php"));
	    final  XmlRpcClient client = new XmlRpcClient();
	    client.setConfig(config);
	    
	    final Object[] params = new Object[]{new String("158308"), new Integer(0), new Integer(25)};	    
	    
	    final StringBuilder b = new StringBuilder();
	    dump(client.execute("get_thread", params), b);
	    
	    System.out.println(b.toString());
	}
}
```


----------



## Babykin (27. Sep 2013)

Super! Vielen, vielen Dank!
Die Dump-Methode ist Hammer. Die Umlaute kriege ich schon hin 
Die Schnittstelle ist relativ schlecht beschrieben, aber es gibt derer Quelltexte in PHP. Und in PHP habe ich schon einen Client realisiert. Es war kein Hexenwerk, vor allerdings weil es keine Typisierung in php gibt. Im Prinzip kann man ins XML reinschauen, welche Datentypen da benutzt werden.


----------

