Top Menu

Jump to content
Home
    • Projects
    • Work packages
    • News
    • Getting started
    • Introduction video
      Welcome to OpenProject
      Get a quick overview of project management and team collaboration with OpenProject. You can restart this video from the help menu.

    • Help and support
    • Upgrade to Enterprise edition
    • User guides
    • Videos
    • Shortcuts
    • Community forum
    • Professional support

    • Additional resources
    • Data privacy and security policy
    • Digital accessibility (DE)
    • OpenProject website
    • Security alerts / Newsletter
    • OpenProject blog
    • Release notes
    • Report a bug
    • Development roadmap
    • Add and edit translations
    • API documentation
  • Sign in
      Create a new account
      Forgot your password?

Side Menu

  • Overview
  • News
  • Forums
  • Wiki
    • Table of contents
      • Expanded. Click to collapseCollapsed. Click to showWiki
        • Expanded. Click to collapseCollapsed. Click to showBeispielprojekte
          • Hierarchy leafFlappy Box2D
          • Hierarchy leafFlappy Improved
          • Hierarchy leafHighscore Hibernate
          • Hierarchy leafHighscore Webservice + Anbindung mit Retrofit
        • Expanded. Click to collapseCollapsed. Click to showEntwicklung mit Java
          • Hierarchy leaf001) Grundlagen - Entwicklungsumgebung
          • Hierarchy leaf002) Erstes Programm
          • Hierarchy leaf003) Variablen und Datentypen
          • Expanded. Click to collapseCollapsed. Click to show004) Schleifen
            • Hierarchy leaf1) for - Zählschleife
            • Hierarchy leaf2) while
            • Hierarchy leaf3) do while
            • Hierarchy leaf4) for each
          • Hierarchy leaf005) Arrays
          • Hierarchy leaf006) Methoden
          • Expanded. Click to collapseCollapsed. Click to show007) Objektorientierte Programmierung
            • Hierarchy leaf001) Klasse
            • Hierarchy leaf002) Vererbung und Darstellung von Klassen in UML
            • Hierarchy leaf003) Abstrakte Klasse
            • Hierarchy leaf004) Design patterns
          • Expanded. Click to collapseCollapsed. Click to show008) Webservices
            • Hierarchy leaf01) REST - Representational State Transfer
            • Hierarchy leaf02) Minimaler Webservice
            • Hierarchy leaf03) Joke Webservice
            • Hierarchy leaf04) Highscore Service
        • Expanded. Click to collapseCollapsed. Click to showMatura - Vorbereitung
          • Hierarchy leaf01) Projektmanagement
          • Hierarchy leaf02) Objektorientierte Programmierung
          • Hierarchy leaf03) Modellierung und UML
          • Expanded. Click to collapseCollapsed. Click to show04) Design Patterns
            • Hierarchy leaf00) Generelle Konzepte
            • Hierarchy leafFactory(-Method) Pattern
            • Hierarchy leafObserver Pattern
            • Hierarchy leafSingleton Pattern
            • Hierarchy leafStrategy Pattern
          • Hierarchy leaf05) Algorithmen und Datenstrukturen
          • Hierarchy leaf06) Webtechnologien
          • Hierarchy leaf07) Webservices
          • Hierarchy leaf08) Softwarequalitätsmanagement
          • Hierarchy leaf09) Softwareentwicklungsmodelle
        • Expanded. Click to collapseCollapsed. Click to showProjekt Rahmenbedingungen
          • Expanded. Click to collapseCollapsed. Click to showRetrospektive
            • Hierarchy leafRetro - [Name Schüler_in]
        • Hierarchy leafReact Native
        • Expanded. Click to collapseCollapsed. Click to showÜbungen
          • Hierarchy leaf1) Basic
          • Expanded. Click to collapseCollapsed. Click to show2) Basic
            • Hierarchy leaf001) Methode ohne Rückabewert mit Parametern
            • Hierarchy leaf002) Methode mit Parametern und Rückgabewert
            • Hierarchy leaf003) Text umdrehen
            • Hierarchy leaf004) Text umdrehen 2
            • Hierarchy leaf005) Kommandozeile
            • Hierarchy leaf006) Kommandozeile 2
            • Hierarchy leaf007) Vererbung - Geometry
            • Hierarchy leaf008) File from String
            • Hierarchy leaf009) Rekursion - Summe
            • Hierarchy leaf010) Rekursion - File
          • Expanded. Click to collapseCollapsed. Click to showDatenstrukturen
            • Hierarchy leaf011) Binärbaum
            • Hierarchy leaf012) Binärbaum - Generics
            • Hierarchy leaf013) AVL - Tree
            • Hierarchy leaf014) Linked List - Einfach verkettete Liste
            • Hierarchy leaf015) Graph
            • Hierarchy leaf016) Dijkstras shortest path first
          • Expanded. Click to collapseCollapsed. Click to showJava - Kara
            • Hierarchy leafKara lernt schreiben
You are here:
  • Wiki
  • Entwicklung mit Java
  • 008) Webservices
  • 03) Joke Webservice

Content

03) Joke Webservice

  • More
    • Print
    • Table of contents

Komplexeres Beispiel Jokewebservice

Für den Jokewebservice kann einfach das Minimalbeispiel erweitert werden.

Der Jokewebservice findet sich in kompletter Ausführung hier: Joke Webservice

NPM

Npm ist der node package manager. Mit dem Befehl npm install [Packetname] kann ein node.js Modul installiert werden.

package.json

Um die Abhängigkeiten des Projekts zu speichern muss die Datei package.json mit npm init erstellt werden. Es sind noch zusätzliche Metadaten wie z.b.: App Version, Beschreibung, uws. enthalten.

Alle nach der initialisierung installierten Module werden in der Date package.json mit Versionscode abgespeichert.

Wird nun das Projekt neu ausgecheckt werden alle Abhängigkeiten mit npm install installiert.

Express

npm install express

Express ist ein Webservice Router, http requests werden an die entsprechenden Routen weitergeleitet.

GET/DELETE/PUT/POST Methoden mit Express

app.get('/', function(req, res) { res.send("Get request"); });

app.delete('/', function(req, res) { res.send("Delete request"); });

app.put('/', function(req, res) { res.send("Put request"); });

app.post('/', function(req, res) { res.send("Post request"); });

CURL Befehle:

curl localhost:3000
#put
curl -X PUT localhost:3000
#put
curl -X DELETE localhost:3000
#put
curl -X POST localhost:3000

Nodemon

npm install -g nodemon

Mit nodemon kann ein node.js Programm gestartet werden. Wird die gestartete Datei verändert, lädt nodemon diese automatisch neu.

Mongoose

Mongoose ist ein Framework um Schemas für MongoDB zu erstellen. Es inkludiert Abfragen, Validierung,...und natürlich die Verbindung zur Datenbank

npm install mongoose

Anbindung der Datenbank in app.js

//Mongoose modul importieren
var mongoose = require('mongoose');
//Verbinden mit Datenbank
mongoose.connect('mongodb://testuser:testpwd@mongodb.drlue.at:9000/testdb?ssl=true&authMechnism=DEFAULT&authSource=authdb');
//Datenbankverbindung holen
var db = mongoose.connection;
//Fehlerausgabe
db.on('error', console.error.bind(console, "MongoDB connection error:"));
//Ausgabe bei erfolgreicher Verbindung
db.once('open', () => {
  console.log("Connected...");
});

Beispiel Schema (model/joke.js)

const mongoose = require('mongoose');
const schema = mongoose.Schema;

var jokeSchema = new schema({
    text: { type: String },
    author: { type: String },
    created_at: { type: Date, default: Date.now }
});
//Export the schema
module.exports = mongoose.model('Joke', jokeSchema);

Erstellen/Löschen von Einträgen in der Datenbank app.js

//Schema importieren
var Joke = require('model/joke');

app.get('/', function (req, res) {
//Alle Einträge zurückgeben
  Joke.find({})
    .then((jokes) => {
        res.json(jokes);
    })
    .catch((error) => {
      res.send("FEHLER: " + error.msg);
    })
});

//Eintrag anhand der ID löschen
app.get('/:id/delete', function (req, res) {
  Joke.findOneAndDelete({ _id: req.params.id })
    .then((result) => {
      res.send("Deleted");
    })
    .catch((error) => {
      res.send("FEHLER: " + error.msg);
    });
});

Mustache

npm install mustache-express

Mustache ist ein template rendering engine. Wir schreiben HTML Code, und können dort Platzhalter einfügen.

views/jokes.mustache

{{#jokes}}
    <div class="badge badge-info">{{author}}</div> - {{text}}
{{/jokes}}

Verwenden des Templates in app.js

var mustacheExpress = require('mustache-express');
app.set('views', './views/');
app.set('view engine', 'mustache');
app.engine('mustache', mustacheExpress());

app.get('/', function (req, res) {
  Joke.find({})
    .then((jokes) => {
        //Hier wird das Template joke.mustache verwendet
        //Wenn im Template Parameter benötigt werden, so werden diese als JSON übergeben
        res.render('joke', { jokes: jokes });
    }).catch((error) => {
      res.send("FEHLER: " + error.msg);
    })
});

Neuen Joke eintragen

Jokes sollen nun über eine HTML Webseite und auch direkt, z.b.: mit curl eingetragen werden können. Um je nach Client Anwendung unterschiedliche Aktionen auszuführen, müssen die Clients die entsprechenden Header mitsenden. Werden Daten nur geholt, so ist der Accept Header wichtig. Dieser beschreibt was der Client gerne hätte:

#Ich möchte eine Webseite
Accept: text/html
#Ich möchte JSON
Accept: application/json

Werden Daten gesendet, so ist der Content-Type Header wichtig. Dieser beschreibt in welchem Format der Client seine Daten sendet:

#Browser sendet Textdaten von einem Formular
Content-Type: x-www-form-urlencoded
#Senden von JSON Daten über eine Anwendung
Content-Type: application/json

Um Daten von POST oder PUT Requests zu erhalten muss folgendes in app.js nach der initialisierung von express() eingetragen werden. Nach dem eintragen kann auf die Werte in gleicherweise zugegriffen werden (egal ob Daten vom Browser oder von einer Anwendung):

//Aktiviert Content-Type: x-www-form-urlencoded
app.use(express.urlencoded());
////Aktiviert Content-Type: application/json
app.use(express.json());

Mustache Datei für das Formular views/joke_create.mustache:

...
<form action="/" id="person" method="post">
    <label class="h2" form="person">Erstellung eines Witzes</label>
    <label for="vorname">Name des Autoren</label> 
    <input type="text" name="vorname" id="vorname">
    <label for="text">Eingabe des Jokes</label>  
    <input type="text" name="text" id="text">
    <button type="submit">Eingaben absenden</button>
</form>
...

Neue Routen in app.js

//Route für das Formular
app.get('/create', function(req, res) {
  res.render("joke_create");
});

//Route für das Eintragen
app.post('/', function (req, res) {
  Joke.create({ text: req.body.text, author: req.body.author })
    .then((result) => {
      if (req.accepts('text/html')) {
        res.redirect('/'); //Aufruf von Browser
      } else {
        res.json(result); //Aufruf von jemandem der kein text/html akzeptiert
      }
    })
    .catch((error) => {
      if (req.accepts('text/html')) {
        res.redirect('/'); //Aufruf von Browser
      } else {
        res.json({ error: "could not create joke" }); //Aufruf von jemandem der kein text/html akzeptiert
      }
    });
});

Einen Witz über curl eintragen

curl -H "Accept: application/json" -H "Content-Type: application/json" -d '{ "author": "lukas", "text": "das ist ein witz" }' -X POST localhost:3000/

Editieren eines Witzes

Neues Mustache file editjoke.mustache

Achtung {{[value]}} kommt aus dem JSON das dem renderer übergeben wurde.

<form action="/{{_id}}" method="post">
    <label class="h2 breit" form="person">Ändern eines Witzes</label><br><br>
    <label for="lName">Name des Autoren:</label>
    <input type="Author" name="author" id="author" value="{{author}}"><br>
    <label for="lWitz">Eingabe des Jokes:</label>  
    <input class="breit" type="Text" name="text" id="text" value="{{text}}"><br><br>
    <button type="submit">Änderung absenden</button>
</form>

Neue Route in app.js

Die Werte aus dem Formular beziehen sich auf den name des Html Elements.

app.post('/:id', function (req, res) {
	Joke.findByIdAndUpdate(req.params.id, { author: req.body.author, text: req.body.text })
    .then((result) => { 
    	if (req.accepts('text/html')) {
        	res.redirect('/');
        } else { 
        	res.json(result);
        }
    }).catch((error) => {
    	if (req.accepts('text/html')) { 
        	res.redirect('/');
        } else {
        	res.json({ error: "could not create joke" });
        }
     });
});
```

## Joke löschen über Javascript **fetch** api

**views/joke.mustache**

Der Joke wird über die Fetch Api gelöscht, es entsteht kein neuer Seitenaufruf. Wurde der Witz erfolgreich gelöscht, so wird das Html Element aus dem DOM (Document Object Model) entfernt.

```html
<script>
	var del = (id) => {
	fetch(id,{
		method: 'delete'
	})
	.then(function (result) {
		if(result.status == 200){
			window.alert("Ok")
			document.getElementById(id).remove()
		} else if(result.status == 500){
			window.alert("Interner Serverfehler")
		} else {
			window.alert("Could not been found")
		}
		console.log(result);
	})
	.catch(function (error) {
		console.log(error);
	})
}
</script>
...
<a class= "btn-inline btn btn-danger btn-sm" onclick="del('{{_id}}')">Delete</a>
...

Neue Route in app.js

Diese entspricht bis auf den Pfad der get :id/delete Route.

//Delete joke
app.delete('/:id', function (req, res) {
  Joke.findOneAndDelete({ _id: req.params.id })
    .then((result) => {
      if (result == null) {
        //Joke wurde nicht gefunden
        res.sendStatus(404);
      } else {
        //Joke wurde erfolgreich gelöscht
        res.sendStatus(200);
      }
      console.log("Successfully deleted...");

    })
    .catch((error) => {
      console.log("Failes to delete...");
      res.sendStatus(500);
    })
});
Loading...