/* Transit - Remote procedure calls made simple Copyright (c) 2012 Ulrich Hilger This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package de.uhilger.transit.web; import de.uhilger.transit.JavaServer; import de.uhilger.transit.JsonFlatWandler; import de.uhilger.transit.JsonNiceWandler; import de.uhilger.transit.JsonWandler; import de.uhilger.transit.NutzerKontext; import de.uhilger.transit.XmlWandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.Writer; import java.util.Enumeration; import java.util.ArrayList; import java.util.List; /** * Das TransitServlet macht beliebige Klassen und Methoden ueber HTTP * zugaenglich. * *

* Achtung:Das TransitServlet sollte nur in einem per Authentifizierung * und Autorisierung geschuetzten Bereich einer Webanwendung bereitgestellt * werden da andernfalls durchweg alle Klassen und Methoden, die sich auf dem * Server finden, zugaenglich werden.

* *

* Fuer die Bereitstellung von Funktionen ist eine Berechtigungspruefung noetig, * die am besten in Form eines Filters implementiert wird.

* * @author Copyright (c) Ulrich Hilger, http://uhilger.de * @author Published under the terms and conditions of the * GNU Affero * General Public License * * @version 1, September 16, 2012 */ public class TransitServlet extends AbstractServlet { /** * Proforma Konstante fuer Schnittstelle Serializable */ public static final long serialVersionUID = 42L; /** * Name des Parameters Klasse */ public static final String CLASS_NAME = "c"; /** * Name des Parameters Methode */ public static final String METHOD_NAME = "m"; /** * Name des Parameters Parameter */ public static final String PARAMETER_NAME = "p"; /** * Name des Parameters Format */ public static final String FORMAT_NAME = "f"; /** * Eine Anfrage via HTTP GET verarbeiten * *

* Folgende Parameter werden erwartet:

*

* c: Klasse, z.B. de.uhilger.test.EineKlasse
* m: Methode
* p: Erster Parameter der Methode in der Reihenfolge der Deklaration
* p: Zweiter Parameter der Methode in der Reihenfolge der Deklaration
* . *
* . *
* p: Letzter Parameter der Methode in der Reihenfolge der Deklaration

* *

* Das Ergebnis der Verarbeitung wird in Form einer Zeichenkette im Format der * JavaScript Object Notation (JSON) in die Antwort der HTTP-Anfrage * geschrieben.

* * @param req die Anfrage, die verarbeitet werden soll * @param resp das Objekt, mit dem das Ergebnis der Verarbeitung mitgeteilt * wird */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { anfrageAusfuehren(req, resp); } /** * Eine Anfrage via HTTP POST verarbeiten * *

* Folgende Parameter werden erwartet:

*

* c: Klasse, z.B. de.uhilger.test.EineKlasse
* m: Methode
* p: Erster Parameter der Methode in der Reihenfolge der Deklaration
* p: Zweiter Parameter der Methode in der Reihenfolge der Deklaration
* . *
* . *
* p: Letzter Parameter der Methode in der Reihenfolge der Deklaration

* *

* Das Ergebnis der Verarbeitung wird in Form einer Zeichenkette im Format der * JavaScript Object Notation (JSON) in die Antwort der HTTP-Anfrage * geschrieben.

* * @param req die Anfrage, die verarbeitet werden soll * @param resp das Objekt, mit dem das Ergebnis der Verarbeitung mitgeteilt * wird */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { anfrageAusfuehren(req, resp); } /** * Diese Methode verarbeitet die Anfragen, die via HTTP GET und HTTP POST an * dieses Servlet gestellt werden. * * @param req die Anfrage, die verarbeitet werden soll * @param resp das Objekt, mit dem das Ergebnis der Verarbeitung mitgeteilt * wird */ @SuppressWarnings("unchecked") public void anfrageAusfuehren(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { JavaServer server = null; try { String klassenName = null; String methodenName = null; List parameterListe = new ArrayList(); String formatName = null; Enumeration en = req.getParameterNames(); while (en.hasMoreElements()) { String pName = en.nextElement().toString(); String[] pWerte = req.getParameterValues(pName); switch (pName) { case CLASS_NAME: klassenName = pWerte[0]; break; case METHOD_NAME: methodenName = pWerte[0]; break; case FORMAT_NAME: formatName = pWerte[0]; break; default: for (String pWert : pWerte) { parameterListe.add(pWert); } break; } } Object[] parameter = parameterListe.toArray(new Object[0]); StringBuilder buf = new StringBuilder(); if (istErlaubt(klassenName)) { server = new JavaServer(); server.wandlerHinzufuegen(new JsonWandler()); server.wandlerHinzufuegen(new JsonFlatWandler()); server.wandlerHinzufuegen(new JsonNiceWandler()); server.wandlerHinzufuegen(new XmlWandler()); Class cls = server.klasseFinden(klassenName); if (cls != null) { Object o = cls.newInstance(); if (o != null) { if (o instanceof NutzerKontext) { ((NutzerKontext) o).setNutzerId(getUserName(req)); } if (o instanceof WebKontext) { ((WebKontext) o).setServletContext(getServletContext()); } if (o instanceof RequestKontext) { ((RequestKontext) o).setRequest(req); } if (o instanceof VerbindungsKontext) { ((VerbindungsKontext) o).setVerbindung(req.getSession()); } } Object resultat = null; if (formatName != null) { resultat = server.methodeAusfuehren(o, methodenName, formatName, parameter); } else { resultat = server.methodeAusfuehren(o, methodenName, JsonWandler.FORMAT_JSON, parameter); } if (resultat != null) { if (formatName == null) { resp.setContentType(MIME_JSON); } else { if (formatName.equalsIgnoreCase(JsonWandler.FORMAT_JSON) || formatName.equalsIgnoreCase(JsonFlatWandler.FORMAT_FLATJSON)) { resp.setContentType(MIME_JSON); } else if (formatName.equalsIgnoreCase(XmlWandler.FORMAT_XML)) { resp.setContentType(MIME_XML); } } buf.append(escapeHtml(resultat.toString())); } else { buf.append("

Resultat von server.methodeAusfuehren ist null.

"); } } else { buf.append("

Ergebnis von server.klasseFinden ist null (Klasse nicht gefunden?).

"); } } else { buf.append("

Klasse " + klassenName + " nicht erlaubt.

"); } Writer w = resp.getWriter(); w.write(buf.toString()); w.flush(); w.close(); } catch (Exception ex) { throw new ServletException(ex); } finally { if (server != null) { server.aufloesen(); server = null; } } } }