diff --git a/lib/classes/JsonApi/Middlewares/Language.php b/lib/classes/JsonApi/Middlewares/Language.php
index 4cde6997357069d4fa57f02a90d2a3520205bf9f..547e9f04e2f9657beb5bc61e8ec5fbc7a810b7f5 100644
--- a/lib/classes/JsonApi/Middlewares/Language.php
+++ b/lib/classes/JsonApi/Middlewares/Language.php
@@ -4,6 +4,7 @@ namespace JsonApi\Middlewares;
 use Negotiation\LanguageNegotiator;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\MiddlewareInterface;
 use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
 
 /**
@@ -12,7 +13,7 @@ use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
  *
  * @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
  */
-class Language
+final class Language implements MiddlewareInterface
 {
     /**
      * @param Request        $request das Request-Objekt
@@ -20,79 +21,13 @@ class Language
      *
      * @return ResponseInterface das neue Response-Objekt
      */
-    public function __invoke(Request $request, RequestHandler $handler)
+    public function process(Request $request, RequestHandler $handler): ResponseInterface
     {
-        $language = $this->detectValidLanguageFromRequest($request);
-        $language_before = false;
+        $language = $_SESSION['_language'] ?? get_accepted_languages($request);
 
-        // Set language if detected
-        if ($language) {
-            $language_before = $_SESSION['_language'];
-            $_SESSION['_language'] = $language;
-            setTempLanguage(false, $language);
-        }
+        init_i18n($language);
+        $_SESSION['_language'] = $language;
 
-        $response =  $handler->handle($request);
-
-        if ($language) {
-            $_SESSION['_language'] = $language_before;
-            restoreLanguage();
-        }
-
-        return $response;
-    }
-
-    /**
-     * Tries to detect a valid installed language from the request.
-     *
-     * @param Request $request
-     * @return string|null The detected language (if any)
-     */
-    private function detectValidLanguageFromRequest(Request $request): ?string
-    {
-        if (!$request->hasHeader('Accept-Language')) {
-            return null;
-        }
-
-        $negotiator = new LanguageNegotiator();
-        $best_language = $negotiator->getBest(
-            $request->getHeaderLine('Accept-Language'),
-            $this->getStudIPLanguagePriorities()
-        );
-
-        if (!$best_language) {
-            return null;
-        }
-
-        return $this->normalizeLanguageForStudIP($best_language->getType());
-    }
-
-    /**
-     * Returns a list of the normalized installed languages for the Stud.IP
-     * system.
-     *
-     * @return array
-     */
-    private function getStudIPLanguagePriorities(): array
-    {
-        return array_map(
-            function ($language) {
-                return str_replace('_', '-', $language);
-            },
-            array_keys($GLOBALS['INSTALLED_LANGUAGES'])
-        );
-    }
-
-    /**
-     * Normalizes the given language string (<language>-<variety>, e.g. de-de)
-     * for Stud.IP (e.g. de_DE).
-     *
-     * @param string $language
-     * @return string
-     */
-    private function normalizeLanguageForStudIP(string $language): string
-    {
-        $tags = explode('-', $language);
-        return $tags[0] . '_' . strtoupper($tags[1]);
+        return $handler->handle($request);
     }
 }
diff --git a/lib/classes/JsonApi/middleware.php b/lib/classes/JsonApi/middleware.php
index f65231c886184106d15a54f1a4a9b68df63f84cd..e00b41bf55f1088a555057808e4abd9996b92b67 100644
--- a/lib/classes/JsonApi/middleware.php
+++ b/lib/classes/JsonApi/middleware.php
@@ -27,7 +27,7 @@ return function (App $app) {
     $app->addRoutingMiddleware();
 
     // Add language middleware
-    $app->add(new Middlewares\Language());
+    $app->add(Middlewares\Language::class);
 
     /** @var array|null */
     $corsOrigin = \Config::get()->getValue('JSONAPI_CORS_ORIGIN');
diff --git a/lib/language.inc.php b/lib/language.inc.php
index 2168d1612945b077ff5a8a869aff871501ebb6e8..fbe847175548f7789cf4a33d32c3196834074723 100644
--- a/lib/language.inc.php
+++ b/lib/language.inc.php
@@ -35,7 +35,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // +---------------------------------------------------------------------------+
-
+use Negotiation\AcceptHeader;
 
 /**
 * This function tries to find the preferred language
@@ -47,22 +47,38 @@
 * @return       string  preferred user language, given in "en_GB"-style
 *
 */
-function get_accepted_languages() {
-    global $INSTALLED_LANGUAGES;
-
-    $_language = Config::get()->DEFAULT_LANGUAGE;
-    $accepted_languages = explode(",", getenv("HTTP_ACCEPT_LANGUAGE"));
-    if (is_array($accepted_languages) && count($accepted_languages)) {
-        foreach ($accepted_languages as $temp_accepted_language) {
-            foreach ($INSTALLED_LANGUAGES as $temp_language => $temp_language_settings) {
-                if (mb_substr(trim($temp_accepted_language), 0, 2) == mb_substr($temp_language, 0, 2)) {
-                    $_language = $temp_language;
-                    break 2;
-                }
-            }
-        }
+function get_accepted_languages(Psr\Http\Message\RequestInterface $request = null) {
+    $accepted_languages = null;
+    if ($request === null) {
+        $accepted_languages = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
+    } elseif ($request->hasHeader('Accept-Language')) {
+        $accepted_languages = $request->getHeaderLine('Accept-Language');
+    }
+
+    // No languages found from http header, set default
+    if (!$accepted_languages) {
+        return Config::get()->DEFAULT_LANGUAGE;
     }
-    return $_language;
+
+    // Use negotiator to identify best match
+    $negotiator = new Negotiation\LanguageNegotiator();
+    $best_language = $negotiator->getBest(
+        $accepted_languages,
+        array_map(
+            function ($language) {
+                return str_replace('_', '-', $language);
+            },
+            array_keys($GLOBALS['INSTALLED_LANGUAGES'])
+        )
+    );
+
+    // No best match, set default
+    if (!$best_language) {
+        return Config::get()->DEFAULT_LANGUAGE;
+    }
+
+    // Normalize language definition for stud.ip
+    return $best_language->getBasePart() . '_' . strtoupper($best_language->getSubPart());
 }
 
 
@@ -192,7 +208,7 @@ function restoreLanguage() {
 * @access   public
 */
 function setLocaleEnv($language, $language_domain = ''){
-    putenv('LANGUAGE'); //unset language preference 
+    putenv('LANGUAGE'); //unset language preference
     $ret = setlocale(LC_ALL, $language . '.UTF-8');
     setlocale(LC_NUMERIC, 'C');
     if ($language_domain) {