Sun, 31 Dec 2017 17:43:39 +0100
user friendly error pages for codes 404, 403 and 500
1.1 --- a/src/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sat Dec 30 20:41:55 2017 +0100 1.2 +++ b/src/java/de/uapcore/lightpit/AbstractLightPITServlet.java Sun Dec 31 17:43:39 2017 +0100 1.3 @@ -73,6 +73,12 @@ 1.4 1.5 /** 1.6 * Invocation mapping gathered from the {@link RequestMapping} annotations. 1.7 + * 1.8 + * Paths in this map must always start with a leading slash, although 1.9 + * the specification in the annotation must not start with a leading slash. 1.10 + * 1.11 + * The reason for this is the different handling of empty paths in 1.12 + * {@link HttpServletRequest#getPathInfo()}. 1.13 */ 1.14 private final Map<HttpMethod, Map<String, HandlerMethod>> mappings = new HashMap<>(); 1.15 1.16 @@ -145,9 +151,11 @@ 1.17 if (params.length == 2 1.18 && HttpServletRequest.class.isAssignableFrom(params[0]) 1.19 && HttpServletResponse.class.isAssignableFrom(params[1])) { 1.20 + 1.21 + final String requestPath = "/"+mapping.get().requestPath(); 1.22 1.23 if (mappings.computeIfAbsent(mapping.get().method(), k -> new HashMap<>()). 1.24 - putIfAbsent(mapping.get().requestPath(), 1.25 + putIfAbsent(requestPath, 1.26 (req, resp) -> invokeMapping(method, req, resp)) != null) { 1.27 LOG.warn("{} {} has multiple mappings", 1.28 mapping.get().method(), 1.29 @@ -157,7 +165,7 @@ 1.30 1.31 LOG.info("{} {} maps to {}", 1.32 mapping.get().method(), 1.33 - mapping.get().requestPath(), 1.34 + requestPath, 1.35 method.getName() 1.36 ); 1.37 } else { 1.38 @@ -219,7 +227,7 @@ 1.39 1.40 private Optional<HandlerMethod> findMapping(HttpMethod method, HttpServletRequest req) { 1.41 return Optional.ofNullable(mappings.get(method)).map( 1.42 - (rm) -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("")) 1.43 + (rm) -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("/")) 1.44 ); 1.45 } 1.46
2.1 --- a/src/java/de/uapcore/lightpit/LightPITModule.java Sat Dec 30 20:41:55 2017 +0100 2.2 +++ b/src/java/de/uapcore/lightpit/LightPITModule.java Sun Dec 31 17:43:39 2017 +0100 2.3 @@ -71,6 +71,10 @@ 2.4 2.5 /** 2.6 * Returns the properties key for the menu label. 2.7 + * 2.8 + * Set this string to empty string, if the module should be hidden from 2.9 + * the menu. 2.10 + * 2.11 * @return the properties key 2.12 */ 2.13 String menuKey() default "menuLabel";
3.1 --- a/src/java/de/uapcore/lightpit/ModuleManager.java Sat Dec 30 20:41:55 2017 +0100 3.2 +++ b/src/java/de/uapcore/lightpit/ModuleManager.java Sun Dec 31 17:43:39 2017 +0100 3.3 @@ -31,6 +31,7 @@ 3.4 import java.util.ArrayList; 3.5 import java.util.Collections; 3.6 import java.util.List; 3.7 +import java.util.Objects; 3.8 import java.util.Optional; 3.9 import javax.servlet.Registration; 3.10 import javax.servlet.ServletContext; 3.11 @@ -118,10 +119,12 @@ 3.12 3.13 private void handleServletRegistration(String name, Registration reg) { 3.14 final Optional<LightPITModule> moduleInfo = getModuleInfo(reg); 3.15 - if (moduleInfo.isPresent()) { 3.16 + if (moduleInfo.isPresent()) { 3.17 + // TODO: implement dependency resolver 3.18 3.19 - // TODO: remove this call and add the module to some dependency resolver, first 3.20 - addModuleToMenu(reg.getClassName(), moduleInfo.get()); 3.21 + if (!moduleInfo.get().menuKey().isEmpty()) { 3.22 + addModuleToMenu(reg.getClassName(), moduleInfo.get()); 3.23 + } 3.24 3.25 LOG.info("Module detected: {}", name); 3.26 } else {
4.1 --- a/src/java/de/uapcore/lightpit/RequestMapping.java Sat Dec 30 20:41:55 2017 +0100 4.2 +++ b/src/java/de/uapcore/lightpit/RequestMapping.java Sun Dec 31 17:43:39 2017 +0100 4.3 @@ -59,7 +59,7 @@ 4.4 * If a menu key is specified, this is also the path, which is linked 4.5 * by the menu entry. 4.6 * 4.7 - * The path must be specified <em>without</em> a trailing slash. 4.8 + * The path must be specified <em>without</em> leading and trailing slash. 4.9 * 4.10 * @return the request path the annotated method should handle 4.11 */
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/java/de/uapcore/lightpit/modules/ErrorModule.java Sun Dec 31 17:43:39 2017 +0100 5.3 @@ -0,0 +1,80 @@ 5.4 +/* 5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5.6 + * 5.7 + * Copyright 2017 Mike Becker. All rights reserved. 5.8 + * 5.9 + * Redistribution and use in source and binary forms, with or without 5.10 + * modification, are permitted provided that the following conditions are met: 5.11 + * 5.12 + * 1. Redistributions of source code must retain the above copyright 5.13 + * notice, this list of conditions and the following disclaimer. 5.14 + * 5.15 + * 2. Redistributions in binary form must reproduce the above copyright 5.16 + * notice, this list of conditions and the following disclaimer in the 5.17 + * documentation and/or other materials provided with the distribution. 5.18 + * 5.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 5.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 5.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 5.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 5.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 5.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 5.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 5.29 + * POSSIBILITY OF SUCH DAMAGE. 5.30 + * 5.31 + */ 5.32 +package de.uapcore.lightpit.modules; 5.33 + 5.34 +import de.uapcore.lightpit.LightPITModule; 5.35 +import de.uapcore.lightpit.AbstractLightPITServlet; 5.36 +import de.uapcore.lightpit.HttpMethod; 5.37 +import de.uapcore.lightpit.RequestMapping; 5.38 +import de.uapcore.lightpit.ResponseType; 5.39 +import javax.servlet.annotation.WebServlet; 5.40 +import javax.servlet.http.HttpServletRequest; 5.41 +import javax.servlet.http.HttpServletResponse; 5.42 + 5.43 +/** 5.44 + * Entry point for the application. 5.45 + */ 5.46 +@LightPITModule( 5.47 + bundleBaseName = "de.uapcore.lightpit.resources.localization.error", 5.48 + modulePath = "error", 5.49 + menuKey = "", 5.50 + titleKey = "title" 5.51 +) 5.52 +@WebServlet( 5.53 + name = "ErrorModule", 5.54 + urlPatterns = "/error/*" 5.55 +) 5.56 +public final class ErrorModule extends AbstractLightPITServlet { 5.57 + 5.58 + public static final String REQ_ATTR_ERROR_CODE = "errorCode"; 5.59 + 5.60 + private ResponseType handle(HttpServletRequest req, HttpServletResponse resp, int sc) { 5.61 + 5.62 + req.setAttribute(REQ_ATTR_ERROR_CODE, sc); 5.63 + setStylesheet(req, "error"); 5.64 + setDynamicFragment(req, "error"); 5.65 + 5.66 + return ResponseType.HTML_FULL; 5.67 + } 5.68 + 5.69 + @RequestMapping(requestPath = "404", method = HttpMethod.GET) 5.70 + public ResponseType handle404(HttpServletRequest req, HttpServletResponse resp) { 5.71 + return handle(req, resp, 404); 5.72 + } 5.73 + 5.74 + @RequestMapping(requestPath = "403", method = HttpMethod.GET) 5.75 + public ResponseType handle403(HttpServletRequest req, HttpServletResponse resp) { 5.76 + return handle(req, resp, 403); 5.77 + } 5.78 + 5.79 + @RequestMapping(requestPath = "500", method = HttpMethod.GET) 5.80 + public ResponseType handle500(HttpServletRequest req, HttpServletResponse resp) { 5.81 + return handle(req, resp, 500); 5.82 + } 5.83 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/java/de/uapcore/lightpit/resources/localization/error.properties Sun Dec 31 17:43:39 2017 +0100 6.3 @@ -0,0 +1,35 @@ 6.4 +# Copyright 2017 Mike Becker. All rights reserved. 6.5 +# 6.6 +# Redistribution and use in source and binary forms, with or without 6.7 +# modification, are permitted provided that the following conditions are met: 6.8 +# 6.9 +# 1. Redistributions of source code must retain the above copyright 6.10 +# notice, this list of conditions and the following disclaimer. 6.11 +# 6.12 +# 2. Redistributions in binary form must reproduce the above copyright 6.13 +# notice, this list of conditions and the following disclaimer in the 6.14 +# documentation and/or other materials provided with the distribution. 6.15 +# 6.16 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 6.17 +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 6.18 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 6.19 +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 6.20 +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 6.21 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 6.22 +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 6.23 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 6.24 +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 6.25 +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 6.26 + 6.27 +title = Error 6.28 + 6.29 +h1 = The requested page cannot be displayed. 6.30 +errorCode = Code 6.31 + 6.32 +errorMessage = Message 6.33 +errorMessage.404 = Page not found 6.34 +errorMessage.403 = Access denied 6.35 +errorMessage.500 = Internal error 6.36 + 6.37 +errorTimestamp = Timestamp 6.38 +errorExceptionText = Internal Exception
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/java/de/uapcore/lightpit/resources/localization/error_de.properties Sun Dec 31 17:43:39 2017 +0100 7.3 @@ -0,0 +1,35 @@ 7.4 +# Copyright 2017 Mike Becker. All rights reserved. 7.5 +# 7.6 +# Redistribution and use in source and binary forms, with or without 7.7 +# modification, are permitted provided that the following conditions are met: 7.8 +# 7.9 +# 1. Redistributions of source code must retain the above copyright 7.10 +# notice, this list of conditions and the following disclaimer. 7.11 +# 7.12 +# 2. Redistributions in binary form must reproduce the above copyright 7.13 +# notice, this list of conditions and the following disclaimer in the 7.14 +# documentation and/or other materials provided with the distribution. 7.15 +# 7.16 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 7.17 +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 7.18 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 7.19 +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 7.20 +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 7.21 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 7.22 +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 7.23 +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 7.24 +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 7.25 +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 7.26 + 7.27 +title = Fehler 7.28 + 7.29 +h1 = Die angeforderte Seite kann nicht angezeigt werden. 7.30 +errorCode = Fehlercode 7.31 + 7.32 +errorMessage = Nachricht 7.33 +errorMessage.404 = Seite nicht gefunden 7.34 +errorMessage.403 = Zugriff verboten 7.35 +errorMessage.500 = Interner Fehler 7.36 + 7.37 +errorTimestamp = Zeitstempel 7.38 +errorExceptionText = Interne Ausnahme
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/web/WEB-INF/dynamic_fragments/error.jsp Sun Dec 31 17:43:39 2017 +0100 8.3 @@ -0,0 +1,56 @@ 8.4 +<%-- 8.5 +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 8.6 + 8.7 +Copyright 2017 Mike Becker. All rights reserved. 8.8 + 8.9 +Redistribution and use in source and binary forms, with or without 8.10 +modification, are permitted provided that the following conditions are met: 8.11 + 8.12 +1. Redistributions of source code must retain the above copyright 8.13 +notice, this list of conditions and the following disclaimer. 8.14 + 8.15 +2. Redistributions in binary form must reproduce the above copyright 8.16 +notice, this list of conditions and the following disclaimer in the 8.17 +documentation and/or other materials provided with the distribution. 8.18 + 8.19 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 8.20 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 8.21 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 8.22 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 8.23 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 8.24 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 8.25 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 8.26 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 8.27 +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 8.28 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 8.29 +--%> 8.30 +<%@page pageEncoding="UTF-8" session="true" %> 8.31 +<%@page import="de.uapcore.lightpit.modules.ErrorModule" %> 8.32 +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 8.33 +<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 8.34 + 8.35 +<c:set scope="page" var="errorCode" value="${requestScope[ErrorModule.REQ_ATTR_ERROR_CODE]}"/> 8.36 + 8.37 +<div id="error-page"> 8.38 + <h1><fmt:message key="h1"/></h1> 8.39 + <table> 8.40 + <tr> 8.41 + <th><fmt:message key="errorCode" />:</th> 8.42 + <td>${errorCode}</td> 8.43 + </tr> 8.44 + <tr> 8.45 + <th><fmt:message key="errorMessage" />:</th> 8.46 + <td><fmt:message key="errorMessage.${errorCode}" /></td> 8.47 + </tr> 8.48 + <tr> 8.49 + <th><fmt:message key="errorTimestamp" />:</th> 8.50 + <td><fmt:formatDate type="both" value="<%= new java.util.Date()%>"/></td> 8.51 + </tr> 8.52 + <c:if test="${not empty exception}"> 8.53 + <tr> 8.54 + <th><fmt:message key="errorExceptionText" />:</th> 8.55 + <td>${exception.class.name} - ${exception.message}</td> 8.56 + </tr> 8.57 + </c:if> 8.58 + </table> 8.59 +</div>
9.1 --- a/web/WEB-INF/web.xml Sat Dec 30 20:41:55 2017 +0100 9.2 +++ b/web/WEB-INF/web.xml Sun Dec 31 17:43:39 2017 +0100 9.3 @@ -9,4 +9,16 @@ 9.4 <param-name>available-languages</param-name> 9.5 <param-value>en,de</param-value> 9.6 </context-param> 9.7 + <error-page> 9.8 + <error-code>404</error-code> 9.9 + <location>/error/404</location> 9.10 + </error-page> 9.11 + <error-page> 9.12 + <error-code>403</error-code> 9.13 + <location>/error/403</location> 9.14 + </error-page> 9.15 + <error-page> 9.16 + <error-code>500</error-code> 9.17 + <location>/error/500</location> 9.18 + </error-page> 9.19 </web-app>
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/web/error.css Sun Dec 31 17:43:39 2017 +0100 10.3 @@ -0,0 +1,55 @@ 10.4 +/* 10.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 10.6 + * 10.7 + * Copyright 2017 Mike Becker. All rights reserved. 10.8 + * 10.9 + * Redistribution and use in source and binary forms, with or without 10.10 + * modification, are permitted provided that the following conditions are met: 10.11 + * 10.12 + * 1. Redistributions of source code must retain the above copyright 10.13 + * notice, this list of conditions and the following disclaimer. 10.14 + * 10.15 + * 2. Redistributions in binary form must reproduce the above copyright 10.16 + * notice, this list of conditions and the following disclaimer in the 10.17 + * documentation and/or other materials provided with the distribution. 10.18 + * 10.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 10.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 10.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 10.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 10.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 10.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 10.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 10.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 10.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 10.29 + * POSSIBILITY OF SUCH DAMAGE. 10.30 + * 10.31 + */ 10.32 + 10.33 +#error-page h1 { 10.34 + font-size: 1.5em; 10.35 +} 10.36 + 10.37 +#error-page table { 10.38 + width: 100%; 10.39 + 10.40 + border-top-style: solid; 10.41 + border-top-width: 1pt; 10.42 + border-top-color: #606060; 10.43 + 10.44 + border-bottom-style: solid; 10.45 + border-bottom-width: 1pt; 10.46 + border-bottom-color: #505050; 10.47 + 10.48 + border-collapse: separate; 10.49 + border-spacing: .5em; 10.50 +} 10.51 + 10.52 +#error-page table th { 10.53 + text-align: right; 10.54 +} 10.55 + 10.56 +#error-page table td { 10.57 + width: 100%; 10.58 +}
11.1 --- a/web/lightpit.css Sat Dec 30 20:41:55 2017 +0100 11.2 +++ b/web/lightpit.css Sun Dec 31 17:43:39 2017 +0100 11.3 @@ -39,7 +39,7 @@ 11.4 border-style: solid; 11.5 border-width: 1pt; 11.6 11.7 - color: black; 11.8 + color: #1c202e; 11.9 } 11.10 11.11 a {