From 0d3cabf85758122934d329330a4ad8e1ce1e90f6 Mon Sep 17 00:00:00 2001 From: Sebastian Hofmann Date: Mon, 15 Apr 2024 11:23:05 +0200 Subject: [PATCH] Migrate to MCRVueRootServlet in mycore --- .../org/mycore/vue/MCRVueRootServlet.java | 143 ------------------ src/main/resources/META-INF/web-fragment.xml | 2 +- src/main/vue/modul_handbuecher/yarn.lock | 6 +- 3 files changed, 4 insertions(+), 147 deletions(-) delete mode 100644 src/main/java/org/mycore/vue/MCRVueRootServlet.java diff --git a/src/main/java/org/mycore/vue/MCRVueRootServlet.java b/src/main/java/org/mycore/vue/MCRVueRootServlet.java deleted file mode 100644 index 72482d86..00000000 --- a/src/main/java/org/mycore/vue/MCRVueRootServlet.java +++ /dev/null @@ -1,143 +0,0 @@ -package org.mycore.vue; - -import org.jdom2.Element; -import org.jdom2.JDOMException; -import org.jdom2.Namespace; -import org.jdom2.input.SAXBuilder; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Entities; -import org.mycore.common.MCRException; -import org.mycore.common.content.MCRContent; -import org.mycore.common.content.MCRJDOMContent; -import org.mycore.common.content.MCRURLContent; -import org.mycore.frontend.MCRFrontendUtil; -import org.mycore.frontend.servlets.MCRContentServlet; -import org.xml.sax.SAXException; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import javax.xml.transform.TransformerException; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -/** - *

This Servlet can be bound to a URL where a Vue Build App with a createWebHistory() router is present.

- * - * <servlet>
- *   <servlet-name>MCRVueRootServlet</servlet-name>
- *   <servlet-class>org.mycore.webtools.vue.MCRVueRootServlet</servlet-class>
- * </servlet>
- * <servlet-mapping>
- *   <servlet-name>MCRVueRootServlet</servlet-name>
- *   <url-pattern>/handbuecher/*</url-pattern>
- * </servlet-mapping>
- *
- *

It will pass through resources that exists at this path like javascript and css, but at every other path it will - * deliver a modified version of the index.html. - * The index.html is convert to xhtml and then will be wrapped with a MyCoReWebPage, which will produce the surrounding - * default layout.

- *

In the example the vue app is located in: src/main/vue/modul_handbuecher

- *

The Router needs to be configured like this:

- * - * function getContext() {
- *   const el = document.createElement('a');
- *   el.href = (<any>window).webApplicationBaseURL;
- *   return el.pathname;
- * }
- * const router = createRouter({
- *   history: createWebHistory(getContext() + "handbuecher/"),
- *   routes
- * }) - *
- *

The String "handbuecher/" is the location of the vue app below the java application context.

- *

To change the output destination of the vue compiler process you need to change the vue.config.js

- * - * const { defineConfig } = require('@vue/cli-service')
- * module.exports = defineConfig({
- *   transpileDependencies: true,
- *   outputDir: "../../../../target/classes/META-INF/resources/handbuecher",
- *   publicPath: "./"
- * });
- *
- */ -public class MCRVueRootServlet extends MCRContentServlet { - - @Override - public MCRContent getContent(HttpServletRequest req, HttpServletResponse resp) throws IOException { - String pathInfo = req.getPathInfo(); - String indexHtmlPath = req.getServletPath() + "/index.html"; - URL resource = getServletContext().getResource(req.getServletPath() + pathInfo); - - if (resource != null && !pathInfo.endsWith("/") && !pathInfo.endsWith("index.html")) { - return new MCRURLContent(resource); - } else { - URL indexResource = getServletContext().getResource(indexHtmlPath); - org.jdom2.Document mycoreWebpage = getIndexDocument(indexResource, - MCRFrontendUtil.getBaseURL() + removeLeadingSlash(req.getServletPath())); - if (pathInfo != null && pathInfo.endsWith("/404")) { - /* if there is a requested route which does not exist, the app should - * redirect to this /404 route the get the actual 404 Code. - * see also https://www.youtube.com/watch?v=vjj8B4sq0UI&t=1815s - * */ - resp.setStatus(404); - } - try { - return getLayoutService().getTransformedContent(req, resp, new MCRJDOMContent(mycoreWebpage)); - } catch (TransformerException | SAXException e) { - throw new IOException(e); - } - } - } - - private String removeLeadingSlash(String sp) { - return sp.startsWith("/") ? sp.substring(1) : sp; - } - - private org.jdom2.Document getIndexDocument(URL indexResource, String absoluteServletPath) throws IOException { - try (InputStream indexFileStream = indexResource.openStream()) { - Document document = Jsoup.parse(indexFileStream, StandardCharsets.UTF_8.toString(), ""); - document.outputSettings().escapeMode(Entities.EscapeMode.xhtml); - document.outputSettings().syntax(Document.OutputSettings.Syntax.xml); - document.outerHtml(); - org.jdom2.Document jdom = new SAXBuilder().build(new StringReader(document.outerHtml())); - Element jdomRoot = jdom.getRootElement(); - List scriptAndLinks = jdomRoot.getChild("head").getChildren().stream() - .filter(el -> el.getName().equals("script") || el.getName().equals("link")) - .collect(Collectors.toList()) - .stream().map(Element::detach).peek(el -> { - String hrefAttr = el.getAttributeValue("href"); - if (hrefAttr != null) { - el.setAttribute("href", absoluteServletPath + "/" + hrefAttr); - } - - String srcAttr = el.getAttributeValue("src"); - if (srcAttr != null) { - el.setAttribute("src", absoluteServletPath + "/" + srcAttr); - } - }).collect(Collectors.toList()); - - List bodyContent = new ArrayList<>(jdomRoot.getChild("body").getChildren()).stream() - .map(Element::detach).collect(Collectors.toList()); - - Element webPage = new Element("MyCoReWebPage"); - org.jdom2.Document webpageDoc = new org.jdom2.Document(webPage); - - Element section = new Element("section"); - webPage.addContent(section); - section.setAttribute("lang", "de", Namespace.XML_NAMESPACE); - section.addContent(scriptAndLinks).addContent(bodyContent); - - return webpageDoc; - } catch (JDOMException e) { - throw new MCRException(e); - } - } - -} diff --git a/src/main/resources/META-INF/web-fragment.xml b/src/main/resources/META-INF/web-fragment.xml index 70b1eee6..b1e9f6b7 100644 --- a/src/main/resources/META-INF/web-fragment.xml +++ b/src/main/resources/META-INF/web-fragment.xml @@ -5,7 +5,7 @@ MCRVueRootServlet - org.mycore.vue.MCRVueRootServlet + org.mycore.webtools.vue.MCRVueRootServlet MCRVueRootServlet diff --git a/src/main/vue/modul_handbuecher/yarn.lock b/src/main/vue/modul_handbuecher/yarn.lock index 139ae0c5..a75c580f 100644 --- a/src/main/vue/modul_handbuecher/yarn.lock +++ b/src/main/vue/modul_handbuecher/yarn.lock @@ -2308,9 +2308,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: - version "1.0.30001469" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz#3dd505430c8522fdc9f94b4a19518e330f5c945a" - integrity sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g== + version "1.0.30001610" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz" + integrity sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA== case-sensitive-paths-webpack-plugin@^2.3.0: version "2.4.0"