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