| | |
| | | |
| | | package de.uhilger.transit.web; |
| | | |
| | | import javax.servlet.*; |
| | | 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 java.io.IOException; |
| | | import java.io.Writer; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.logging.Level; |
| | | import java.util.logging.Logger; |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | import javax.servlet.http.*; |
| | | |
| | | import java.io.*; |
| | | |
| | | import java.util.*; |
| | | import java.util.logging.*; |
| | | |
| | | import de.uhilger.transit.*; |
| | | |
| | | /** |
| | | * Das TransitServlet macht beliebige Klassen und Methoden |
| | | * Das TransitServletRS macht beliebige Klassen und Methoden |
| | | * ueber HTTP zugaenglich. |
| | | * |
| | | * <p><b>Achtung:</b>Das TransitServlet sollte nur in einem |
| | | * <p>Methodenaufrufe über dieses Servlet erfolgen in der Form<br> |
| | | * <code> |
| | | * http://server:port/contextpfad/servletpfad/name.der.package.Klasse/methode/antwortformat/param1/param2/../paramN |
| | | * </code></p> |
| | | * |
| | | * <p>Standardmäßig werden von Transit die Antwortformate JSON, JSONFLAT und XML |
| | | * bereitgestellt. Über die Schnittstelle Wandler lassen sich weitere Formate |
| | | * hinzufügen.</p> |
| | | * |
| | | * <p><b>Achtung:</b>Das TransitServletRS 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.</p> |
| | | * |
| | | * <p>Fuer die Bereitstellung von Funktionen ist eine Berechtigungspruefung |
| | | * noetig, die am besten in Form eines Filters implementiert wird.</p> |
| | | * noetig, die am besten in Form eines Filters implementiert wird. |
| | | * Transit stellt hierfür die Klassen Waechter und RechtePruefer bereit.</p> |
| | | * |
| | | * @author Copyright (c) Ulrich Hilger, http://uhilger.de |
| | | * @author Published under the terms and conditions of |
| | |
| | | * |
| | | * @version 1, September 16, 2012 |
| | | */ |
| | | public class TransitServletRS extends HttpServlet { |
| | | public class TransitServletRS extends AbstractServlet { |
| | | |
| | | /** Proforma Konstante fuer Schnittstelle Serializable */ |
| | | public static final long serialVersionUID = 42L; |
| | | |
| | | private static final Logger logger = Logger.getLogger(TransitServletRS.class.getName()); |
| | | |
| | | public static final String MIME_JSON = "application/json"; |
| | | public static final String MIME_XML = "text/xml"; |
| | | |
| | | private static final String[] specialChars = {new String("\u00c4"), new String("\u00d6"), |
| | | new String("\u00dc"), new String("\u00e4"), new String("\u00f6"), new String("\u00fc"), new String("\u00df")}; |
| | | |
| | | public static final String KLASSEN_TRENNER = ";"; |
| | | //private String klassen; |
| | | private String[] klassen; |
| | | |
| | | public void init(ServletConfig servletConfig) throws ServletException{ |
| | | this.klassen = servletConfig.getInitParameter("klassen").split(KLASSEN_TRENNER); |
| | | super.init(servletConfig); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Eine Anfrage via HTTP GET verarbeiten |
| | | * |
| | |
| | | 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); |
| | | if(pName.equals(CLASS_NAME)) { |
| | | klassenName = pWerte[0]; |
| | | } else if(pName.equals(METHOD_NAME)) { |
| | | methodenName = pWerte[0]; |
| | | } else if(pName.equals(FORMAT_NAME)) { |
| | | formatName = pWerte[0]; |
| | | } else { |
| | | for(int i = 0; i < pWerte.length; i++) { |
| | | parameterListe.add(pWerte[i]); |
| | | } |
| | | } |
| | | } |
| | | */ |
| | | |
| | | /* |
| | | http://server:port/contextpfad/servletpfad/de.irgend.eine.Klasse/methode/format/param1/param2/../paramN |
| | | wird zu |
| | | elemente[0] = / |
| | | elemente[1] = de.irgend.eine.Klasse |
| | | elemente[2] = methode |
| | | elemente[3] = format |
| | | elemente[4]-[n] = param1 |
| | | elemente[4]-[n] = param1 - paramn |
| | | */ |
| | | |
| | | String pathInfo = req.getPathInfo(); |
| | | logger.info("pathInfo: " + pathInfo); |
| | | logger.log(Level.INFO, "pathInfo: {0}", pathInfo); |
| | | String[] elemente = pathInfo.split("/"); |
| | | String klassenName = elemente[1]; |
| | | StringBuffer buf = new StringBuffer(); |
| | | StringBuilder buf = new StringBuilder(); |
| | | if(istErlaubt(klassenName)) { |
| | | //if(this.klassen.contains(klassenName)) { |
| | | //if(this.klassen.matches(klassenName)) { |
| | | String methodenName = elemente[2]; |
| | | String formatName = elemente[3]; |
| | | List parameterListe = new ArrayList(); |
| | |
| | | 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(Waechter.getUserName(req)); |
| | | ((NutzerKontext) o).setNutzerId(getUserName(req)); |
| | | } |
| | | if(o instanceof WebKontext) { |
| | | ((WebKontext) o).setServletContext(getServletContext()); |
| | |
| | | buf.append("<p>Ergebnis von server.klasseFinden ist null (Klasse nicht gefunden?).</p>"); |
| | | } |
| | | } else { |
| | | buf.append("<p>Klasse " + klassenName + " nicht erlaubt.</p>"); |
| | | buf.append("<p>Klasse ").append(klassenName).append(" nicht erlaubt.</p>"); |
| | | } |
| | | Writer w = resp.getWriter(); |
| | | w.write(buf.toString()); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Hier wird geprueft, ob der Name einer Klasse der Liste der erlaubten |
| | | * Klassen bzw. Packages entspricht. Im Deployment Descriptor wird ein |
| | | * Ausdruck wie z.B. |
| | | * |
| | | * de.uhilger.test.web;de.uhilger.test.api;de.uhilger.test.db.KlassenName |
| | | * |
| | | * erwartet. Diese Methode spaltet diesen Ausdruck an den ';' auf und prueft |
| | | * fuer jeden Ausdruck, ob der KlassenName mit diesem Ausdruck beginnt. |
| | | * Beginnt der Klassenname mit einem der Ausdruecke, wird der Zugriff erlaubt |
| | | * |
| | | * @param klassenName Name der Klasse, fuer die der Zugriff geprueft |
| | | * werden soll |
| | | * @return true, wenn die Klasse laut dem Eintrag im Deployment Desccriptor |
| | | * aufgerufen werden darf, false wenn nicht |
| | | */ |
| | | private boolean istErlaubt(String klassenName) { |
| | | boolean erlaubt = false; |
| | | for(int i = 0; i < klassen.length && !erlaubt; i++) { |
| | | erlaubt = klassenName.startsWith(klassen[i]); |
| | | } |
| | | return erlaubt; |
| | | } |
| | | |
| | | public String escapeHtml(String text) { |
| | | text = text.replace(specialChars[0], "Ä"); |
| | | text = text.replace(specialChars[1], "Ö"); |
| | | text = text.replace(specialChars[2], "Ü"); |
| | | text = text.replace(specialChars[3], "ä"); |
| | | text = text.replace(specialChars[4], "ö"); |
| | | text = text.replace(specialChars[5], "ü"); |
| | | text = text.replace(specialChars[6], "ß"); |
| | | return text; |
| | | } |
| | | } |