Java Web Services via REST bereitstellen
ulrich
2016-12-27 2c72f85fed2d2001335bcaffccebcc2c9f0dc123
commit | author | age
ca8e1e 1 /*
1da1ca 2  Transit - Remote procedure calls made simple
U 3  Copyright (c) 2012  Ulrich Hilger
ca8e1e 4
1da1ca 5  This program is free software: you can redistribute it and/or modify
U 6  it under the terms of the GNU Affero General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
ca8e1e 9
1da1ca 10  This program is distributed in the hope that it will be useful,
U 11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU Affero General Public License for more details.
ca8e1e 14
1da1ca 15  You should have received a copy of the GNU Affero General Public License
U 16  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
ca8e1e 18 package de.uhilger.transit.web;
U 19
3f6c85 20 import de.uhilger.transit.JavaServer;
U 21 import de.uhilger.transit.JsonFlatWandler;
87f8e9 22 import de.uhilger.transit.JsonNiceWandler;
3f6c85 23 import de.uhilger.transit.JsonWandler;
U 24 import de.uhilger.transit.NutzerKontext;
25 import de.uhilger.transit.XmlWandler;
ca8e1e 26 import javax.servlet.ServletException;
U 27
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30
31 import java.io.IOException;
32 import java.io.Writer;
33
34 import java.util.Enumeration;
35 import java.util.ArrayList;
36 import java.util.List;
37
38
39 /**
1da1ca 40  * Das TransitServlet macht beliebige Klassen und Methoden ueber HTTP
U 41  * zugaenglich.
42  *
43  * <p>
44  * <b>Achtung:</b>Das TransitServlet sollte nur in einem per Authentifizierung
45  * und Autorisierung geschuetzten Bereich einer Webanwendung bereitgestellt
46  * werden da andernfalls durchweg alle Klassen und Methoden, die sich auf dem
47  * Server finden, zugaenglich werden.</p>
48  *
49  * <p>
50  * Fuer die Bereitstellung von Funktionen ist eine Berechtigungspruefung noetig,
51  * die am besten in Form eines Filters implementiert wird.</p>
52  *
ca8e1e 53  * @author Copyright (c) Ulrich Hilger, http://uhilger.de
1da1ca 54  * @author Published under the terms and conditions of the
U 55  * <a href="http://www.gnu.org/licenses/agpl-3.0" target="_blank">GNU Affero
56  * General Public License</a>
57  *
ca8e1e 58  * @version 1, September 16, 2012
U 59  */
1da1ca 60 public class TransitServlet extends AbstractServlet {
ca8e1e 61
1da1ca 62   /**
U 63    * Proforma Konstante fuer Schnittstelle Serializable
64    */
ca8e1e 65   public static final long serialVersionUID = 42L;
1da1ca 66
U 67   /**
68    * Name des Parameters Klasse
69    */
ca8e1e 70   public static final String CLASS_NAME = "c";
1da1ca 71   /**
U 72    * Name des Parameters Methode
73    */
ca8e1e 74   public static final String METHOD_NAME = "m";
1da1ca 75   /**
U 76    * Name des Parameters Parameter
77    */
ca8e1e 78   public static final String PARAMETER_NAME = "p";
1da1ca 79   /**
U 80    * Name des Parameters Format
81    */
ca8e1e 82   public static final String FORMAT_NAME = "f";
1da1ca 83
ca8e1e 84   /**
U 85    * Eine Anfrage via HTTP GET verarbeiten
1da1ca 86    *
U 87    * <p>
88    * Folgende Parameter werden erwartet:</p>
89    * <p>
90    * c: Klasse, z.B. de.uhilger.test.EineKlasse<br>
ca8e1e 91    * m: Methode<br>
U 92    * p: Erster Parameter der Methode in der Reihenfolge der Deklaration<br>
93    * p: Zweiter Parameter der Methode in der Reihenfolge der Deklaration<br>
1da1ca 94    * .
U 95    * <br>
96    * .
97    * <br>
ca8e1e 98    * p: Letzter Parameter der Methode in der Reihenfolge der Deklaration</p>
1da1ca 99    *
U 100    * <p>
101    * Das Ergebnis der Verarbeitung wird in Form einer Zeichenkette im Format der
102    * JavaScript Object Notation (JSON) in die Antwort der HTTP-Anfrage
103    * geschrieben.</p>
104    *
ca8e1e 105    * @param req die Anfrage, die verarbeitet werden soll
1da1ca 106    * @param resp das Objekt, mit dem das Ergebnis der Verarbeitung mitgeteilt
U 107    * wird
ca8e1e 108    */
U 109   @Override
110   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
111     anfrageAusfuehren(req, resp);
112   }
1da1ca 113
ca8e1e 114   /**
U 115    * Eine Anfrage via HTTP POST verarbeiten
1da1ca 116    *
U 117    * <p>
118    * Folgende Parameter werden erwartet:</p>
119    * <p>
120    * c: Klasse, z.B. de.uhilger.test.EineKlasse<br>
ca8e1e 121    * m: Methode<br>
U 122    * p: Erster Parameter der Methode in der Reihenfolge der Deklaration<br>
123    * p: Zweiter Parameter der Methode in der Reihenfolge der Deklaration<br>
1da1ca 124    * .
U 125    * <br>
126    * .
127    * <br>
ca8e1e 128    * p: Letzter Parameter der Methode in der Reihenfolge der Deklaration</p>
1da1ca 129    *
U 130    * <p>
131    * Das Ergebnis der Verarbeitung wird in Form einer Zeichenkette im Format der
132    * JavaScript Object Notation (JSON) in die Antwort der HTTP-Anfrage
133    * geschrieben.</p>
134    *
ca8e1e 135    * @param req die Anfrage, die verarbeitet werden soll
1da1ca 136    * @param resp das Objekt, mit dem das Ergebnis der Verarbeitung mitgeteilt
U 137    * wird
ca8e1e 138    */
U 139   @Override
140   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
141     anfrageAusfuehren(req, resp);
142   }
1da1ca 143
ca8e1e 144   /**
1da1ca 145    * Diese Methode verarbeitet die Anfragen, die via HTTP GET und HTTP POST an
U 146    * dieses Servlet gestellt werden.
147    *
ca8e1e 148    * @param req die Anfrage, die verarbeitet werden soll
1da1ca 149    * @param resp das Objekt, mit dem das Ergebnis der Verarbeitung mitgeteilt
U 150    * wird
ca8e1e 151    */
U 152   @SuppressWarnings("unchecked")
153   public void anfrageAusfuehren(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
154     JavaServer server = null;
155     try {
156       String klassenName = null;
157       String methodenName = null;
158       List parameterListe = new ArrayList();
159       String formatName = null;
160       Enumeration en = req.getParameterNames();
1da1ca 161       while (en.hasMoreElements()) {
ca8e1e 162         String pName = en.nextElement().toString();
U 163         String[] pWerte = req.getParameterValues(pName);
3f6c85 164         switch (pName) {
U 165           case CLASS_NAME:
166             klassenName = pWerte[0];
167             break;
168           case METHOD_NAME:
169             methodenName = pWerte[0];
170             break;
171           case FORMAT_NAME:
172             formatName = pWerte[0];
173             break;
174           default:
175             for (String pWerte1 : pWerte) {
176               parameterListe.add(pWerte1);
177             } break;
ca8e1e 178         }
U 179       }
180       Object[] parameter = parameterListe.toArray(new Object[0]);
1da1ca 181       StringBuilder buf = new StringBuilder();
U 182       if (istErlaubt(klassenName)) {
183         server = new JavaServer();
184         server.wandlerHinzufuegen(new JsonWandler());
185         server.wandlerHinzufuegen(new JsonFlatWandler());
87f8e9 186         server.wandlerHinzufuegen(new JsonNiceWandler());
1da1ca 187         server.wandlerHinzufuegen(new XmlWandler());
U 188         Class cls = server.klasseFinden(klassenName);
189         if (cls != null) {
190           Object o = cls.newInstance();
191           if (o != null) {
192             if (o instanceof NutzerKontext) {
193               ((NutzerKontext) o).setNutzerId(getUserName(req));
194             }
195             if (o instanceof WebKontext) {
196               ((WebKontext) o).setServletContext(getServletContext());
197             }
198             if (o instanceof RequestKontext) {
199               ((RequestKontext) o).setRequest(req);
200             }
201             if (o instanceof VerbindungsKontext) {
202               ((VerbindungsKontext) o).setVerbindung(req.getSession());
ca8e1e 203             }
U 204           }
1da1ca 205           Object resultat = null;
U 206           if (formatName != null) {
207             resultat = server.methodeAusfuehren(o, methodenName, formatName, parameter);
208           } else {
209             resultat = server.methodeAusfuehren(o, methodenName, JsonWandler.FORMAT_JSON, parameter);
210           }
211           if (resultat != null) {
212             if (formatName == null) {
213               resp.setContentType(MIME_JSON);
214             } else {
215               if (formatName.equalsIgnoreCase(JsonWandler.FORMAT_JSON) || formatName.equalsIgnoreCase(JsonFlatWandler.FORMAT_FLATJSON)) {
216                 resp.setContentType(MIME_JSON);
217               } else if (formatName.equalsIgnoreCase(XmlWandler.FORMAT_XML)) {
218                 resp.setContentType(MIME_XML);
219               }
220             }
221             buf.append(escapeHtml(resultat.toString()));
222           } else {
223             buf.append("<p>Resultat von server.methodeAusfuehren ist null.</p>");
224           }
ca8e1e 225         } else {
1da1ca 226           buf.append("<p>Ergebnis von server.klasseFinden ist null (Klasse nicht gefunden?).</p>");
ca8e1e 227         }
U 228       } else {
1da1ca 229         buf.append("<p>Klasse " + klassenName + " nicht erlaubt.</p>");
ca8e1e 230       }
U 231       Writer w = resp.getWriter();
232       w.write(buf.toString());
233       w.flush();
234       w.close();
1da1ca 235     } catch (Exception ex) {
ca8e1e 236       throw new ServletException(ex);
U 237     } finally {
1da1ca 238       if (server != null) {
ca8e1e 239         server.aufloesen();
U 240         server = null;
241       }
242     }
243   }
1da1ca 244
U 245 }