| Code Kitchen Allgemeines Coder-Forum rund um das Programmieren eigenständiger, ausführbarer Programme. |
Diskussion: Java und Apache XML-RPC - Default Handler? im Forum Code Kitchen, in der Kategorie Software Home; Anzeige Hi, ich arbeite gerade an einer Java Software, die mit einem am Netzwerk angebundenen Gerät per XML-RPC kommunziert. Das ...
![]() |
| | #1 (permalink) |
| Senior Member Registriert seit: 26.03.06 ![]() Likes: 16 | Anzeige Hi, ich arbeite gerade an einer Java Software, die mit einem am Netzwerk angebundenen Gerät per XML-RPC kommunziert. Das Gerät macht Callbacks auf einen XML-RPC Server, den ich bereitstellen muss. Und da liegt das Problem: Diese Callbacks sehen etwa so aus: Code: mathias@mini:~$ nc -l 8000 POST /xmlrpc HTTP/1.1 User-Agent: XMLRPC++ 0.7 Host: 10.0.0.211:8000 Content-Type: text/xml Content-length: 141 <?xml version="1.0"?> <methodCall><methodName>listDevices</methodName> <params><param><value>someID</value></param></params></methodCall> Weiss jemand ob und wie ich mit solchen Calls überhaupt etwas anfangen kann bzw sie irgendwie behandeln kann? Grüße serow EDIT: Um es mal auf ein Minibespiel herunterzubrechen habe ich hier einen EchoServer und EchoClient. Der EchoClient ruft auf dem Server die Methode "echo" auf, aber genauso wie mein Gerät hier ohne einen Handler angzugeben. Code: public class EchoServer {
public static void main(String[] args) throws Exception {
WebServer webServer = new WebServer(8080);
EchoService echo = new EchoServiceImpl();
PropertyHandlerMapping phm = new PropertyHandlerMapping();
phm.setRequestProcessorFactoryFactory(new EchoRequestProcessorFactoryFactory(echo));
phm.setVoidMethodEnabled(true);
phm.addHandler("EchoService", EchoService.class);
XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
xmlRpcServer.setHandlerMapping(phm);
XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
serverConfig.setEnabledForExtensions(true);
serverConfig.setContentLengthOptional(false);
webServer.start();
}
}
public class EchoClient {
public static void main(String[] args) throws Exception {
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://127.0.0.1:8080/xmlrpc"));
config.setEnabledForExtensions(true);
config.setConnectionTimeout(60 * 1000);
config.setReplyTimeout(60 * 1000);
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
Object[] params = new Object[] {"bla"};
client.execute("echo", params);
}
} Geändert von Serow (25.07.11 um 17:06 Uhr) |
| | |
| | #2 (permalink) |
| Senior Member Themenstarter Registriert seit: 26.03.06 ![]() Likes: 16 | Hi nochmal, mir sind gerade Zweifel gekommen ob ich mit diesem doch sehr speziellen Anliegen hier überhaupt richtig bin. Deswegen habe ich den Beitrag noch in einem Java Forum gepostet: Apache XMl-RPC - Default Handler Grüße serow |
| | |
| HaBOT | - Anzeige - |
| |
| | #3 (permalink) |
| Senior Member | Hallo Serow, ich hab mir mal die Sourcen von Apache XML-RPC angeschaut. Ich konnte keine Möglichkeit finden einen Default-Handler zu bestimmen. Ich habs aber dennoch geschafft daß ein Clientaufruf ohne Handler "angenommen" wird. Ich hab einfach die Klasse org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java überschrieben und konnte somit bei der Methode getHandler einen Defaultwert hinterlegen. Wenn dir diese Variante nicht zu dirty ist kann ich die Sourcen hier posten. Gruß odigo |
| | |
| | #4 (permalink) |
| Senior Member | Ach was solls, ich poste es einfach. Du kannst es benutzen oder auch nicht. Vorab nochmal zur Erklärung was ich gemacht habe. Die unveränderte Methode getHandler Code: public XmlRpcHandler getHandler(String pHandlerName)
throws XmlRpcNoSuchHandlerException, XmlRpcException {
XmlRpcHandler result = (XmlRpcHandler) handlerMap.get(pHandlerName);
if (result == null) {
throw new XmlRpcNoSuchHandlerException("No such handler: " + pHandlerName);
}
return result;
} Code: public XmlRpcHandler getHandler(String pHandlerName)
throws XmlRpcNoSuchHandlerException, XmlRpcException {
XmlRpcHandler result = (XmlRpcHandler) handlerMap.get("Calculator." + pHandlerName);
if (result == null) {
throw new XmlRpcNoSuchHandlerException("No such handler: " + pHandlerName);
}
return result;
} |
| | |
| | #5 (permalink) |
| Senior Member Themenstarter Registriert seit: 26.03.06 ![]() Likes: 16 | Hi, vielen Dank! Ist zwar dirty aber ich bin da momentan nicht wählerisch ![]() Grüße serow |
| | |
| | #6 (permalink) |
| Senior Member Themenstarter Registriert seit: 26.03.06 ![]() Likes: 16 | Hi, @odigo: Hast du zufällig auch entdeckt, die man die system.* Methoden implementieren kann? In der Dokumentation steht zwar etwas darüber, aber so wirklich schnallen will ichs nicht. Gerade die Methode system.multicall ist für mich sehr wichtig und die wird überhaupt nicht implementiert. Grüße serow |
| | |
| | #7 (permalink) |
| Senior Member Themenstarter Registriert seit: 26.03.06 ![]() Likes: 16 | Hi, ich hatte gerade etwas Zeit etwas rumzuprobieren. Ich habs es geschafft system.multicall zu implementieren. Apache XMP-RPC hat bereits system.listMethods, system.methodSignature und system.methodHelp implementiert. Da habe icn angeknüpft und system.multicall dazugepackt: Code: public class SystemHandler {
private XmlRpcListableHandlerMapping mapping;
public SystemHandler(XmlRpcListableHandlerMapping pMapping) {
this.mapping = pMapping;
}
public String[][] methodSignature(String methodName) throws XmlRpcException {
return mapping.getMethodSignature(methodName);
}
public String methodHelp(String methodName) throws XmlRpcException {
return mapping.getMethodHelp(methodName);
}
public String[] listMethods() throws XmlRpcException {
return mapping.getListMethods();
}
@SuppressWarnings("unchecked")
public void multicall(Object[] calls) throws XmlRpcException {
System.out.println("MULTICALL: " + Arrays.toString(calls));
for(Object obj: calls) {
Map<String, Object> call = (Map<String, Object>)obj;
String methodname = call.get("methodname").toString();
Object[] params = (Object[])call.get("params");
XmlRpcRequest req = new XmlRpcClientRequestImpl(
new XmlRpcRequestConfig() {
@Override
public TimeZone getTimeZone() {
return null;
}
@Override
public boolean isEnabledForExtensions() {
return false;
}
},
methodname,
params
);
XmlRpcHandler handler = mapping.getHandler(methodname);
handler.execute(req);
}
}
public static void addSystemHandler(final PropertyHandlerMapping pMapping) throws XmlRpcException {
final RequestProcessorFactoryFactory factory = pMapping.getRequestProcessorFactoryFactory();
final SystemHandler systemHandler = new SystemHandler(pMapping);
pMapping.setRequestProcessorFactoryFactory(
new RequestProcessorFactoryFactory(){
@SuppressWarnings("unchecked")
public RequestProcessorFactory getRequestProcessorFactory(Class pClass) throws XmlRpcException {
if (SystemHandler.class.equals(pClass)) {
return new RequestProcessorFactory(){
public Object getRequestProcessor(XmlRpcRequest request) throws XmlRpcException {
return systemHandler;
}
};
} else {
return factory.getRequestProcessorFactory(pClass);
}
}
}
);
pMapping.addHandler("system", SystemHandler.class);
}
} Weiss jemand einen anderen Weg? Oder gar eine andere API, die das alles implementiert? Was ich etwas seltsam finde: Wenn man bei Google nach "apache xml rpc system.multicall" sucht findet man beispielsweise das hier: MultiCall (Apache XML-RPC 2.0.1 API) So eine Klasse gibt es nur leider nicht... Das scheint eine ganz andere API zu sein, als die, die man runterladen kann. Schnall ich nicht ... Grüße serow |
| | |
| | #8 (permalink) |
| Senior Member | Versteh ich auch nicht warum Multicall von Version 2 auf 3 anscheinend wegrationalisiert worden ist. Der XML-RPC-Server in C unterstützt imho auch nach wie vor Multicall. |
| | |
| | #9 (permalink) |
| Senior Member Themenstarter Registriert seit: 26.03.06 ![]() Likes: 16 | Hi, ich vermute mal den kann ich aus Java heraus schlecht nutzen oder? |
| | |
| | #10 (permalink) |
| Senior Member | Äh ja. Das einzige was du natürlich machen könntest daß du Multicall auf Basis von den C-Sourcen nachbaust. Ob das aber so einfach ist kann ich nicht sagen. |
| | |
| | #11 (permalink) |
| Senior Member Themenstarter Registriert seit: 26.03.06 ![]() Likes: 16 | Hi, ich habe momentan immernoch das Workaround mit der Klasse org.apache.xmlrpc.server.AbstractReflectiveHandler Mapping am Laufen. Ich habe es so umgesetzt, dass ich das entsprechende Package einfach in meinem Projekt angelegt habe und dort eine gleichnamig Klasse erzeugt habe. Dort habe ich den Original-Code reinkopiert und die Änderungen vorgenommen. Da mein Projekt aber selbst nur eine API ist, die wiederum in einem anderen Projekt verwendet werden soll, habe ich nun folgendes Problem: Ich selbst liefere meinen Code als JAR aus plus die JARs von Apache, die ich selbst nutze. In dem anderen Projekt, werden dann alle JARs in den Classpath aufgenommen. FOLGE: meine überschriebene Version von AbstractReflectiveHandlerMapping scheint den Kürzeren zu ziehen. Stattdess wird die Klasse aus dem Apache JAR geladen. Wie löst man sowas nun am elegantesten? Und auf welche Weise krieg ich lizenzentechnisch keine Probleme? Grüße serow |
| | |
| | #12 (permalink) |
| Senior Member Themenstarter Registriert seit: 26.03.06 ![]() Likes: 16 | Hi, mensch, dass ich da nicht gleich draufgekommen bin: Code: public class MyHandlerMapping extends PropertyHandlerMapping {
private Log log = LogFactory.getLog(MyHandlerMapping.class);
public XmlRpcHandler getHandler(String pHandlerName) throws XmlRpcNoSuchHandlerException, XmlRpcException {
log.debug("somebody asked for a handler for " + pHandlerName);
XmlRpcHandler result = null;
try {
result = super.getHandler(pHandlerName);
} catch(Exception ex) {
//ignore
}
log.debug("super class methods returned " + result);
if(result == null) {
result = super.getHandler("CallbackHandler." + pHandlerName);
log.debug("asking super class method for CallbackHandler." + pHandlerName);
log.debug("result was " + result);
}
if (result == null) {
throw new XmlRpcNoSuchHandlerException("No such handler: " + pHandlerName);
}
return result;
}
} serow |
| | |
![]() |
| - Anzeige - | |
| |
| Themen-Optionen | |
| Ansicht | |
| |