├── .gitignore ├── .mvn ├── jvm.config ├── maven.config └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml ├── spring-boot-legacy ├── docs │ ├── sample-gae-pom.xml │ └── sample-web.xml ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── boot │ │ │ ├── legacy │ │ │ └── context │ │ │ │ └── web │ │ │ │ ├── AnnotationConfigNonEmbeddedWebApplicationContext.java │ │ │ │ ├── MetricFilterAutoConfiguration.java │ │ │ │ ├── NonEmbeddedWebApplicationContext.java │ │ │ │ ├── SecurityFilterAutoConfiguration.java │ │ │ │ ├── SpringBootContextLoaderListener.java │ │ │ │ └── servlet │ │ │ │ └── support │ │ │ │ └── ErrorPageFilterConfiguration.java │ │ │ └── web │ │ │ └── servlet │ │ │ └── LegacyServletContextInitializerBeans.java │ └── resources │ │ └── META-INF │ │ └── spring.factories │ └── test │ └── java │ └── org │ └── springframework │ └── boot │ └── legacy │ └── context │ └── web │ ├── AnnotationConfigNonEmbeddedWebApplicationContextTests.java │ └── SpringBootContextLoaderListenerTests.java └── spring-boot-samples ├── pom.xml ├── spring-boot-sample-gae-2.5 ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── demo │ │ │ ├── Application.java │ │ │ └── hello │ │ │ ├── Greeting.java │ │ │ └── HelloWorldController.java │ ├── resources │ │ ├── application.properties │ │ ├── logging.properties │ │ └── static │ │ │ └── static.html │ └── webapp │ │ ├── META-INF │ │ └── context.xml │ │ └── WEB-INF │ │ ├── appengine-web.xml │ │ └── web.xml │ └── test │ └── java │ └── demo │ └── EmbeddedIntegrationTests.java ├── spring-boot-sample-gae-3.1 ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── demo │ │ │ ├── Application.java │ │ │ └── hello │ │ │ ├── Greeting.java │ │ │ └── HelloWorldController.java │ ├── resources │ │ ├── application.properties │ │ ├── logging.properties │ │ └── static │ │ │ └── static.html │ └── webapp │ │ ├── META-INF │ │ └── context.xml │ │ └── WEB-INF │ │ ├── appengine-web.xml │ │ └── web.xml │ └── test │ └── java │ └── demo │ └── EmbeddedIntegrationTests.java └── spring-boot-sample-secure-legacy ├── pom.xml └── src ├── main ├── java │ └── demo │ │ └── Application.java ├── resources │ └── application.properties └── webapp │ ├── META-INF │ └── context.xml │ └── WEB-INF │ ├── jboss-deployment-structure.xml │ ├── jboss-web.xml │ └── web.xml └── test └── java └── demo └── EmbeddedIntegrationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .#* 3 | *# 4 | .classpath 5 | .project 6 | .settings/ 7 | .springBeans 8 | .sts4-cache/ 9 | .attach_pid* 10 | target/ 11 | 12 | # IntelliJ IDEA Project Files 13 | .idea/ 14 | *.iml 15 | -------------------------------------------------------------------------------- /.mvn/jvm.config: -------------------------------------------------------------------------------- 1 | -Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring 2 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsyer/spring-boot-legacy/deea53054d7d1fb3b435326b2933c7beb283a2fe/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Spring Boot Support for Servlet 2.5 2 | =================================== 3 | 4 | Latest release 2.0.1.RELEASE, updated to Spring Boot 2.0.3.RELEASE. 5 | 6 | Spring Boot is built on Servlet 3.1. Older servlet versions can be 7 | used with Spring Boot, but some workarounds are needed. This project 8 | is a library that gives you a start with those. There is a sample that 9 | is running on Google Appengine at http://dsyerboot.appspot.com/. Copy 10 | the `web.xml` from the sample to get started with your own project. 11 | 12 | To deploy the sample to GAE use `mvn appengine:update` (reference docs 13 | are 14 | [here](https://cloud.google.com/appengine/docs/java/tools/maven#app_engine_maven_plugin_goals)). 15 | 16 | Additionally this can be used to load Spring Boot in a Servlet 3.0+ container like Wildfly 8.2.1 when 17 | you exclude the Spring Framework and Spring Boot dependencies from the WAR and place them in the EAR. i.e. A Skinny Ear. 18 | See [Spring Boot EAR with Skinny WARs](https://github.com/ddcruver/spring-boot-ear-skinny-war). -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # 58 | # Look for the Apple JDKs first to preserve the existing behaviour, and then look 59 | # for the new JDKs provided by Oracle. 60 | # 61 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then 62 | # 63 | # Apple JDKs 64 | # 65 | export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home 66 | fi 67 | 68 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then 69 | # 70 | # Apple JDKs 71 | # 72 | export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 73 | fi 74 | 75 | if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then 76 | # 77 | # Oracle JDKs 78 | # 79 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 80 | fi 81 | 82 | if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then 83 | # 84 | # Apple JDKs 85 | # 86 | export JAVA_HOME=`/usr/libexec/java_home` 87 | fi 88 | ;; 89 | esac 90 | 91 | if [ -z "$JAVA_HOME" ] ; then 92 | if [ -r /etc/gentoo-release ] ; then 93 | JAVA_HOME=`java-config --jre-home` 94 | fi 95 | fi 96 | 97 | if [ -z "$M2_HOME" ] ; then 98 | ## resolve links - $0 may be a link to maven's home 99 | PRG="$0" 100 | 101 | # need this for relative symlinks 102 | while [ -h "$PRG" ] ; do 103 | ls=`ls -ld "$PRG"` 104 | link=`expr "$ls" : '.*-> \(.*\)$'` 105 | if expr "$link" : '/.*' > /dev/null; then 106 | PRG="$link" 107 | else 108 | PRG="`dirname "$PRG"`/$link" 109 | fi 110 | done 111 | 112 | saveddir=`pwd` 113 | 114 | M2_HOME=`dirname "$PRG"`/.. 115 | 116 | # make it fully qualified 117 | M2_HOME=`cd "$M2_HOME" && pwd` 118 | 119 | cd "$saveddir" 120 | # echo Using m2 at $M2_HOME 121 | fi 122 | 123 | # For Cygwin, ensure paths are in UNIX format before anything is touched 124 | if $cygwin ; then 125 | [ -n "$M2_HOME" ] && 126 | M2_HOME=`cygpath --unix "$M2_HOME"` 127 | [ -n "$JAVA_HOME" ] && 128 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 129 | [ -n "$CLASSPATH" ] && 130 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 131 | fi 132 | 133 | # For Migwn, ensure paths are in UNIX format before anything is touched 134 | if $mingw ; then 135 | [ -n "$M2_HOME" ] && 136 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 137 | [ -n "$JAVA_HOME" ] && 138 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 139 | # TODO classpath? 140 | fi 141 | 142 | if [ -z "$JAVA_HOME" ]; then 143 | javaExecutable="`which javac`" 144 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 145 | # readlink(1) is not available as standard on Solaris 10. 146 | readLink=`which readlink` 147 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 148 | if $darwin ; then 149 | javaHome="`dirname \"$javaExecutable\"`" 150 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 151 | else 152 | javaExecutable="`readlink -f \"$javaExecutable\"`" 153 | fi 154 | javaHome="`dirname \"$javaExecutable\"`" 155 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 156 | JAVA_HOME="$javaHome" 157 | export JAVA_HOME 158 | fi 159 | fi 160 | fi 161 | 162 | if [ -z "$JAVACMD" ] ; then 163 | if [ -n "$JAVA_HOME" ] ; then 164 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 165 | # IBM's JDK on AIX uses strange locations for the executables 166 | JAVACMD="$JAVA_HOME/jre/sh/java" 167 | else 168 | JAVACMD="$JAVA_HOME/bin/java" 169 | fi 170 | else 171 | JAVACMD="`which java`" 172 | fi 173 | fi 174 | 175 | if [ ! -x "$JAVACMD" ] ; then 176 | echo "Error: JAVA_HOME is not defined correctly." >&2 177 | echo " We cannot execute $JAVACMD" >&2 178 | exit 1 179 | fi 180 | 181 | if [ -z "$JAVA_HOME" ] ; then 182 | echo "Warning: JAVA_HOME environment variable is not set." 183 | fi 184 | 185 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 186 | 187 | # For Cygwin, switch paths to Windows format before running java 188 | if $cygwin; then 189 | [ -n "$M2_HOME" ] && 190 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 191 | [ -n "$JAVA_HOME" ] && 192 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 193 | [ -n "$CLASSPATH" ] && 194 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 195 | fi 196 | 197 | # traverses directory structure from process work directory to filesystem root 198 | # first directory with .mvn subdirectory is considered project base directory 199 | find_maven_basedir() { 200 | local basedir=$(pwd) 201 | local wdir=$(pwd) 202 | while [ "$wdir" != '/' ] ; do 203 | if [ -d "$wdir"/.mvn ] ; then 204 | basedir=$wdir 205 | break 206 | fi 207 | wdir=$(cd "$wdir/.."; pwd) 208 | done 209 | echo "${basedir}" 210 | } 211 | 212 | # concatenates all lines of a file 213 | concat_lines() { 214 | if [ -f "$1" ]; then 215 | echo "$(tr -s '\n' ' ' < "$1")" 216 | fi 217 | } 218 | 219 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} 220 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 221 | 222 | # Provide a "standardized" way to retrieve the CLI args that will 223 | # work with both Windows and non-Windows executions. 224 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 225 | export MAVEN_CMD_LINE_ARGS 226 | 227 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 228 | 229 | exec "$JAVACMD" \ 230 | $MAVEN_OPTS \ 231 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 232 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 233 | ${WRAPPER_LAUNCHER} "$@" 234 | 235 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | set MAVEN_CMD_LINE_ARGS=%* 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | 121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" 122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 123 | 124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 125 | if ERRORLEVEL 1 goto error 126 | goto end 127 | 128 | :error 129 | set ERROR_CODE=1 130 | 131 | :end 132 | @endlocal & set ERROR_CODE=%ERROR_CODE% 133 | 134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 138 | :skipRcPost 139 | 140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 142 | 143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 144 | 145 | exit /B %ERROR_CODE% 146 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-legacy-parent 8 | 2.7.0-SNAPSHOT 9 | pom 10 | 11 | Spring Boot Legacy Parent 12 | Spring Boot Servlet 2.5 support 13 | 14 | 15 | spring-boot-legacy 16 | spring-boot-samples 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-deploy-plugin 25 | 26 | true 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /spring-boot-legacy/docs/sample-gae-pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.demo 7 | demo 8 | 0.0.1-SNAPSHOT 9 | war 10 | 11 | gae 12 | Demo project 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.0.0.BUILD-SNAPSHOT 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-actuator 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-tomcat 32 | provided 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-legacy 37 | 1.0.0.BUILD-SNAPSHOT 38 | 39 | 40 | net.kindleit 41 | gae-runtime 42 | ${gae.version} 43 | pom 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | com.google.appengine 52 | appengine-api-labs 53 | ${gae.version} 54 | test 55 | 56 | 57 | com.google.appengine 58 | appengine-api-stubs 59 | ${gae.version} 60 | test 61 | 62 | 63 | com.google.appengine 64 | appengine-testing 65 | ${gae.version} 66 | test 67 | 68 | 69 | 70 | 71 | demo.Application 72 | UTF-8 73 | UTF-8 74 | 1.7 75 | / 76 | 1.8.8 77 | ${settings.localRepository}/com/google/appengine/appengine-java-sdk/${gae.version}/appengine-java-sdk-${gae.version} 78 | test 79 | 80 | 81 | 82 | 83 | 84 | org.springframework.boot 85 | spring-boot-maven-plugin 86 | 87 | 88 | net.kindleit 89 | maven-gae-plugin 90 | 0.9.6 91 | 92 | 93 | net.kindleit 94 | gae-runtime 95 | ${gae.version} 96 | pom 97 | 98 | 99 | 100 | 101 | maven-release-plugin 102 | 103 | gae:deploy 104 | 105 | 106 | 107 | 108 | 109 | 110 | 113 | 114 | integration-build 115 | 116 | stage 117 | 118 | 119 | 120 | 124 | 125 | release-build 126 | 127 | 128 | performRelease 129 | true 130 | 131 | 132 | 133 | 134 | 136 | release 137 | 138 | 139 | 140 | 141 | 142 | 143 | spring-snapshots 144 | Spring Snapshots 145 | http://repo.spring.io/snapshot 146 | 147 | true 148 | 149 | 150 | 151 | spring-milestones 152 | Spring Milestones 153 | http://repo.spring.io/milestone 154 | 155 | false 156 | 157 | 158 | 159 | 160 | 161 | spring-snapshots 162 | Spring Snapshots 163 | http://repo.spring.io/snapshot 164 | 165 | true 166 | 167 | 168 | 169 | spring-milestones 170 | Spring Milestones 171 | http://repo.spring.io/milestone 172 | 173 | false 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /spring-boot-legacy/docs/sample-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | contextConfigLocation 8 | demo.Application 9 | 10 | 11 | 12 | org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener 13 | 14 | 15 | 16 | metricFilter 17 | org.springframework.web.filter.DelegatingFilterProxy 18 | 19 | 20 | 21 | metricFilter 22 | /* 23 | 24 | 25 | 26 | appServlet 27 | org.springframework.web.servlet.DispatcherServlet 28 | 29 | contextAttribute 30 | org.springframework.web.context.WebApplicationContext.ROOT 31 | 32 | 1 33 | 34 | 35 | 36 | appServlet 37 | / 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /spring-boot-legacy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.7.5 10 | 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-legacy 15 | 2.7.0-SNAPSHOT 16 | 17 | Spring Boot Legacy 18 | Spring Boot web.xml support 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-actuator 24 | true 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-security 30 | true 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-tomcat 40 | 41 | 42 | true 43 | 44 | 45 | 46 | javax.servlet 47 | javax.servlet-api 48 | provided 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-test 54 | test 55 | 56 | 57 | 58 | 59 | 60 | 1.8 61 | 2.7.5 62 | 63 | 64 | http://spring.io 65 | 66 | Pivotal 67 | http://spring.io 68 | 69 | 70 | 71 | Apache 2.0 72 | http://www.apache.org/licenses/LICENSE-2.0.txt 73 | 74 | 75 | 76 | 77 | http://github.com/dsyer/spring-boot-legacy 78 | scm:git:git://github.com/dsyer/spring-boot-legacy.git 79 | scm:git:ssh://git@github.com/dsyer/spring-boot-legacy.git 80 | HEAD 81 | 82 | 83 | 84 | 85 | 86 | static.springframework.org 87 | scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-boot-legacy 88 | 89 | 90 | 91 | repo.spring.io 92 | Spring Release Repository 93 | http://repo.spring.io/libs-release-local 94 | 95 | 96 | 97 | repo.spring.io 98 | Spring Snapshot Repository 99 | http://repo.spring.io/libs-snapshot-local 100 | 101 | 102 | 103 | 104 | 105 | 106 | dsyer 107 | Dave Syer 108 | dsyer@pivotal.io 109 | 110 | 111 | 112 | 113 | 114 | 115 | org.apache.maven.plugins 116 | maven-compiler-plugin 117 | 118 | ${java.version} 119 | ${java.version} 120 | 121 | 122 | 123 | org.apache.maven.plugins 124 | maven-surefire-plugin 125 | 126 | 127 | 128 | **/*Tests.java 129 | 130 | 131 | **/Abstract*.java 132 | 133 | 134 | 135 | 136 | maven-source-plugin 137 | 138 | 139 | attach-sources 140 | 141 | jar 142 | 143 | package 144 | 145 | 146 | 147 | 148 | maven-javadoc-plugin 149 | 150 | 151 | attach-javadoc 152 | package 153 | 154 | jar 155 | 156 | false 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | milestone 166 | 167 | 168 | repo.spring.io 169 | Spring Milestone Repository 170 | http://repo.spring.io/libs-milestone-local 171 | 172 | 173 | 174 | 175 | central 176 | 177 | 178 | sonatype-nexus-snapshots 179 | Sonatype Nexus Snapshots 180 | https://oss.sonatype.org/content/repositories/snapshots/ 181 | 182 | 183 | sonatype-nexus-staging 184 | Nexus Release Repository 185 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 186 | 187 | 188 | 189 | 190 | 191 | maven-gpg-plugin 192 | 193 | 194 | sign-artifacts 195 | verify 196 | 197 | sign 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /spring-boot-legacy/src/main/java/org/springframework/boot/legacy/context/web/AnnotationConfigNonEmbeddedWebApplicationContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.boot.legacy.context.web; 18 | 19 | import java.util.Arrays; 20 | import java.util.LinkedHashSet; 21 | import java.util.Set; 22 | 23 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 24 | import org.springframework.beans.factory.support.BeanNameGenerator; 25 | import org.springframework.beans.factory.support.DefaultListableBeanFactory; 26 | import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; 27 | import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; 28 | import org.springframework.context.annotation.AnnotationConfigRegistry; 29 | import org.springframework.context.annotation.AnnotationConfigUtils; 30 | import org.springframework.context.annotation.AnnotationScopeMetadataResolver; 31 | import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; 32 | import org.springframework.context.annotation.ScopeMetadataResolver; 33 | import org.springframework.core.env.ConfigurableEnvironment; 34 | import org.springframework.stereotype.Component; 35 | import org.springframework.util.Assert; 36 | import org.springframework.util.ClassUtils; 37 | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; 38 | 39 | /** 40 | * {@link ServletWebServerApplicationContext} that accepts annotated classes as input - in 41 | * particular {@link org.springframework.context.annotation.Configuration @Configuration} 42 | * -annotated classes, but also plain {@link Component @Component} classes and JSR-330 43 | * compliant classes using {@code javax.inject} annotations. Allows for registering 44 | * classes one by one (specifying class names as config location) as well as for classpath 45 | * scanning (specifying base packages as config location). 46 | *

47 | * Note: In case of multiple {@code @Configuration} classes, later {@code @Bean} 48 | * definitions will override ones defined in earlier loaded files. This can be leveraged 49 | * to deliberately override certain bean definitions via an extra Configuration class. 50 | * 51 | * @author Phillip Webb 52 | * @author Dave Syer 53 | * @author Daniel Cruver 54 | * @see #register(Class...) 55 | * @see #scan(String...) 56 | * @see ServletWebServerApplicationContext 57 | * @see AnnotationConfigWebApplicationContext 58 | */ 59 | public class AnnotationConfigNonEmbeddedWebApplicationContext 60 | extends NonEmbeddedWebApplicationContext 61 | implements AnnotationConfigRegistry { 62 | 63 | private final AnnotatedBeanDefinitionReader reader; 64 | 65 | private final ClassPathBeanDefinitionScanner scanner; 66 | 67 | private final Set> annotatedClasses = new LinkedHashSet<>(); 68 | 69 | private String[] basePackages; 70 | 71 | /** 72 | * Create a new {@link AnnotationConfigNonEmbeddedWebApplicationContext} that needs 73 | * to be populated through {@link #register} calls and then manually 74 | * {@linkplain #refresh refreshed}. 75 | */ 76 | public AnnotationConfigNonEmbeddedWebApplicationContext() { 77 | this.reader = new AnnotatedBeanDefinitionReader(this); 78 | this.scanner = new ClassPathBeanDefinitionScanner(this); 79 | } 80 | 81 | /** 82 | * Create a new {@link AnnotationConfigNonEmbeddedWebApplicationContext}, deriving 83 | * bean definitions from the given annotated classes and automatically refreshing the 84 | * context. 85 | * @param annotatedClasses one or more annotated classes, e.g. {@code @Configuration} 86 | * classes 87 | */ 88 | public AnnotationConfigNonEmbeddedWebApplicationContext( 89 | Class... annotatedClasses) { 90 | this(); 91 | register(annotatedClasses); 92 | refresh(); 93 | } 94 | 95 | /** 96 | * Create a new {@link AnnotationConfigNonEmbeddedWebApplicationContext} with the 97 | * given {@code DefaultListableBeanFactory}. The context needs to be populated through 98 | * {@link #register} calls and then manually {@linkplain #refresh refreshed}. 99 | * @param beanFactory the DefaultListableBeanFactory instance to use for this context 100 | */ 101 | public AnnotationConfigNonEmbeddedWebApplicationContext( 102 | DefaultListableBeanFactory beanFactory) { 103 | super(beanFactory); 104 | this.reader = new AnnotatedBeanDefinitionReader(this); 105 | this.scanner = new ClassPathBeanDefinitionScanner(this); 106 | } 107 | 108 | /** 109 | * Create a new {@link AnnotationConfigNonEmbeddedWebApplicationContext}, scanning 110 | * for bean definitions in the given packages and automatically refreshing the 111 | * context. 112 | * @param basePackages the packages to check for annotated classes 113 | */ 114 | public AnnotationConfigNonEmbeddedWebApplicationContext(String... basePackages) { 115 | this(); 116 | scan(basePackages); 117 | refresh(); 118 | } 119 | 120 | /** 121 | * {@inheritDoc} 122 | *

123 | * Delegates given environment to underlying {@link AnnotatedBeanDefinitionReader} and 124 | * {@link ClassPathBeanDefinitionScanner} members. 125 | */ 126 | @Override 127 | public void setEnvironment(ConfigurableEnvironment environment) { 128 | super.setEnvironment(environment); 129 | this.reader.setEnvironment(environment); 130 | this.scanner.setEnvironment(environment); 131 | } 132 | 133 | /** 134 | * Provide a custom {@link BeanNameGenerator} for use with 135 | * {@link AnnotatedBeanDefinitionReader} and/or 136 | * {@link ClassPathBeanDefinitionScanner}, if any. 137 | *

138 | * Default is 139 | * {@link org.springframework.context.annotation.AnnotationBeanNameGenerator}. 140 | *

141 | * Any call to this method must occur prior to calls to {@link #register(Class...)} 142 | * and/or {@link #scan(String...)}. 143 | * @param beanNameGenerator the bean name generator 144 | * @see AnnotatedBeanDefinitionReader#setBeanNameGenerator 145 | * @see ClassPathBeanDefinitionScanner#setBeanNameGenerator 146 | */ 147 | public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { 148 | this.reader.setBeanNameGenerator(beanNameGenerator); 149 | this.scanner.setBeanNameGenerator(beanNameGenerator); 150 | this.getBeanFactory().registerSingleton( 151 | AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, 152 | beanNameGenerator); 153 | } 154 | 155 | /** 156 | * Set the {@link ScopeMetadataResolver} to use for detected bean classes. 157 | *

158 | * The default is an {@link AnnotationScopeMetadataResolver}. 159 | *

160 | * Any call to this method must occur prior to calls to {@link #register(Class...)} 161 | * and/or {@link #scan(String...)}. 162 | * @param scopeMetadataResolver the scope metadata resolver 163 | */ 164 | public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) { 165 | this.reader.setScopeMetadataResolver(scopeMetadataResolver); 166 | this.scanner.setScopeMetadataResolver(scopeMetadataResolver); 167 | } 168 | 169 | /** 170 | * Register one or more annotated classes to be processed. Note that 171 | * {@link #refresh()} must be called in order for the context to fully process the new 172 | * class. 173 | *

174 | * Calls to {@code #register} are idempotent; adding the same annotated class more 175 | * than once has no additional effect. 176 | * @param annotatedClasses one or more annotated classes, e.g. {@code @Configuration} 177 | * classes 178 | * @see #scan(String...) 179 | * @see #refresh() 180 | */ 181 | @Override 182 | public final void register(Class... annotatedClasses) { 183 | Assert.notEmpty(annotatedClasses, 184 | "At least one annotated class must be specified"); 185 | this.annotatedClasses.addAll(Arrays.asList(annotatedClasses)); 186 | } 187 | 188 | /** 189 | * Perform a scan within the specified base packages. Note that {@link #refresh()} 190 | * must be called in order for the context to fully process the new class. 191 | * @param basePackages the packages to check for annotated classes 192 | * @see #register(Class...) 193 | * @see #refresh() 194 | */ 195 | @Override 196 | public final void scan(String... basePackages) { 197 | Assert.notEmpty(basePackages, "At least one base package must be specified"); 198 | this.basePackages = basePackages; 199 | } 200 | 201 | @Override 202 | protected void prepareRefresh() { 203 | this.scanner.clearCache(); 204 | super.prepareRefresh(); 205 | } 206 | 207 | @Override 208 | protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { 209 | super.postProcessBeanFactory(beanFactory); 210 | if (this.basePackages != null && this.basePackages.length > 0) { 211 | this.scanner.scan(this.basePackages); 212 | } 213 | if (!this.annotatedClasses.isEmpty()) { 214 | this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); 215 | } 216 | } 217 | 218 | } -------------------------------------------------------------------------------- /spring-boot-legacy/src/main/java/org/springframework/boot/legacy/context/web/MetricFilterAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.boot.legacy.context.web; 18 | 19 | import java.io.IOException; 20 | 21 | import javax.servlet.Filter; 22 | import javax.servlet.FilterChain; 23 | import javax.servlet.Servlet; 24 | import javax.servlet.ServletException; 25 | import javax.servlet.http.HttpServletRequest; 26 | import javax.servlet.http.HttpServletResponse; 27 | import javax.servlet.http.HttpServletResponseWrapper; 28 | 29 | import io.micrometer.core.instrument.MeterRegistry; 30 | 31 | import org.springframework.beans.factory.annotation.Autowired; 32 | import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; 33 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 34 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 35 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 36 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 37 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; 38 | import org.springframework.context.annotation.Bean; 39 | import org.springframework.context.annotation.Configuration; 40 | import org.springframework.core.Ordered; 41 | import org.springframework.core.annotation.Order; 42 | import org.springframework.http.HttpStatus; 43 | import org.springframework.util.StopWatch; 44 | import org.springframework.web.filter.OncePerRequestFilter; 45 | import org.springframework.web.servlet.HandlerMapping; 46 | import org.springframework.web.util.UrlPathHelper; 47 | 48 | /** 49 | * {@link EnableAutoConfiguration Auto-configuration} that records Servlet interactions 50 | * with a {@link MeterRegistry}. 51 | * 52 | * @author Dave Syer 53 | * @author Phillip Webb 54 | * @author Daniel Cruver 55 | */ 56 | @Configuration 57 | @ConditionalOnBean({MeterRegistry.class}) 58 | @ConditionalOnClass({Servlet.class, MetricsAutoConfiguration.class}) 59 | @ConditionalOnMissingClass("javax.servlet.ServletRegistration") 60 | @AutoConfigureAfter({ 61 | MetricsAutoConfiguration.class}) 62 | public class MetricFilterAutoConfiguration { 63 | 64 | private static final int UNDEFINED_HTTP_STATUS = 999; 65 | 66 | private static final String UNKNOWN_PATH_SUFFIX = "/unmapped"; 67 | 68 | @Autowired 69 | private MeterRegistry meterRegistry; 70 | 71 | @Bean 72 | public Filter metricFilter() { 73 | return new MetricsFilter(); 74 | } 75 | 76 | /** 77 | * Filter that counts requests and measures processing times. 78 | */ 79 | @Order(Ordered.HIGHEST_PRECEDENCE) 80 | private final class MetricsFilter extends OncePerRequestFilter { 81 | 82 | @Override 83 | protected void doFilterInternal(HttpServletRequest request, 84 | HttpServletResponse response, FilterChain chain) throws ServletException, 85 | IOException { 86 | UrlPathHelper helper = new UrlPathHelper(); 87 | String suffix = helper.getPathWithinApplication(request); 88 | StopWatch stopWatch = new StopWatch(); 89 | stopWatch.start(); 90 | MetricsFilterResponseWrapper wrapper = new MetricsFilterResponseWrapper( 91 | response); 92 | try { 93 | chain.doFilter(request, wrapper); 94 | } 95 | finally { 96 | stopWatch.stop(); 97 | int status = getStatus(wrapper); 98 | Object bestMatchingPattern = request 99 | .getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); 100 | if (bestMatchingPattern != null) { 101 | suffix = bestMatchingPattern.toString().replaceAll("[{}]", "-"); 102 | } 103 | else if (HttpStatus.valueOf(status).is4xxClientError()) { 104 | suffix = UNKNOWN_PATH_SUFFIX; 105 | } 106 | String gaugeKey = getKey("response" + suffix); 107 | meterRegistry.gauge(gaugeKey, 108 | stopWatch.getTotalTimeMillis()); 109 | String counterKey = getKey("status." + getStatus(wrapper) + suffix); 110 | meterRegistry.counter(counterKey); 111 | } 112 | } 113 | 114 | private int getStatus(MetricsFilterResponseWrapper response) { 115 | try { 116 | return response.getStatus(); 117 | } 118 | catch (Exception ex) { 119 | return UNDEFINED_HTTP_STATUS; 120 | } 121 | } 122 | 123 | private String getKey(String string) { 124 | // graphite compatible metric names 125 | String value = string.replace("/", "."); 126 | value = value.replace("..", "."); 127 | if (value.endsWith(".")) { 128 | value = value + "root"; 129 | } 130 | if (value.startsWith("_")) { 131 | value = value.substring(1); 132 | } 133 | return value; 134 | } 135 | } 136 | 137 | private class MetricsFilterResponseWrapper extends HttpServletResponseWrapper { 138 | 139 | private int status; 140 | 141 | public MetricsFilterResponseWrapper(HttpServletResponse response) { 142 | super(response); 143 | } 144 | 145 | public int getStatus() { 146 | return status; 147 | } 148 | 149 | @Override 150 | public void setStatus(int sc) { 151 | setStatus(sc, null); 152 | } 153 | 154 | @Override 155 | public void setStatus(int status, String sm) { 156 | this.status = status; 157 | super.setStatus(status, sm); 158 | } 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /spring-boot-legacy/src/main/java/org/springframework/boot/legacy/context/web/NonEmbeddedWebApplicationContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.boot.legacy.context.web; 18 | 19 | import java.util.Collection; 20 | import java.util.EventListener; 21 | 22 | import javax.servlet.Filter; 23 | import javax.servlet.Servlet; 24 | import javax.servlet.ServletConfig; 25 | import javax.servlet.ServletContext; 26 | import javax.servlet.ServletException; 27 | 28 | import org.apache.commons.logging.Log; 29 | import org.apache.commons.logging.LogFactory; 30 | 31 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 32 | import org.springframework.beans.factory.support.DefaultListableBeanFactory; 33 | import org.springframework.boot.web.servlet.LegacyServletContextInitializerBeans; 34 | import org.springframework.boot.web.servlet.ServletContextInitializer; 35 | import org.springframework.boot.web.servlet.ServletContextInitializerBeans; 36 | import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; 37 | import org.springframework.context.ApplicationContextException; 38 | import org.springframework.core.io.Resource; 39 | import org.springframework.web.context.ContextLoader; 40 | import org.springframework.web.context.ContextLoaderListener; 41 | import org.springframework.web.context.WebApplicationContext; 42 | import org.springframework.web.context.support.GenericWebApplicationContext; 43 | import org.springframework.web.context.support.ServletContextResource; 44 | import org.springframework.web.context.support.WebApplicationContextUtils; 45 | 46 | /** 47 | * A version of the {@link ServletWebServerApplicationContext} that can be used with a 48 | * SpringApplication in a web (i.e. servlet) context but does not require an embedded 49 | * servlet container. 50 | * 51 | * @author Daniel Cruver 52 | */ 53 | public class NonEmbeddedWebApplicationContext extends GenericWebApplicationContext { 54 | private ServletConfig servletConfig; 55 | 56 | private String namespace; 57 | 58 | /** 59 | * Create a new {@link NonEmbeddedWebApplicationContext}. 60 | */ 61 | public NonEmbeddedWebApplicationContext() { 62 | } 63 | 64 | /** 65 | * Create a new {@link ServletWebServerApplicationContext} with the given 66 | * {@code DefaultListableBeanFactory}. 67 | * @param beanFactory the DefaultListableBeanFactory instance to use for this context 68 | */ 69 | public NonEmbeddedWebApplicationContext(DefaultListableBeanFactory beanFactory) { 70 | super(beanFactory); 71 | } 72 | 73 | @Override 74 | protected void onRefresh() { 75 | super.onRefresh(); 76 | try { 77 | init(); 78 | } 79 | catch (Throwable ex) { 80 | throw new ApplicationContextException("Unable to start application context", 81 | ex); 82 | } 83 | } 84 | 85 | public void init() { 86 | ServletContext servletContext = getServletContext(); 87 | if (servletContext != null) { 88 | try { 89 | getSelfInitializer().onStartup(servletContext); 90 | } 91 | catch (ServletException ex) { 92 | throw new ApplicationContextException("Cannot initialize servlet context", 93 | ex); 94 | } 95 | } 96 | initPropertySources(); 97 | } 98 | 99 | @Override 100 | public void setServletContext(ServletContext servletContext) { 101 | super.setServletContext(servletContext); 102 | // prepareWebApplicationContext(servletContext); 103 | } 104 | 105 | /** 106 | * Returns the {@link ServletContextInitializer} that will be used to complete the 107 | * setup of this {@link WebApplicationContext}. 108 | * @return the self initializer 109 | * @see #prepareWebApplicationContext(ServletContext) 110 | */ 111 | private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() { 112 | return this::selfInitialize; 113 | } 114 | 115 | private void selfInitialize(ServletContext servletContext) throws ServletException { 116 | prepareWebApplicationContext(servletContext); 117 | ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 118 | 119 | ServletWebServerApplicationContext.ExistingWebApplicationScopes existingScopes = 120 | new ServletWebServerApplicationContext.ExistingWebApplicationScopes(beanFactory); 121 | 122 | WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, getServletContext()); 123 | existingScopes.restore(); 124 | 125 | WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, getServletContext()); 126 | 127 | Collection servletContextInitializerBeans; 128 | 129 | if (servletContext.getMajorVersion() >= 3) { 130 | servletContextInitializerBeans = getServletContextInitializerBeans(); 131 | } 132 | else { 133 | servletContextInitializerBeans = getLegacyServletContextInitializerBeans(); 134 | } 135 | 136 | for (ServletContextInitializer beans : servletContextInitializerBeans) { 137 | beans.onStartup(servletContext); 138 | } 139 | 140 | } 141 | 142 | /** 143 | * Returns {@link ServletContextInitializer}s that should be used with the embedded 144 | * web server. By default this method will first attempt to find 145 | * {@link ServletContextInitializer}, {@link Servlet}, {@link Filter} and certain 146 | * {@link EventListener} beans. 147 | * @return the servlet initializer beans 148 | */ 149 | protected Collection getServletContextInitializerBeans() { 150 | return new ServletContextInitializerBeans(getBeanFactory()); 151 | } 152 | 153 | /** 154 | * Returns {@link ServletContextInitializer}s that should be used in 2.5 Servlet. 155 | * {@link ServletContextInitializer}, {@link Servlet}, {@link Filter} and certain 156 | * {@link EventListener} beans. 157 | * @return the servlet initializer beans 158 | */ 159 | protected Collection getLegacyServletContextInitializerBeans() { 160 | return new LegacyServletContextInitializerBeans(getBeanFactory()); 161 | } 162 | 163 | /** 164 | * Prepare the {@link WebApplicationContext} with the given fully loaded 165 | * {@link ServletContext}. This method is usually called from 166 | * {@link ServletContextInitializer#onStartup(ServletContext)} and is similar to the 167 | * functionality usually provided by a {@link ContextLoaderListener}. 168 | * @param servletContext the operational servlet context 169 | */ 170 | protected void prepareWebApplicationContext(ServletContext servletContext) { 171 | Object rootContext = servletContext 172 | .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); 173 | if (rootContext != null) { 174 | if (rootContext == this) { 175 | throw new IllegalStateException( 176 | "Cannot initialize context because there is already a root application context present - " 177 | + "check whether you have multiple ServletContextInitializers!"); 178 | } 179 | else { 180 | return; 181 | } 182 | } 183 | Log logger = LogFactory.getLog(ContextLoader.class); 184 | servletContext.log("Initializing Spring Boot Legacy WebApplicationContext"); 185 | WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory(), 186 | getServletContext()); 187 | WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), 188 | getServletContext()); 189 | try { 190 | servletContext.setAttribute( 191 | WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this); 192 | if (logger.isDebugEnabled()) { 193 | logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" 194 | + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 195 | + "]"); 196 | } 197 | setServletContext(servletContext); 198 | if (logger.isInfoEnabled()) { 199 | long elapsedTime = System.currentTimeMillis() - getStartupDate(); 200 | logger.info("Root WebApplicationContext: initialization completed in " 201 | + elapsedTime + " ms"); 202 | } 203 | } 204 | catch (RuntimeException ex) { 205 | logger.error("Context initialization failed", ex); 206 | servletContext.setAttribute( 207 | WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); 208 | throw ex; 209 | } 210 | catch (Error ex) { 211 | logger.error("Context initialization failed", ex); 212 | servletContext.setAttribute( 213 | WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); 214 | throw ex; 215 | } 216 | } 217 | 218 | @Override 219 | protected Resource getResourceByPath(String path) { 220 | if (getServletContext() == null) { 221 | return new ClassPathContextResource(path, getClassLoader()); 222 | } 223 | return new ServletContextResource(getServletContext(), path); 224 | } 225 | 226 | @Override 227 | public String getNamespace() { 228 | return this.namespace; 229 | } 230 | 231 | @Override 232 | public void setNamespace(String namespace) { 233 | this.namespace = namespace; 234 | } 235 | 236 | @Override 237 | public ServletConfig getServletConfig() { 238 | return this.servletConfig; 239 | } 240 | 241 | @Override 242 | public void setServletConfig(ServletConfig servletConfig) { 243 | this.servletConfig = servletConfig; 244 | } 245 | 246 | } 247 | -------------------------------------------------------------------------------- /spring-boot-legacy/src/main/java/org/springframework/boot/legacy/context/web/SecurityFilterAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.boot.legacy.context.web; 17 | 18 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 23 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 24 | import org.springframework.context.annotation.Bean; 25 | import org.springframework.context.annotation.Configuration; 26 | import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; 27 | 28 | @Configuration 29 | @ConditionalOnWebApplication 30 | @EnableConfigurationProperties 31 | @ConditionalOnClass(AbstractSecurityWebApplicationInitializer.class) 32 | @ConditionalOnMissingClass("javax.servlet.AsyncContext") 33 | @AutoConfigureAfter(name = "org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration") 34 | public class SecurityFilterAutoConfiguration { 35 | 36 | private static final String DEFAULT_FILTER_NAME = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME; 37 | 38 | @Bean 39 | @ConditionalOnBean(name = DEFAULT_FILTER_NAME) 40 | public Object securityFilterChainRegistration() { 41 | return new Object(); 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /spring-boot-legacy/src/main/java/org/springframework/boot/legacy/context/web/SpringBootContextLoaderListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.boot.legacy.context.web; 18 | 19 | import java.util.Arrays; 20 | import java.util.Collections; 21 | 22 | import javax.servlet.ServletContext; 23 | 24 | import org.apache.commons.logging.Log; 25 | import org.apache.commons.logging.LogFactory; 26 | import org.springframework.beans.BeanUtils; 27 | import org.springframework.boot.SpringApplication; 28 | import org.springframework.boot.builder.ParentContextApplicationContextInitializer; 29 | import org.springframework.boot.builder.SpringApplicationBuilder; 30 | import org.springframework.boot.legacy.context.web.servlet.support.ErrorPageFilterConfiguration; 31 | import org.springframework.boot.web.servlet.support.ErrorPageFilter; 32 | import org.springframework.context.ApplicationContext; 33 | import org.springframework.context.ApplicationContextException; 34 | import org.springframework.context.ApplicationContextInitializer; 35 | import org.springframework.context.ConfigurableApplicationContext; 36 | import org.springframework.context.annotation.Configuration; 37 | import org.springframework.core.annotation.AnnotationUtils; 38 | import org.springframework.util.Assert; 39 | import org.springframework.util.ClassUtils; 40 | import org.springframework.util.StringUtils; 41 | import org.springframework.web.context.ContextLoaderListener; 42 | import org.springframework.web.context.ConfigurableWebApplicationContext; 43 | import org.springframework.web.context.WebApplicationContext; 44 | import org.springframework.web.context.support.StandardServletEnvironment; 45 | 46 | /** 47 | * A {@link ContextLoaderListener} that uses {@link SpringApplication} to initialize an 48 | * application context. Allows Servlet 2.5 applications (with web.xml) to take advantage 49 | * of all the initialization extras in Spring Boot even if they don't use an embedded 50 | * container. 51 | * 52 | * @author Daniel Cruver 53 | * @author Dave Syer 54 | */ 55 | public class SpringBootContextLoaderListener extends ContextLoaderListener { 56 | 57 | /** 58 | * Name of servlet context parameter (i.e., {@value}) that can specify to 59 | * disable registration of error page filter. 60 | * 61 | * @see org.springframework.boot.web.servlet.support.SpringBootServletInitializer#setRegisterErrorPageFilter(boolean) 62 | */ 63 | public static final String SPRING_BOOT_LEGACY_REGISTER_ERROR_PAGE_FILTER_PARAM = "springBootLegacyRegisterErrorPageFilter"; 64 | 65 | private static final String INIT_PARAM_DELIMITERS = ",; \t\n"; 66 | 67 | protected Log logger; // Don't initialize early 68 | 69 | private boolean registerErrorPageFilter = true; 70 | 71 | /** 72 | * Set if the {@link ErrorPageFilter} should be registered. Set to {@code false} if 73 | * error page mappings should be handled via the server and not Spring Boot. 74 | * 75 | * This method is a clone from {@link org.springframework.boot.web.servlet.support.SpringBootServletInitializer} but since 76 | * we are initializing it differently, we can not call this method on the {@link ContextLoaderListener} a servlet context 77 | * param {@link #SPRING_BOOT_LEGACY_REGISTER_ERROR_PAGE_FILTER_PARAM} has been provided for setting this value. 78 | * 79 | * @param registerErrorPageFilter if the {@link ErrorPageFilter} should be registered. 80 | */ 81 | protected final void setRegisterErrorPageFilter(boolean registerErrorPageFilter) { 82 | this.registerErrorPageFilter = registerErrorPageFilter; 83 | } 84 | 85 | @Override 86 | public WebApplicationContext initWebApplicationContext( 87 | final ServletContext servletContext) { 88 | this.logger = LogFactory.getLog(getClass()); 89 | this.logger.debug("Initializing WebApplicationContext"); 90 | String configLocationParam = servletContext.getInitParameter(CONFIG_LOCATION_PARAM); 91 | String[] classNames = StringUtils.tokenizeToStringArray(configLocationParam, INIT_PARAM_DELIMITERS); 92 | 93 | setRegisterErrorPageFilterFromContextParam(servletContext); 94 | 95 | SpringApplicationBuilder builder = createSpringApplicationBuilder(classNames); 96 | 97 | StandardServletEnvironment environment = new StandardServletEnvironment(); 98 | environment.initPropertySources(servletContext, null); 99 | builder.environment(environment); 100 | 101 | setMainClass(builder, classNames); 102 | 103 | @SuppressWarnings("unchecked") 104 | Class contextClass = (Class) determineContextClass(servletContext); 105 | builder.contextFactory((type) -> (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass)); 106 | 107 | ApplicationContext parent = getExistingRootWebApplicationContext(servletContext); 108 | 109 | if (parent != null) { 110 | this.logger.info("Root context already created (using as parent)."); 111 | servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null); 112 | builder.initializers(new ParentContextApplicationContextInitializer(parent)); 113 | } 114 | 115 | builder.initializers((ApplicationContextInitializer) applicationContext -> applicationContext.setServletContext(servletContext)); 116 | 117 | // Ensure error pages are registered 118 | if (this.registerErrorPageFilter) { 119 | builder.sources(ErrorPageFilterConfiguration.class); 120 | } 121 | 122 | SpringApplication application = builder.build(); 123 | 124 | if (application.getAllSources().isEmpty() && AnnotationUtils.findAnnotation(getClass(), Configuration.class) != null) { 125 | application.addPrimarySources(Collections.singleton(getClass())); 126 | } 127 | 128 | Assert.state(!application.getAllSources().isEmpty(), 129 | "No SpringApplication sources have been defined. Either override the " 130 | + "configure method or add an @Configuration annotation"); 131 | 132 | WebApplicationContext context = (WebApplicationContext) application.run(); 133 | servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context); 134 | return context; 135 | } 136 | 137 | private void setMainClass(SpringApplicationBuilder builder, String[] classNames) { 138 | try { 139 | builder.main(Class.forName(classNames[0])); 140 | } 141 | catch (ClassNotFoundException e) { 142 | this.logger.warn("Could create instance of class " + classNames[0] + " provided by " + CONFIG_LOCATION_PARAM, e); 143 | } 144 | } 145 | 146 | private void setRegisterErrorPageFilterFromContextParam(ServletContext servletContext) { 147 | String contextParamValue = servletContext.getInitParameter(SPRING_BOOT_LEGACY_REGISTER_ERROR_PAGE_FILTER_PARAM); 148 | 149 | if (contextParamValue == null) { 150 | this.logger.debug("No context init parameter found for " + SPRING_BOOT_LEGACY_REGISTER_ERROR_PAGE_FILTER_PARAM + "; leaving it at default value: " + this.registerErrorPageFilter); 151 | } 152 | else if (StringUtils.hasText(contextParamValue)) { 153 | boolean booleanValue = Boolean.parseBoolean(contextParamValue); 154 | setRegisterErrorPageFilter(booleanValue); 155 | this.logger.debug("Found context init parameter found for " + SPRING_BOOT_LEGACY_REGISTER_ERROR_PAGE_FILTER_PARAM + "; updating registerErrorPageFilter to " + this.registerErrorPageFilter); 156 | } 157 | else { 158 | this.logger.warn("Context init parameter found for " + SPRING_BOOT_LEGACY_REGISTER_ERROR_PAGE_FILTER_PARAM + " but it is empty; leaving it at default value: " + this.registerErrorPageFilter); 159 | } 160 | } 161 | 162 | protected SpringApplicationBuilder createSpringApplicationBuilder(String[] classNames) { 163 | 164 | if (this.logger.isDebugEnabled()) { 165 | this.logger.debug("Creating SpringApplicationBuilder ( with classes: " + Arrays.toString(classNames) + ")"); 166 | } 167 | 168 | Class[] classes = new Class[classNames.length]; 169 | for (int i = 0; i < classes.length; i++) { 170 | try { 171 | classes[i] = ClassUtils.forName(classNames[i], null); 172 | } 173 | catch (ClassNotFoundException e) { 174 | throw new ApplicationContextException( 175 | "Failed to load custom context class [" + classNames[i] + "]", e); 176 | } 177 | } 178 | 179 | return new SpringApplicationBuilder(classes); 180 | } 181 | 182 | private ApplicationContext getExistingRootWebApplicationContext(ServletContext servletContext) { 183 | Object context = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); 184 | if (context instanceof ApplicationContext) { 185 | return (ApplicationContext) context; 186 | } 187 | return null; 188 | } 189 | 190 | @Override 191 | protected Class determineContextClass(ServletContext servletContext) { 192 | this.logger = LogFactory.getLog(getClass()); 193 | String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM); 194 | 195 | if (contextClassName != null) { 196 | this.logger.info("Using context class: " + contextClassName); 197 | try { 198 | return ClassUtils.forName(contextClassName, null); 199 | } 200 | catch (Exception e) { 201 | throw new ApplicationContextException( 202 | "Failed to load custom context class [" + contextClassName + "]", 203 | e); 204 | } 205 | } 206 | 207 | logger.debug("Using default context class: " + AnnotationConfigNonEmbeddedWebApplicationContext.class.getCanonicalName() + ""); 208 | return AnnotationConfigNonEmbeddedWebApplicationContext.class; 209 | } 210 | 211 | } 212 | -------------------------------------------------------------------------------- /spring-boot-legacy/src/main/java/org/springframework/boot/legacy/context/web/servlet/support/ErrorPageFilterConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 CUBRC, Inc. - Unpublished Work - All rights reserved under the copyright laws of the United States. 3 | * CUBRC, Inc. does not grant permission to any party outside the United States Government to use, disclose, copy, or make derivative works of this software. 4 | */ 5 | 6 | package org.springframework.boot.legacy.context.web.servlet.support; 7 | 8 | import org.springframework.boot.web.servlet.support.ErrorPageFilter; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | /** 13 | * Configuration for {@link ErrorPageFilter}. 14 | * 15 | * NOTE: Original class {@link ErrorPageFilterConfiguration} is not accessible. 16 | * 17 | * @author Daniel Cruver 18 | * @author Andy Wilkinson 19 | */ 20 | @Configuration 21 | public class ErrorPageFilterConfiguration { 22 | 23 | @Bean 24 | public ErrorPageFilter errorPageFilter() { 25 | return new ErrorPageFilter(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-boot-legacy/src/main/java/org/springframework/boot/web/servlet/LegacyServletContextInitializerBeans.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.boot.web.servlet; 18 | 19 | import java.util.AbstractCollection; 20 | import java.util.ArrayList; 21 | import java.util.Collections; 22 | import java.util.Comparator; 23 | import java.util.EventListener; 24 | import java.util.HashSet; 25 | import java.util.Iterator; 26 | import java.util.LinkedHashMap; 27 | import java.util.List; 28 | import java.util.Map; 29 | import java.util.Map.Entry; 30 | import java.util.Set; 31 | 32 | import javax.servlet.Filter; 33 | import javax.servlet.Servlet; 34 | 35 | import org.apache.commons.logging.Log; 36 | import org.apache.commons.logging.LogFactory; 37 | 38 | import org.springframework.aop.scope.ScopedProxyUtils; 39 | import org.springframework.beans.factory.ListableBeanFactory; 40 | import org.springframework.beans.factory.support.BeanDefinitionRegistry; 41 | import org.springframework.core.annotation.AnnotationAwareOrderComparator; 42 | import org.springframework.util.LinkedMultiValueMap; 43 | import org.springframework.util.MultiValueMap; 44 | 45 | /** 46 | * A copy of org.springframework.boot.web.servlet.ServletContextInitializerBeans without Servlet 3.0 API calls. 47 | * 48 | * A collection {@link ServletContextInitializer}s obtained from a 49 | * {@link ListableBeanFactory}. Includes all {@link ServletContextInitializer} beans and 50 | * also adapts {@link Servlet}, {@link Filter} and certain {@link EventListener} beans. 51 | *

52 | * Items are sorted so that adapted beans are top ({@link Servlet}, {@link Filter} then 53 | * {@link EventListener}) and direct {@link ServletContextInitializer} beans are at the 54 | * end. Further sorting is applied within these groups using the 55 | * {@link AnnotationAwareOrderComparator}. 56 | * 57 | * @author Dave Syer 58 | * @author Phillip Webb 59 | * @author Daniel Cruver 60 | * @since 2.0.0 61 | */ 62 | public class LegacyServletContextInitializerBeans 63 | extends AbstractCollection { 64 | 65 | private static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet"; 66 | 67 | private static final Log logger = LogFactory 68 | .getLog(ServletContextInitializerBeans.class); 69 | 70 | /** 71 | * Seen bean instances or bean names. 72 | */ 73 | private final Set seen = new HashSet<>(); 74 | 75 | private final MultiValueMap, ServletContextInitializer> initializers; 76 | 77 | private List sortedList; 78 | 79 | public LegacyServletContextInitializerBeans(ListableBeanFactory beanFactory) { 80 | this.initializers = new LinkedMultiValueMap<>(); 81 | addServletContextInitializerBeans(beanFactory); 82 | addAdaptableBeans(beanFactory); 83 | List sortedInitializers = new ArrayList<>(); 84 | this.initializers.values().forEach((contextInitializers) -> { 85 | AnnotationAwareOrderComparator.sort(contextInitializers); 86 | sortedInitializers.addAll(contextInitializers); 87 | }); 88 | this.sortedList = Collections.unmodifiableList(sortedInitializers); 89 | } 90 | 91 | private void addServletContextInitializerBeans(ListableBeanFactory beanFactory) { 92 | for (Entry initializerBean : getOrderedBeansOfType( 93 | beanFactory, ServletContextInitializer.class)) { 94 | addServletContextInitializerBean(initializerBean.getKey(), 95 | initializerBean.getValue(), beanFactory); 96 | } 97 | } 98 | 99 | private void addServletContextInitializerBean(String beanName, 100 | ServletContextInitializer initializer, ListableBeanFactory beanFactory) { 101 | if (initializer instanceof ServletRegistrationBean) { 102 | Servlet source = ((ServletRegistrationBean) initializer).getServlet(); 103 | addServletContextInitializerBean(Servlet.class, beanName, initializer, 104 | beanFactory, source); 105 | } 106 | else if (initializer instanceof FilterRegistrationBean) { 107 | Filter source = ((FilterRegistrationBean) initializer).getFilter(); 108 | addServletContextInitializerBean(Filter.class, beanName, initializer, 109 | beanFactory, source); 110 | } 111 | else if (initializer instanceof DelegatingFilterProxyRegistrationBean) { 112 | String source = ((DelegatingFilterProxyRegistrationBean) initializer).getTargetBeanName(); 113 | addServletContextInitializerBean(Filter.class, beanName, initializer, 114 | beanFactory, source); 115 | } 116 | else if (initializer instanceof ServletListenerRegistrationBean) { 117 | EventListener source = ((ServletListenerRegistrationBean) initializer) 118 | .getListener(); 119 | addServletContextInitializerBean(EventListener.class, beanName, initializer, 120 | beanFactory, source); 121 | } 122 | else { 123 | addServletContextInitializerBean(ServletContextInitializer.class, beanName, 124 | initializer, beanFactory, initializer); 125 | } 126 | } 127 | 128 | private void addServletContextInitializerBean(Class type, String beanName, 129 | ServletContextInitializer initializer, ListableBeanFactory beanFactory, 130 | Object source) { 131 | this.initializers.add(type, initializer); 132 | if (source != null) { 133 | // Mark the underlying source as seen in case it wraps an existing bean 134 | this.seen.add(source); 135 | } 136 | if (logger.isDebugEnabled()) { 137 | String resourceDescription = getResourceDescription(beanName, beanFactory); 138 | int order = getOrder(initializer); 139 | logger.debug("Added existing " 140 | + type.getSimpleName() + " initializer bean '" + beanName 141 | + "'; order=" + order + ", resource=" + resourceDescription); 142 | } 143 | } 144 | 145 | private String getResourceDescription(String beanName, 146 | ListableBeanFactory beanFactory) { 147 | if (beanFactory instanceof BeanDefinitionRegistry) { 148 | BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; 149 | return registry.getBeanDefinition(beanName).getResourceDescription(); 150 | } 151 | return "unknown"; 152 | } 153 | 154 | @SuppressWarnings("unchecked") 155 | private void addAdaptableBeans(ListableBeanFactory beanFactory) { 156 | addAsRegistrationBean(beanFactory, Servlet.class, 157 | new ServletRegistrationBeanAdapter()); 158 | addAsRegistrationBean(beanFactory, Filter.class, 159 | new FilterRegistrationBeanAdapter()); 160 | for (Class listenerType : ServletListenerRegistrationBean 161 | .getSupportedTypes()) { 162 | addAsRegistrationBean(beanFactory, EventListener.class, 163 | (Class) listenerType, 164 | new ServletListenerRegistrationBeanAdapter()); 165 | } 166 | } 167 | 168 | private void addAsRegistrationBean(ListableBeanFactory beanFactory, Class type, 169 | RegistrationBeanAdapter adapter) { 170 | addAsRegistrationBean(beanFactory, type, type, adapter); 171 | } 172 | 173 | private void addAsRegistrationBean(ListableBeanFactory beanFactory, 174 | Class type, Class beanType, RegistrationBeanAdapter adapter) { 175 | List> beans = getOrderedBeansOfType(beanFactory, beanType, 176 | this.seen); 177 | for (Entry bean : beans) { 178 | if (this.seen.add(bean.getValue())) { 179 | int order = getOrder(bean.getValue()); 180 | String beanName = bean.getKey(); 181 | // One that we haven't already seen 182 | RegistrationBean registration = adapter.createRegistrationBean(beanName, 183 | bean.getValue(), beans.size()); 184 | registration.setOrder(order); 185 | this.initializers.add(type, registration); 186 | if (logger.isDebugEnabled()) { 187 | logger.debug( 188 | "Created " + type.getSimpleName() + " initializer for bean '" 189 | + beanName + "'; order=" + order + ", resource=" 190 | + getResourceDescription(beanName, beanFactory)); 191 | } 192 | } 193 | } 194 | } 195 | 196 | private int getOrder(Object value) { 197 | return new AnnotationAwareOrderComparator() { 198 | @Override 199 | public int getOrder(Object obj) { 200 | return super.getOrder(obj); 201 | } 202 | }.getOrder(value); 203 | } 204 | 205 | private List> getOrderedBeansOfType( 206 | ListableBeanFactory beanFactory, Class type) { 207 | return getOrderedBeansOfType(beanFactory, type, Collections.emptySet()); 208 | } 209 | 210 | private List> getOrderedBeansOfType( 211 | ListableBeanFactory beanFactory, Class type, Set excludes) { 212 | Comparator> comparator = (o1, 213 | o2) -> AnnotationAwareOrderComparator.INSTANCE.compare(o1.getValue(), 214 | o2.getValue()); 215 | String[] names = beanFactory.getBeanNamesForType(type, true, false); 216 | Map map = new LinkedHashMap<>(); 217 | for (String name : names) { 218 | if (!excludes.contains(name) && !ScopedProxyUtils.isScopedTarget(name)) { 219 | T bean = beanFactory.getBean(name, type); 220 | if (!excludes.contains(bean)) { 221 | map.put(name, bean); 222 | } 223 | } 224 | } 225 | List> beans = new ArrayList<>(); 226 | beans.addAll(map.entrySet()); 227 | beans.sort(comparator); 228 | return beans; 229 | } 230 | 231 | @Override 232 | public Iterator iterator() { 233 | return this.sortedList.iterator(); 234 | } 235 | 236 | @Override 237 | public int size() { 238 | return this.sortedList.size(); 239 | } 240 | 241 | /** 242 | * Adapter to convert a given Bean type into a {@link RegistrationBean} (and hence a 243 | * {@link ServletContextInitializer}). 244 | */ 245 | private interface RegistrationBeanAdapter { 246 | 247 | RegistrationBean createRegistrationBean(String name, T source, 248 | int totalNumberOfSourceBeans); 249 | 250 | } 251 | 252 | /** 253 | * {@link RegistrationBeanAdapter} for {@link Servlet} beans. 254 | */ 255 | private static class ServletRegistrationBeanAdapter 256 | implements RegistrationBeanAdapter { 257 | 258 | @Override 259 | public RegistrationBean createRegistrationBean(String name, Servlet source, 260 | int totalNumberOfSourceBeans) { 261 | String url = (totalNumberOfSourceBeans != 1 ? "/" + name + "/" : "/"); 262 | if (name.equals(DISPATCHER_SERVLET_NAME)) { 263 | url = "/"; // always map the main dispatcherServlet to "/" 264 | } 265 | ServletRegistrationBean bean = new ServletRegistrationBean<>(source, 266 | url); 267 | bean.setName(name); 268 | // bean.setMultipartConfig(this.multipartConfig); 269 | return bean; 270 | } 271 | 272 | } 273 | 274 | /** 275 | * {@link RegistrationBeanAdapter} for {@link Filter} beans. 276 | */ 277 | private static class FilterRegistrationBeanAdapter 278 | implements RegistrationBeanAdapter { 279 | 280 | @Override 281 | public RegistrationBean createRegistrationBean(String name, Filter source, 282 | int totalNumberOfSourceBeans) { 283 | FilterRegistrationBean bean = new FilterRegistrationBean<>(source); 284 | bean.setName(name); 285 | return bean; 286 | } 287 | 288 | } 289 | 290 | /** 291 | * {@link RegistrationBeanAdapter} for certain {@link EventListener} beans. 292 | */ 293 | private static class ServletListenerRegistrationBeanAdapter 294 | implements RegistrationBeanAdapter { 295 | 296 | @Override 297 | public RegistrationBean createRegistrationBean(String name, EventListener source, 298 | int totalNumberOfSourceBeans) { 299 | return new ServletListenerRegistrationBean<>(source); 300 | } 301 | 302 | } 303 | 304 | } 305 | -------------------------------------------------------------------------------- /spring-boot-legacy/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | # Auto Configure 2 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 3 | org.springframework.boot.legacy.context.web.MetricFilterAutoConfiguration,\ 4 | org.springframework.boot.legacy.context.web.SecurityFilterAutoConfiguration 5 | -------------------------------------------------------------------------------- /spring-boot-legacy/src/test/java/org/springframework/boot/legacy/context/web/AnnotationConfigNonEmbeddedWebApplicationContextTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-2014 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.boot.legacy.context.web; 17 | 18 | import org.junit.jupiter.api.Test; 19 | import org.springframework.boot.builder.SpringApplicationBuilder; 20 | import org.springframework.context.ConfigurableApplicationContext; 21 | import org.springframework.context.annotation.Configuration; 22 | 23 | /** 24 | * @author Dave Syer 25 | * 26 | */ 27 | public class AnnotationConfigNonEmbeddedWebApplicationContextTests { 28 | 29 | @Test 30 | public void test() { 31 | ConfigurableApplicationContext context = new SpringApplicationBuilder( 32 | TestConfiguration.class).contextFactory(type -> 33 | new AnnotationConfigNonEmbeddedWebApplicationContext()).run(); 34 | context.close(); 35 | } 36 | 37 | @Configuration 38 | protected static class TestConfiguration { 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /spring-boot-legacy/src/test/java/org/springframework/boot/legacy/context/web/SpringBootContextLoaderListenerTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-2014 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.boot.legacy.context.web; 17 | 18 | import static org.junit.jupiter.api.Assertions.assertNotNull; 19 | 20 | import java.util.Collections; 21 | 22 | import javax.servlet.ServletContext; 23 | 24 | import org.junit.jupiter.api.Test; 25 | import org.mockito.Mockito; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.web.context.ContextLoader; 28 | 29 | /** 30 | * @author Dave Syer 31 | * 32 | */ 33 | public class SpringBootContextLoaderListenerTests { 34 | 35 | private ServletContext servletContext = Mockito.mock(ServletContext.class); 36 | 37 | @Test 38 | public void test() { 39 | Mockito.when(servletContext.getInitParameterNames()).thenReturn( 40 | Collections.emptyEnumeration()); 41 | Mockito.when(servletContext.getAttributeNames()).thenReturn( 42 | Collections.emptyEnumeration()); 43 | Mockito.when(servletContext.getInitParameter(ContextLoader.CONFIG_LOCATION_PARAM)) 44 | .thenReturn(TestConfiguration.class.getName()); 45 | SpringBootContextLoaderListener listener = new SpringBootContextLoaderListener(); 46 | assertNotNull(listener.initWebApplicationContext(servletContext)); 47 | } 48 | 49 | @Configuration 50 | protected static class TestConfiguration { 51 | 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-boot-samples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.7.5 10 | 11 | 12 | 13 | spring-boot-samples 14 | 0.0.1-SNAPSHOT 15 | pom 16 | 17 | Spring Boot Samples 18 | Spring Boot Samples Parent Project 19 | 20 | 21 | 22 | 1.8 23 | 24 | UTF-8 25 | UTF-8 26 | 27 | 28 | 29 | spring-boot-sample-gae-2.5 30 | spring-boot-sample-gae-3.1 31 | spring-boot-sample-secure-legacy 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-deploy-plugin 40 | 41 | true 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/README.md: -------------------------------------------------------------------------------- 1 | Simple Spring Boot app that runs on Google AppEngine. No attempt has been made to use the Google APIs - just a minimal Spring app that works. 2 | 3 | Google App Engine Java 8 Runtime with Servlet 2.5 does require [spring-boot-legacy](https://github.com/scratches/spring-boot-legacy)! 4 | 5 | To Test Locally: 6 | ``` 7 | $ git clone https://github.com/dyser/spring-boot-legacy 8 | $ cd spring-boot-legacy 9 | $ mvn clean install 10 | $ cd spring-boot-samples/spring-boot-sample-gae-2.5 11 | $ mvn appengine:devserver 12 | ``` 13 | 14 | To Deploy: 15 | ``` 16 | $ git clone https://github.com/dyser/spring-boot-legacy 17 | $ cd spring-boot-legacy 18 | $ mvn clean install 19 | $ cd spring-boot-samples/spring-boot-sample-gae-2.5 20 | $ mvn appengine:update 21 | $ mvn appengine:update -Dgae.appId=$ 22 | $ 23 | ``` 24 | 25 | To Deploy to specific AppEngine Project and Version: 26 | ``` 27 | $ git clone https://github.com/dyser/spring-boot-legacy 28 | $ cd spring-boot-legacy 29 | $ mvn clean install 30 | $ cd spring-boot-samples/spring-boot-sample-gae-2.5 31 | $ mvn appengine:update -Dgae.appId=${APP_ENGINE_PROJECT_ID} -Dgae.version=${APP_ENGINE_PROJECT_VERSION} 32 | $ 33 | ``` 34 | 35 | Also runs as a deployed WAR in WTP or regular Tomcat container. The `main()` app (normal Spring Boot launcher) should also work. 36 | 37 | > NOTE: Google AppEngine does not allow JMX, so you have to switch it off in a Spring Boot app (`spring.jmx.enabled=false`). 38 | 39 | > WARNING: Spring Boot manages the appengine API version, which is nice. This project overrides it by virtue of using the `spring-boot-starter-parent` and defining the `appengine.version`. But beware, because `appengine.version` has a specific (other) meaning to the appengine Maven plugin, so we also have to define `gae.version` and use that to set the application version in the plugin configuration. 40 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-samples 8 | 0.0.1-SNAPSHOT 9 | 10 | spring-boot-sample-gae-2.5 11 | 0.0.1-SNAPSHOT 12 | war 13 | 14 | Spring Boot Sample GAE 2.5 15 | Spring Boot Sample in Google AppEngine using Java 8 Runtime with Servlet 2.5 (w/Spring Boot Legacy) 16 | 17 | 18 | demo.Application 19 | 20 | / 21 | 22 | 1.9.63 23 | 24 | cf-sandbox-dsyer 25 | 5 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-legacy 32 | 2.7.0-SNAPSHOT 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-actuator 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-security 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-logging 48 | 49 | 50 | ch.qos.logback 51 | logback-classic 52 | 53 | 54 | org.slf4j 55 | jul-to-slf4j 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-web 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-starter-tomcat 67 | 68 | 69 | 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-starter-jetty 74 | provided 75 | 76 | 77 | 78 | org.slf4j 79 | slf4j-jdk14 80 | runtime 81 | 82 | 83 | 84 | org.slf4j 85 | jul-to-slf4j 86 | provided 87 | 88 | 89 | 90 | javax.servlet 91 | javax.servlet-api 92 | provided 93 | 94 | 95 | 96 | 97 | 98 | org.springframework.boot 99 | spring-boot-starter-test 100 | test 101 | 102 | 103 | 104 | org.springframework.security 105 | spring-security-test 106 | test 107 | 108 | 109 | 110 | com.google.appengine 111 | appengine-api-labs 112 | ${appengine.version} 113 | test 114 | 115 | 116 | com.google.appengine 117 | appengine-api-stubs 118 | ${appengine.version} 119 | test 120 | 121 | 122 | com.google.appengine 123 | appengine-testing 124 | ${appengine.version} 125 | test 126 | 127 | 128 | 129 | org.apache.httpcomponents 130 | httpclient 131 | test 132 | 133 | 134 | 135 | 136 | 137 | 138 | org.apache.maven.plugins 139 | maven-war-plugin 140 | 141 | WEB-INF/lib/websocket-*.jar 142 | 143 | 144 | 145 | org.springframework.boot 146 | spring-boot-maven-plugin 147 | 148 | 149 | com.google.appengine 150 | appengine-maven-plugin 151 | ${appengine.version} 152 | 153 | ${gae.appId} 154 | ${gae.version} 155 | true 156 | 8181 157 | 158 | 159 | 160 | org.apache.maven.plugins 161 | maven-release-plugin 162 | 163 | appengine:update 164 | 165 | 166 | 167 | org.apache.tomcat.maven 168 | tomcat6-maven-plugin 169 | 2.2 170 | 171 | / 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | integration 180 | 181 | 182 | 183 | org.apache.maven.plugins 184 | maven-failsafe-plugin 185 | 186 | 187 | failsafe-it 188 | integration-test 189 | 190 | integration-test 191 | 192 | 193 | ${skipTests} 194 | 195 | **/NonEmbedded*Tests.java 196 | 197 | 198 | 199 | 200 | 201 | 202 | org.apache.tomcat.maven 203 | tomcat6-maven-plugin 204 | 205 | 206 | start-tomcat 207 | pre-integration-test 208 | 209 | run 210 | 211 | 212 | / 213 | true 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | spring-snapshots 226 | Spring Snapshots 227 | http://repo.spring.io/snapshot 228 | 229 | true 230 | 231 | 232 | 233 | spring-milestones 234 | Spring Milestones 235 | http://repo.spring.io/milestone 236 | 237 | false 238 | 239 | 240 | 241 | 242 | 243 | spring-snapshots 244 | Spring Snapshots 245 | http://repo.spring.io/snapshot 246 | 247 | true 248 | 249 | 250 | 251 | spring-milestones 252 | Spring Milestones 253 | http://repo.spring.io/milestone 254 | 255 | false 256 | 257 | 258 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo; 18 | 19 | import java.util.Arrays; 20 | import java.util.logging.Level; 21 | import java.util.logging.Logger; 22 | 23 | import javax.servlet.ServletContext; 24 | 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.beans.factory.annotation.Value; 27 | import org.springframework.boot.CommandLineRunner; 28 | import org.springframework.boot.SpringApplication; 29 | import org.springframework.boot.autoconfigure.SpringBootApplication; 30 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 31 | import org.springframework.context.ApplicationContext; 32 | import org.springframework.context.annotation.Bean; 33 | import org.springframework.web.bind.annotation.RequestMapping; 34 | import org.springframework.web.bind.annotation.RestController; 35 | 36 | @SpringBootApplication 37 | @RestController 38 | public class Application extends SpringBootServletInitializer { 39 | 40 | private static final java.util.logging.Logger logger = Logger.getLogger(Application.class.getCanonicalName()); 41 | 42 | @Autowired 43 | private ServletContext context; 44 | 45 | @Value("${info.version}") 46 | private String version; 47 | 48 | public static void main(String[] args) { 49 | SpringApplication.run(Application.class, args); 50 | } 51 | 52 | @Bean 53 | public CommandLineRunner commandLineRunner(ApplicationContext ctx) { 54 | return args -> { 55 | 56 | String[] beanNames = ctx.getBeanDefinitionNames(); 57 | Arrays.sort(beanNames); 58 | 59 | StringBuilder beans = new StringBuilder(); 60 | 61 | beans.append("Spring Boot Beans: "); 62 | 63 | for (String beanName : beanNames) { 64 | beans.append(beanName); 65 | beans.append(System.lineSeparator()); 66 | } 67 | 68 | if(logger.isLoggable(Level.SEVERE)) { 69 | logger.fine(beans.toString()); 70 | } 71 | }; 72 | } 73 | 74 | @RequestMapping("/") 75 | public String home() { 76 | return "Spring Boot Sample - Google AppEngine - Java 8 Runtime with Servlet 2.5 Web Descriptor"; 77 | } 78 | 79 | @RequestMapping("/version") 80 | public String getVersion() { 81 | return version; 82 | } 83 | 84 | @RequestMapping("/servlet-version") 85 | public String getServletVersion() { 86 | return context.getEffectiveMajorVersion() + "." + context.getEffectiveMinorVersion(); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/java/demo/hello/Greeting.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo.hello; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | 22 | public class Greeting { 23 | 24 | private final long id; 25 | 26 | private final String content; 27 | 28 | @JsonCreator 29 | public Greeting(@JsonProperty("id") long id, @JsonProperty("content") String content) { 30 | 31 | this.id = id; 32 | this.content = content; 33 | } 34 | 35 | public long getId() { 36 | return id; 37 | } 38 | 39 | public String getContent() { 40 | return content; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Greeting{" + 46 | "id=" + id + 47 | ", content='" + content + '\'' + 48 | '}'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/java/demo/hello/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo.hello; 18 | 19 | import java.util.concurrent.atomic.AtomicInteger; 20 | import java.util.logging.Logger; 21 | 22 | import io.micrometer.core.annotation.Timed; 23 | import io.micrometer.core.instrument.Counter; 24 | import io.micrometer.core.instrument.MeterRegistry; 25 | 26 | import org.springframework.http.MediaType; 27 | import org.springframework.web.bind.annotation.GetMapping; 28 | import org.springframework.web.bind.annotation.RequestParam; 29 | import org.springframework.web.bind.annotation.ResponseBody; 30 | import org.springframework.web.bind.annotation.RestController; 31 | 32 | @RestController 33 | public class HelloWorldController { 34 | 35 | public static final String HELLO_WORLD_COUNTER = "hello-world.requested"; 36 | 37 | private static final String HELLO_TEMPLATE = "Hello, %s!"; 38 | 39 | private static final java.util.logging.Logger logger = Logger.getLogger(HelloWorldController.class.getCanonicalName()); 40 | 41 | private final Counter counter; 42 | 43 | private final AtomicInteger internalCounter; 44 | 45 | public HelloWorldController(MeterRegistry registry) { 46 | 47 | this.counter = registry.counter(HELLO_WORLD_COUNTER); 48 | this.internalCounter = new AtomicInteger(); 49 | } 50 | 51 | @Timed 52 | @GetMapping(value = "/hello-world", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) 53 | @ResponseBody 54 | public Greeting sayHello( 55 | @RequestParam(name = "name", required = false, defaultValue = "Stranger") String name) { 56 | 57 | logger.info("Called Hello Endpoint"); 58 | counter.increment(); 59 | return new Greeting(internalCounter.incrementAndGet(), String.format(HELLO_TEMPLATE, name)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | debug=true 2 | 3 | info.version=0.0.1-SNAPSHOT 4 | 5 | spring.jmx.enabled=false 6 | 7 | spring.security.user.name=user 8 | spring.security.user.password=password 9 | 10 | management.metrics.enable.root=true 11 | management.metrics.web.server.auto-time-requests=true 12 | 13 | management.endpoint.metrics.enabled=true 14 | management.endpoints.web.exposure.include=* 15 | 16 | logging.level.ROOT=INFO 17 | logging.level.org.springframework=INFO 18 | logging.level.org.springframework.boot=DEBUG 19 | logging.level.org.springframework.boot.legacy=TRACE 20 | logging.level.org.springframework.web=INFO 21 | logging.level.org.springframework.security=DEBUG 22 | logging.level.org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping=INFO -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/resources/logging.properties: -------------------------------------------------------------------------------- 1 | # java.util.logging.ConsoleHandler.level=DEBUG 2 | .level=FINE 3 | 4 | # org.apache.catalina.core.ContainerBase.[Catalina].level = INFO 5 | # org.apache.catalina.core.ContainerBase.[Catalina].handlers = java.util.logging.ConsoleHandler -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/resources/static/static.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Static Page 6 | 7 | 8 | 9 | Static Page located in src/main/resources/static/static.html 10 | 11 | 12 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/webapp/WEB-INF/appengine-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | java8 4 | true 5 | true 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | contextConfigLocation 8 | demo.Application 9 | 10 | 11 | 12 | org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener 13 | 14 | 15 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-2.5/src/test/java/demo/EmbeddedIntegrationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | import org.junit.jupiter.api.BeforeEach; 24 | import org.junit.jupiter.api.Test; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.beans.factory.annotation.Value; 27 | import org.springframework.boot.actuate.metrics.MetricsEndpoint; 28 | import org.springframework.boot.test.context.SpringBootTest; 29 | import org.springframework.boot.test.web.client.TestRestTemplate; 30 | import org.springframework.http.client.support.BasicAuthenticationInterceptor; 31 | import org.springframework.security.core.userdetails.UserDetails; 32 | import org.springframework.security.provisioning.InMemoryUserDetailsManager; 33 | import org.springframework.test.context.ContextConfiguration; 34 | 35 | import demo.hello.Greeting; 36 | import demo.hello.HelloWorldController; 37 | 38 | 39 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 40 | @ContextConfiguration(classes = Application.class) 41 | public class EmbeddedIntegrationTests { 42 | 43 | private static final Log logger = LogFactory.getLog(EmbeddedIntegrationTests.class); 44 | 45 | private static final boolean TEST_WITH_SECURITY = true; 46 | 47 | @Value("${info.version}") 48 | private String expectedVersion; 49 | 50 | private String password; 51 | 52 | @Value("${local.server.port}") 53 | private int port; 54 | 55 | @Autowired 56 | private TestRestTemplate restTemplate; 57 | 58 | @Autowired(required = false) 59 | private InMemoryUserDetailsManager userDetailsManager; 60 | 61 | private String username = "user"; 62 | 63 | @BeforeEach 64 | public void setup() { 65 | 66 | if(TEST_WITH_SECURITY) { 67 | // Get password from userDetailsManager, currently this is hardcoded in application.properties but 68 | // this is especially important when it is set to be automatically generated. 69 | UserDetails userDetails = userDetailsManager.loadUserByUsername(username); 70 | password = userDetails.getPassword().replace("{noop}", ""); 71 | BasicAuthenticationInterceptor bai = new BasicAuthenticationInterceptor(username, password); 72 | restTemplate.getRestTemplate().getInterceptors().add(bai); 73 | } 74 | } 75 | 76 | @Test 77 | public void testActuatorConditionsEndpoint() { 78 | String body = restTemplate.getForObject("http://127.0.0.1:" + port + "/version", String.class); 79 | logger.debug("found version = " + body); 80 | String response = restTemplate.getForObject("http://127.0.0.1:" + port + "/actuator/conditions", String.class); 81 | logger.debug(response); 82 | } 83 | 84 | @Test 85 | public void testHelloWorldCounter() { 86 | long expectedValue = 0; 87 | 88 | for (int i = 0; i < 10; i++) { 89 | expectedValue++; 90 | 91 | Greeting greeting = restTemplate.getForObject("http://127.0.0.1:" + port + "/hello-world", Greeting.class); 92 | logger.debug("greeting = " + greeting); 93 | 94 | // Hit endpoint and check counter. 95 | assertThat(greeting).isNotNull(); 96 | assertThat(greeting.getContent()).isEqualTo("Hello, Stranger!"); 97 | // Check our own internal counter, this is just a sanity check 98 | assertThat(greeting.getId()).isEqualTo(expectedValue); 99 | 100 | // Verify metrics are being updated. 101 | MetricsEndpoint.MetricResponse response = restTemplate.getForObject("http://127.0.0.1:" + port + "/actuator/metrics/" + HelloWorldController.HELLO_WORLD_COUNTER, MetricsEndpoint.MetricResponse.class); 102 | MetricsEndpoint.Sample sample = response.getMeasurements().get(0); 103 | assertThat(sample.getValue()).isEqualTo((double) expectedValue); 104 | } 105 | 106 | String response = restTemplate.getForObject("http://127.0.0.1:" + port + "/actuator/metrics/http.server.requests", String.class); 107 | 108 | logger.info(response); 109 | } 110 | 111 | @Test 112 | public void testVersion() { 113 | //mvc.perform(get("/")) 114 | String body = restTemplate.getForObject("http://127.0.0.1:" + port + "/version", String.class); 115 | logger.debug("found version = " + body); 116 | assertThat(body).contains(expectedVersion); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/README.md: -------------------------------------------------------------------------------- 1 | Simple Spring Boot app that runs on Google AppEngine. No attempt has been made to use the Google APIs - just a minimal Spring app that works. 2 | 3 | Google App Engine Java 8 Runtime with Servlet 3.1 does NOT require [spring-boot-legacy](https://github.com/scratches/spring-boot-legacy)! 4 | 5 | To Test Locally: 6 | ``` 7 | $ git clone https://github.com/dyser/spring-boot-legacy 8 | $ cd spring-boot-legacy 9 | $ mvn install 10 | $ cd spring-boot-samples/spring-boot-sample-gae-3.1 11 | $ mvn appengine:devserver 12 | ``` 13 | 14 | To Deploy: 15 | ``` 16 | $ git clone https://github.com/dyser/spring-boot-legacy 17 | $ cd spring-boot-legacy 18 | $ mvn install 19 | $ cd spring-boot-samples/spring-boot-sample-gae-3.1 20 | $ mvn appengine:update 21 | ``` 22 | 23 | To Deploy to specific AppEngine Project and Version: 24 | ``` 25 | $ git clone https://github.com/dyser/spring-boot-legacy 26 | $ cd spring-boot-legacy 27 | $ mvn clean install 28 | $ cd spring-boot-samples/spring-boot-sample-gae-3.1 29 | $ mvn appengine:update -Dgae.appId=${APP_ENGINE_PROJECT_ID} -Dgae.version=${APP_ENGINE_PROJECT_VERSION} 30 | $ 31 | ``` 32 | 33 | Also runs as a deployed WAR in WTP or regular Tomcat container. The `main()` app (normal Spring Boot launcher) should also work. 34 | 35 | > NOTE: Google AppEngine does not allow JMX, so you have to switch it off in a Spring Boot app (`spring.jmx.enabled=false`). 36 | 37 | > WARNING: Spring Boot manages the appengine API version, which is nice. This project overrides it by virtue of using the `spring-boot-starter-parent` and defining the `appengine.version`. But beware, because `appengine.version` has a specific (other) meaning to the appengine Maven plugin, so we also have to define `gae.version` and use that to set the application version in the plugin configuration. 38 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-samples 8 | 0.0.1-SNAPSHOT 9 | 10 | spring-boot-sample-gae-3.1 11 | 0.0.1-SNAPSHOT 12 | war 13 | 14 | Spring Boot Sample GAE 3.1 15 | Spring Boot Sample in Google AppEngine using Java 8 Runtime with Servlet 3.1 (w/o Spring Boot Legacy) 16 | 17 | 18 | demo.Application 19 | 20 | / 21 | 22 | 1.9.63 23 | 24 | cf-sandbox-dsyer 25 | 5 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-actuator 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-security 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-logging 42 | 43 | 44 | ch.qos.logback 45 | logback-classic 46 | 47 | 48 | org.slf4j 49 | jul-to-slf4j 50 | 51 | 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-starter-web 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-starter-tomcat 61 | 62 | 63 | 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-starter-jetty 68 | provided 69 | 70 | 71 | 72 | org.slf4j 73 | slf4j-jdk14 74 | runtime 75 | 76 | 77 | 78 | org.slf4j 79 | jul-to-slf4j 80 | provided 81 | 82 | 83 | 84 | javax.servlet 85 | javax.servlet-api 86 | provided 87 | 88 | 89 | 90 | 91 | 92 | org.springframework.boot 93 | spring-boot-starter-test 94 | test 95 | 96 | 97 | 98 | org.springframework.security 99 | spring-security-test 100 | test 101 | 102 | 103 | 104 | com.google.appengine 105 | appengine-api-labs 106 | ${appengine.version} 107 | test 108 | 109 | 110 | com.google.appengine 111 | appengine-api-stubs 112 | ${appengine.version} 113 | test 114 | 115 | 116 | com.google.appengine 117 | appengine-testing 118 | ${appengine.version} 119 | test 120 | 121 | 122 | 123 | org.apache.httpcomponents 124 | httpclient 125 | test 126 | 127 | 128 | 129 | 130 | 131 | 132 | org.springframework.boot 133 | spring-boot-maven-plugin 134 | 135 | 136 | com.google.appengine 137 | appengine-maven-plugin 138 | ${appengine.version} 139 | 140 | ${gae.appId} 141 | ${gae.version} 142 | true 143 | 8181 144 | 145 | 146 | 147 | org.apache.maven.plugins 148 | maven-release-plugin 149 | 150 | appengine:update 151 | 152 | 153 | 154 | org.apache.tomcat.maven 155 | tomcat6-maven-plugin 156 | 2.2 157 | 158 | / 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | integration 167 | 168 | 169 | 170 | org.apache.maven.plugins 171 | maven-failsafe-plugin 172 | 173 | 174 | failsafe-it 175 | integration-test 176 | 177 | integration-test 178 | 179 | 180 | ${skipTests} 181 | 182 | **/NonEmbedded*Tests.java 183 | 184 | 185 | 186 | 187 | 188 | 189 | org.apache.tomcat.maven 190 | tomcat6-maven-plugin 191 | 192 | 193 | start-tomcat 194 | pre-integration-test 195 | 196 | run 197 | 198 | 199 | / 200 | true 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | spring-snapshots 213 | Spring Snapshots 214 | http://repo.spring.io/snapshot 215 | 216 | true 217 | 218 | 219 | 220 | spring-milestones 221 | Spring Milestones 222 | http://repo.spring.io/milestone 223 | 224 | false 225 | 226 | 227 | 228 | 229 | 230 | spring-snapshots 231 | Spring Snapshots 232 | http://repo.spring.io/snapshot 233 | 234 | true 235 | 236 | 237 | 238 | spring-milestones 239 | Spring Milestones 240 | http://repo.spring.io/milestone 241 | 242 | false 243 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo; 18 | 19 | import java.util.Arrays; 20 | import java.util.logging.Level; 21 | import java.util.logging.Logger; 22 | 23 | import javax.servlet.ServletContext; 24 | 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.beans.factory.annotation.Value; 27 | import org.springframework.boot.CommandLineRunner; 28 | import org.springframework.boot.SpringApplication; 29 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 30 | import org.springframework.boot.autoconfigure.SpringBootApplication; 31 | import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; 32 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 33 | import org.springframework.context.ApplicationContext; 34 | import org.springframework.context.annotation.Bean; 35 | import org.springframework.web.bind.annotation.RequestMapping; 36 | import org.springframework.web.bind.annotation.RestController; 37 | 38 | @SpringBootApplication 39 | @RestController 40 | @EnableAutoConfiguration 41 | public class Application extends SpringBootServletInitializer { 42 | 43 | private static final java.util.logging.Logger logger = Logger.getLogger(Application.class.getCanonicalName()); 44 | 45 | @Autowired 46 | private ServletContext context; 47 | 48 | @Value("${info.version}") 49 | private String version; 50 | 51 | public static void main(String[] args) { 52 | SpringApplication.run(Application.class, args); 53 | } 54 | 55 | @Bean 56 | public CommandLineRunner commandLineRunner(ApplicationContext ctx) { 57 | return args -> { 58 | 59 | String[] beanNames = ctx.getBeanDefinitionNames(); 60 | Arrays.sort(beanNames); 61 | 62 | StringBuilder beans = new StringBuilder(); 63 | 64 | beans.append("Spring Boot Beans: "); 65 | 66 | for (String beanName : beanNames) { 67 | beans.append(beanName); 68 | beans.append(System.lineSeparator()); 69 | } 70 | 71 | if(logger.isLoggable(Level.SEVERE)) { 72 | logger.fine(beans.toString()); 73 | } 74 | }; 75 | } 76 | 77 | @RequestMapping("/") 78 | public String home() { 79 | return "Spring Boot Sample - Google AppEngine - Java 8 Runtime with Servlet 3.1 Web Descriptor"; 80 | } 81 | 82 | @RequestMapping("/version") 83 | public String getVersion() { 84 | return version; 85 | } 86 | 87 | @RequestMapping("/servlet-version") 88 | public String getServletVersion() { 89 | return context.getEffectiveMajorVersion() + "." + context.getEffectiveMinorVersion(); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/java/demo/hello/Greeting.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo.hello; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | 22 | public class Greeting { 23 | 24 | private final long id; 25 | 26 | private final String content; 27 | 28 | @JsonCreator 29 | public Greeting(@JsonProperty("id") long id, @JsonProperty("content") String content) { 30 | 31 | this.id = id; 32 | this.content = content; 33 | } 34 | 35 | public long getId() { 36 | return id; 37 | } 38 | 39 | public String getContent() { 40 | return content; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "Greeting{" + 46 | "id=" + id + 47 | ", content='" + content + '\'' + 48 | '}'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/java/demo/hello/HelloWorldController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo.hello; 18 | 19 | import java.util.concurrent.atomic.AtomicInteger; 20 | import java.util.logging.Logger; 21 | 22 | import io.micrometer.core.annotation.Timed; 23 | import io.micrometer.core.instrument.Counter; 24 | import io.micrometer.core.instrument.MeterRegistry; 25 | 26 | import org.springframework.http.MediaType; 27 | import org.springframework.web.bind.annotation.GetMapping; 28 | import org.springframework.web.bind.annotation.RequestParam; 29 | import org.springframework.web.bind.annotation.ResponseBody; 30 | import org.springframework.web.bind.annotation.RestController; 31 | 32 | @RestController 33 | public class HelloWorldController { 34 | 35 | public static final String HELLO_WORLD_COUNTER = "hello-world.requested"; 36 | 37 | private static final String HELLO_TEMPLATE = "Hello, %s!"; 38 | 39 | private static final java.util.logging.Logger logger = Logger.getLogger(HelloWorldController.class.getCanonicalName()); 40 | 41 | private final Counter counter; 42 | 43 | private final AtomicInteger internalCounter; 44 | 45 | public HelloWorldController(MeterRegistry registry) { 46 | 47 | this.counter = registry.counter(HELLO_WORLD_COUNTER); 48 | this.internalCounter = new AtomicInteger(); 49 | } 50 | 51 | @Timed 52 | @GetMapping(value = "/hello-world", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) 53 | @ResponseBody 54 | public Greeting sayHello( 55 | @RequestParam(name = "name", required = false, defaultValue = "Stranger") String name) { 56 | 57 | logger.info("Called Hello Endpoint"); 58 | counter.increment(); 59 | return new Greeting(internalCounter.incrementAndGet(), String.format(HELLO_TEMPLATE, name)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | debug=true 2 | 3 | info.version=0.0.1-SNAPSHOT 4 | 5 | spring.jmx.enabled=false 6 | 7 | spring.security.user.name=user 8 | spring.security.user.password=password 9 | 10 | management.metrics.enable.root=true 11 | management.metrics.web.server.auto-time-requests=true 12 | 13 | management.endpoint.metrics.enabled=true 14 | management.endpoints.web.exposure.include=* 15 | 16 | logging.level.ROOT=INFO 17 | logging.level.org.springframework=INFO 18 | logging.level.org.springframework.boot=DEBUG 19 | logging.level.org.springframework.boot.legacy=TRACE 20 | logging.level.org.springframework.web=INFO 21 | logging.level.org.springframework.security=DEBUG 22 | logging.level.org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping=INFO -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/resources/logging.properties: -------------------------------------------------------------------------------- 1 | # java.util.logging.ConsoleHandler.level=DEBUG 2 | .level=FINE 3 | 4 | # org.apache.catalina.core.ContainerBase.[Catalina].level = INFO 5 | # org.apache.catalina.core.ContainerBase.[Catalina].handlers = java.util.logging.ConsoleHandler -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/resources/static/static.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Static Page 6 | 7 | 8 | 9 | Static Page located in src/main/resources/static/static.html 10 | 11 | 12 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/webapp/WEB-INF/appengine-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | java8 4 | true 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-gae-3.1/src/test/java/demo/EmbeddedIntegrationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | import org.junit.jupiter.api.BeforeEach; 24 | import org.junit.jupiter.api.Test; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.beans.factory.annotation.Value; 27 | import org.springframework.boot.actuate.metrics.MetricsEndpoint; 28 | import org.springframework.boot.test.context.SpringBootTest; 29 | import org.springframework.boot.test.web.client.TestRestTemplate; 30 | import org.springframework.http.client.support.BasicAuthenticationInterceptor; 31 | import org.springframework.security.core.userdetails.UserDetails; 32 | import org.springframework.security.provisioning.InMemoryUserDetailsManager; 33 | import org.springframework.test.context.ContextConfiguration; 34 | 35 | import demo.hello.Greeting; 36 | import demo.hello.HelloWorldController; 37 | 38 | 39 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 40 | @ContextConfiguration(classes = Application.class) 41 | public class EmbeddedIntegrationTests { 42 | 43 | private static final Log logger = LogFactory.getLog(EmbeddedIntegrationTests.class); 44 | 45 | private static final boolean TEST_WITH_SECURITY = true; 46 | 47 | @Value("${info.version}") 48 | private String expectedVersion; 49 | 50 | private String password; 51 | 52 | @Value("${local.server.port}") 53 | private int port; 54 | 55 | @Autowired 56 | private TestRestTemplate restTemplate; 57 | 58 | @Autowired(required = false) 59 | private InMemoryUserDetailsManager userDetailsManager; 60 | 61 | private String username = "user"; 62 | 63 | @BeforeEach 64 | public void setup() { 65 | 66 | if(TEST_WITH_SECURITY) { 67 | // Get password from userDetailsManager, currently this is hardcoded in application.properties but 68 | // this is especially important when it is set to be automatically generated. 69 | UserDetails userDetails = userDetailsManager.loadUserByUsername(username); 70 | password = userDetails.getPassword().replace("{noop}", ""); 71 | BasicAuthenticationInterceptor bai = new BasicAuthenticationInterceptor(username, password); 72 | restTemplate.getRestTemplate().getInterceptors().add(bai); 73 | } 74 | } 75 | 76 | @Test 77 | public void testActuatorConditionsEndpoint() { 78 | String body = restTemplate.getForObject("http://127.0.0.1:" + port + "/version", String.class); 79 | logger.debug("found version = " + body); 80 | String response = restTemplate.getForObject("http://127.0.0.1:" + port + "/actuator/conditions", String.class); 81 | logger.debug(response); 82 | } 83 | 84 | @Test 85 | public void testHelloWorldCounter() { 86 | long expectedValue = 0; 87 | 88 | for (int i = 0; i < 10; i++) { 89 | expectedValue++; 90 | 91 | Greeting greeting = restTemplate.getForObject("http://127.0.0.1:" + port + "/hello-world", Greeting.class); 92 | logger.debug("greeting = " + greeting); 93 | 94 | // Hit endpoint and check counter. 95 | assertThat(greeting).isNotNull(); 96 | assertThat(greeting.getContent()).isEqualTo("Hello, Stranger!"); 97 | // Check our own internal counter, this is just a sanity check 98 | assertThat(greeting.getId()).isEqualTo(expectedValue); 99 | 100 | // Verify metrics are being updated. 101 | MetricsEndpoint.MetricResponse response = restTemplate.getForObject("http://127.0.0.1:" + port + "/actuator/metrics/" + HelloWorldController.HELLO_WORLD_COUNTER, MetricsEndpoint.MetricResponse.class); 102 | MetricsEndpoint.Sample sample = response.getMeasurements().get(0); 103 | assertThat(sample.getValue()).isEqualTo((double) expectedValue); 104 | } 105 | 106 | String response = restTemplate.getForObject("http://127.0.0.1:" + port + "/actuator/metrics/http.server.requests", String.class); 107 | 108 | logger.info(response); 109 | } 110 | 111 | @Test 112 | public void testVersion() { 113 | //mvc.perform(get("/")) 114 | String body = restTemplate.getForObject("http://127.0.0.1:" + port + "/version", String.class); 115 | logger.debug("found version = " + body); 116 | assertThat(body).contains(expectedVersion); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-secure-legacy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.boot 8 | spring-boot-samples 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | spring-boot-sample-secure-legacy 13 | 0.0.1-SNAPSHOT 14 | war 15 | 16 | Spring Boot Sample Secure Legacy 17 | Demo project 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-actuator 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-security 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-tomcat 35 | provided 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-validation 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-legacy 46 | 2.7.0-SNAPSHOT 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | org.apache.httpcomponents 57 | httpclient 58 | test 59 | 60 | 61 | 62 | 63 | demo.Application 64 | UTF-8 65 | UTF-8 66 | 1.8 67 | / 68 | 69 | 70 | 71 | 72 | 73 | 74 | org.apache.maven.plugins 75 | maven-deploy-plugin 76 | 77 | true 78 | 79 | 80 | 81 | 82 | 83 | 84 | org.springframework.boot 85 | spring-boot-maven-plugin 86 | 87 | 88 | org.apache.tomcat.maven 89 | tomcat6-maven-plugin 90 | 2.2 91 | 92 | / 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | integration 101 | 102 | 103 | 104 | org.apache.maven.plugins 105 | maven-failsafe-plugin 106 | 107 | 108 | failsafe-it 109 | integration-test 110 | 111 | integration-test 112 | 113 | 114 | ${skipTests} 115 | 116 | **/NonEmbedded*Tests.java 117 | 118 | 119 | 120 | 121 | 122 | 123 | org.apache.tomcat.maven 124 | tomcat6-maven-plugin 125 | 126 | 127 | start-tomcat 128 | pre-integration-test 129 | 130 | run 131 | 132 | 133 | / 134 | true 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | spring-snapshots 147 | Spring Snapshots 148 | http://repo.spring.io/snapshot 149 | 150 | true 151 | 152 | 153 | 154 | spring-milestones 155 | Spring Milestones 156 | http://repo.spring.io/milestone 157 | 158 | false 159 | 160 | 161 | 162 | 163 | 164 | spring-snapshots 165 | Spring Snapshots 166 | http://repo.spring.io/snapshot 167 | 168 | true 169 | 170 | 171 | 172 | spring-milestones 173 | Spring Milestones 174 | http://repo.spring.io/milestone 175 | 176 | false 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-secure-legacy/src/main/java/demo/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo; 18 | 19 | import javax.servlet.ServletContext; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.beans.factory.annotation.Value; 23 | import org.springframework.boot.SpringApplication; 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.context.annotation.ComponentScan; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.web.bind.annotation.RequestMapping; 28 | import org.springframework.web.bind.annotation.RestController; 29 | 30 | @Configuration 31 | @ComponentScan 32 | @EnableAutoConfiguration 33 | @RestController 34 | public class Application { 35 | 36 | @Autowired 37 | private ServletContext context; 38 | 39 | @Value("${message}") 40 | private String message; 41 | 42 | @Value("${info.version}") 43 | private String version; 44 | 45 | public static void main(String[] args) { 46 | SpringApplication.run(Application.class, args); 47 | } 48 | 49 | @RequestMapping("/version") 50 | public String getVersion() { 51 | return version; 52 | } 53 | 54 | @RequestMapping("/") 55 | public String home() { 56 | return message; 57 | } 58 | 59 | @RequestMapping("/servlet-version") 60 | public String getServletVersion() { 61 | return context.getEffectiveMajorVersion() + "." + context.getEffectiveMinorVersion(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-secure-legacy/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | info.version=0.0.1-SNAPSHOT 2 | 3 | message=Hello World 4 | 5 | spring.jmx.enabled=true 6 | 7 | spring.security.user.name=user 8 | spring.security.user.password=password 9 | 10 | management.metrics.enable.root=true 11 | management.metrics.web.server.auto-time-requests=true 12 | 13 | management.endpoint.metrics.enabled=true 14 | management.endpoints.web.exposure.include=* 15 | 16 | # logging.level.org.springframework=WARN 17 | # logging.level.org.springframework.boot=DEBUG 18 | # logging.level.org.springframework.security=DEBUG 19 | # logging.level.org.springframework.web=INFO 20 | # logging.level.org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping=INFO 21 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-secure-legacy/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-secure-legacy/src/main/webapp/WEB-INF/jboss-deployment-structure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-secure-legacy/src/main/webapp/WEB-INF/jboss-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /spring-boot-sample-secure-legacy 4 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-secure-legacy/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | contextConfigLocation 9 | demo.Application 10 | 11 | 12 | 13 | org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /spring-boot-samples/spring-boot-sample-secure-legacy/src/test/java/demo/EmbeddedIntegrationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package demo; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.assertTrue; 21 | 22 | import org.apache.commons.codec.binary.Base64; 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | import org.junit.jupiter.api.Test; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.beans.factory.annotation.Value; 28 | import org.springframework.boot.test.context.SpringBootTest; 29 | import org.springframework.boot.test.web.client.TestRestTemplate; 30 | import org.springframework.http.HttpEntity; 31 | import org.springframework.http.HttpHeaders; 32 | import org.springframework.http.HttpMethod; 33 | import org.springframework.http.HttpStatus; 34 | import org.springframework.http.ResponseEntity; 35 | import org.springframework.test.context.ContextConfiguration; 36 | 37 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 38 | @ContextConfiguration(classes = Application.class) 39 | public class EmbeddedIntegrationTests { 40 | 41 | private static final Log logger = LogFactory.getLog(EmbeddedIntegrationTests.class); 42 | 43 | @Autowired 44 | private TestRestTemplate restTemplate; 45 | 46 | @Value("${local.server.port}") 47 | private int port; 48 | 49 | @Value("${message}") 50 | private String expectedMessage; 51 | 52 | @Value("${info.version}") 53 | private String expectedVersion; 54 | 55 | @Value("${spring.security.user.name}") 56 | private String username; 57 | 58 | @Value("${spring.security.user.password}") 59 | private String password; 60 | 61 | @Test 62 | public void testSecureRedirectToLoginPage() { 63 | ResponseEntity responseEntity = restTemplate.getForEntity("http://127.0.0.1:" + port + "/", String.class); 64 | String body = responseEntity.getBody(); 65 | assertEquals(HttpStatus.FOUND, responseEntity.getStatusCode(), "Wrong body: " + body); 66 | assertEquals("http://127.0.0.1:" + port + "/login", responseEntity.getHeaders().get("Location").get(0), "Not Login Page"); 67 | } 68 | 69 | @Test 70 | public void testSecureAuthenticated() { 71 | String plainCreds = username + ":" + password; 72 | byte[] plainCredsBytes = plainCreds.getBytes(); 73 | byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); 74 | String base64Creds = new String(base64CredsBytes); 75 | 76 | HttpHeaders headers = new HttpHeaders(); 77 | headers.add("Authorization", "Basic " + base64Creds); 78 | 79 | HttpEntity request = new HttpEntity<>(headers); 80 | 81 | ResponseEntity responseEntity = restTemplate.exchange("http://127.0.0.1:" + port + "/", HttpMethod.GET, request, String.class, new Object[] {}); 82 | 83 | String body = responseEntity.getBody(); 84 | logger.info("found / = " + body); 85 | assertTrue(body.contains(expectedMessage), "Wrong body: " + body); 86 | } 87 | 88 | @Test 89 | public void testVersion() { 90 | String plainCreds = username + ":" + password; 91 | byte[] plainCredsBytes = plainCreds.getBytes(); 92 | byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); 93 | String base64Creds = new String(base64CredsBytes); 94 | 95 | HttpHeaders headers = new HttpHeaders(); 96 | headers.add("Authorization", "Basic " + base64Creds); 97 | 98 | HttpEntity request = new HttpEntity<>(headers); 99 | 100 | ResponseEntity responseEntity = restTemplate.exchange("http://127.0.0.1:" + port + "/version", HttpMethod.GET, request, String.class, new Object[] {}); 101 | String body = responseEntity.getBody(); 102 | 103 | logger.info("found version = " + body); 104 | assertTrue(body.contains(expectedVersion), "Wrong body: " + body); 105 | } 106 | } 107 | --------------------------------------------------------------------------------