diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.gitignore" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.gitignore" new file mode 100644 index 0000000..549e00a --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.gitignore" @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/MavenWrapperDownloader.java" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/MavenWrapperDownloader.java" new file mode 100644 index 0000000..a45eb6b --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/MavenWrapperDownloader.java" @@ -0,0 +1,118 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.jar" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.jar" new file mode 100644 index 0000000..2cc7d4a Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.jar" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.properties" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.properties" new file mode 100644 index 0000000..a9f1ef8 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.properties" @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw" new file mode 100755 index 0000000..a16b543 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw" @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw.cmd" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw.cmd" new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw.cmd" @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/pom.xml" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/pom.xml" new file mode 100644 index 0000000..f803ee5 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/pom.xml" @@ -0,0 +1,46 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.0.RELEASE + + + com.panda + fileInclude + 0.0.1-SNAPSHOT + fileInclude + fileInclude + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/FileIncludeApplication.java" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/FileIncludeApplication.java" new file mode 100644 index 0000000..3b60c4e --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/FileIncludeApplication.java" @@ -0,0 +1,31 @@ +package com.panda.fileinclude; + +import org.apache.catalina.connector.Connector; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class FileIncludeApplication { + + + public static void main(String[] args) { + SpringApplication.run(FileIncludeApplication.class, args); + } + + @Bean + public ConfigurableServletWebServerFactory webServerFactory() { + TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); + factory.addConnectorCustomizers(new TomcatConnectorCustomizer() { + @Override + public void customize(Connector connector) { + connector.setProperty("relaxedQueryChars", "|{}[]"); + } + }); + return factory; + } + +} diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/TemplateController.java" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/TemplateController.java" new file mode 100644 index 0000000..04db78d --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/TemplateController.java" @@ -0,0 +1,40 @@ +package com.panda.fileinclude; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import org.springframework.web.servlet.View; + +@Controller +public class TemplateController { + Logger log = LoggerFactory.getLogger(TemplateController.class); + + @GetMapping("/") + public String index(Model model) { + model.addAttribute("message", "hello world!"); + return "index"; + } + + + @GetMapping("/admin") + public String path(@RequestParam String language) { + return "language/" + language + "/admin"; + } + + @GetMapping("/page") + public String path(@RequestParam String exp, Model model) { + model.addAttribute("exp", exp); + return "exp"; + } + + @GetMapping("/test") + public String test(@RequestParam String path) { + return "/" + path; + } + + +} diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/application.properties" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/application.properties" new file mode 100644 index 0000000..2088962 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/application.properties" @@ -0,0 +1,8 @@ +spring.thymeleaf.cache=false +spring.thymeleaf.prefix=classpath:/templates/ +spring.thymeleaf.suffix=.html +spring.thymeleaf.encoding=UTF-8 +spring.thymeleaf.content-type=text/html +spring.thymeleaf.mode=HTML5 +tomcat.util.http.parser.HttpParser.requestTargetAllow=|{} +org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/exp.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/exp.html" new file mode 100644 index 0000000..bbbb8b7 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/exp.html" @@ -0,0 +1,11 @@ + + + + Hello World! + + +

Hello

+

+ + \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/index.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/index.html" new file mode 100644 index 0000000..ec1cd3b --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/index.html" @@ -0,0 +1,11 @@ + + + + Hello World! + + +

Hello

+

+ + \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/admin.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/admin.html" new file mode 100644 index 0000000..a520af8 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/admin.html" @@ -0,0 +1,11 @@ + + + + Cn Admin page! + + +

Hello Cn-Admin

+

+ + \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/index.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/index.html" new file mode 100644 index 0000000..39109c0 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/index.html" @@ -0,0 +1,11 @@ + + + + Cn Admin index page! + + +

Hello Admin

+

+ + \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/admin.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/admin.html" new file mode 100644 index 0000000..d7e65dc --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/admin.html" @@ -0,0 +1,11 @@ + + + + En Admin page! + + +

Hello En-Admin

+

+ + \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/index.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/index.html" new file mode 100644 index 0000000..a948b70 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/index.html" @@ -0,0 +1,11 @@ + + + + En Admin index page! + + +

Hello Admin

+

+ + \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/test.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/test.html" new file mode 100644 index 0000000..b13c1a6 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/test.html" @@ -0,0 +1,11 @@ + + + + Hello World! + + +

Hello

+

+ + \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png" new file mode 100644 index 0000000..f3fc43f Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png" new file mode 100644 index 0000000..aa1f717 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png" new file mode 100644 index 0000000..59c85db Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png" new file mode 100644 index 0000000..27ca759 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png" new file mode 100644 index 0000000..4675e07 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png" new file mode 100644 index 0000000..48f85c7 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png" new file mode 100644 index 0000000..cdaa77b Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png" new file mode 100644 index 0000000..fcde230 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png" new file mode 100644 index 0000000..08f7e5b Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/18.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/18.png" new file mode 100644 index 0000000..f99b7e1 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/18.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/19.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/19.png" new file mode 100644 index 0000000..85df171 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/19.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png" new file mode 100644 index 0000000..1e5d4f9 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/20.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/20.png" new file mode 100644 index 0000000..b91f8f1 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/20.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/21.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/21.png" new file mode 100644 index 0000000..28b3a37 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/21.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/22.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/22.png" new file mode 100644 index 0000000..74d6188 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/22.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/23.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/23.png" new file mode 100644 index 0000000..7695fe0 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/23.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/24.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/24.png" new file mode 100644 index 0000000..2c86456 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/24.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/25.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/25.png" new file mode 100644 index 0000000..6cb71aa Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/25.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png" new file mode 100644 index 0000000..c1f8868 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png" new file mode 100644 index 0000000..ac9b500 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png" new file mode 100644 index 0000000..0dc51b2 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png" new file mode 100644 index 0000000..b389131 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png" new file mode 100644 index 0000000..3ba8f49 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png" new file mode 100644 index 0000000..1b3b919 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png" new file mode 100644 index 0000000..d4e1fc6 Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/1.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/1.png" new file mode 100644 index 0000000..9c5f0ae Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/1.png" differ diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/META-INF/MANIFEST.MF" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/META-INF/MANIFEST.MF" new file mode 100644 index 0000000..5e94951 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/META-INF/MANIFEST.MF" @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/WEB-INF/web.xml" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/WEB-INF/web.xml" new file mode 100644 index 0000000..12ac295 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/WEB-INF/web.xml" @@ -0,0 +1,14 @@ + + + include + + JAX-RS Tools Generated - Do not modify + JAX-RS Servlet + com.sun.jersey.spi.container.servlet.ServletContainer + 1 + + + JAX-RS Servlet + /jaxrs/* + + \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/data.txt" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/data.txt" new file mode 100644 index 0000000..51993f0 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/data.txt" @@ -0,0 +1 @@ +本地包含测试页面 \ No newline at end of file diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_local.jsp" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_local.jsp" new file mode 100644 index 0000000..8fa7002 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_local.jsp" @@ -0,0 +1,19 @@ +<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> + +<% + String file = request.getParameter("file"); +%> + + + + + + + + JSP 文件包含测试(本地) + + + +File Include Test Page.
+ + diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_remote.jsp" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_remote.jsp" new file mode 100644 index 0000000..2acf8c9 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_remote.jsp" @@ -0,0 +1,27 @@ +<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + 远程文件包含测试 + <% + + String url = request.getParameter("url"); + + %> + + + + + + + + + + + + +This is my JSP page.
+ + diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/index.jsp" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/index.jsp" new file mode 100644 index 0000000..774f8fe --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/index.jsp" @@ -0,0 +1,26 @@ +<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> +<% +String path = request.getContextPath(); +String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; +%> + + + + + + + My JSP 'index.jsp' starting page + + + + + + + + + + This is my JSP page.
+ + diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-06\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-06\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md" new file mode 100644 index 0000000..7f0aba3 --- /dev/null +++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-06\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md" @@ -0,0 +1,348 @@ +# 【Java 代码审计入门-06】文件包含漏洞原理与实际案例介绍 + +## 0x00 写在前面 + +为什么会有这一些列的文章呢?因为我发现网上没有成系列的文章或者教程,基本上是 Java 代码审计中某个点来阐述的,对于新人来说可能不是那么友好,加上本人也在学习 Java 审计,想做个学习历程的记录和总结,因此有了本系列的文章。 + +本系列的文章面向人群主要是**拥有 Java 基本语法基础的朋友**,系列文章的内容主要包括,审计环境介绍、SQL 漏洞原理与实际案例介绍、XSS 漏洞原理与实际案例介绍、SSRF 漏洞原理与实际案例介绍、RCE 漏洞原理与实际案例介绍、包含漏洞原理与实际案例介绍、序列化漏洞原理与实际案例介绍、S2系列经典漏洞分析、WebLogic 系列经典漏洞分析、fastjson系列经典漏洞分析、jackson系列经典漏洞分析等,可能内容顺序会略有调整,但是总体内容不会改变,最后希望这系列的文章能够给你带来一点收获。 + +目前已完成内容如下: + +【Java 代码审计入门-01】审计前的准备 https://www.cnpanda.net/codeaudit/588.html + +【Java 代码审计入门-02】SQL 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/600.html + +【Java 代码审计入门-03】XSS 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/605.html + +【Java 代码审计入门-04】SSRF 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/678.html + +【Java 代码审计入门-05】RCE 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/759.html + +## 0x01 前戏 + +下载 RCE 测试源码: + +https://github.com/cn-panda/JavaCodeAudit + +导入项目,可以得到以下目录: + +![1.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/1.png) + +![2.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/2.png) + +项目是一个为了体现文件包含而特地写的一些功能,比如从本地引入文件、从远程引入文件等,此外,还有 Springboot+thymeleaf 的文件包含测试项目。 + +## 0x02 漏洞原理 + +文件包含漏洞出现最多的地方是在由 PHP 编写的 Web应用中,我们知道,在 PHP 中,攻击者可以通过 PHP 中的某些包含函数(如:include、require 等),去包含一个含有攻击代码的恶意文件,在包含这个文件后,由于 PHP 包含函数的特性,无论包含的是什么类型的文件,都会将所包含的文件当作 PHP 代码去解析执行。 + +也就是说,攻击者可能上传一个一句话木马后缀是 txt 或者 jpg 的文件,上传后利用文件包含漏洞去包含这个一句话木马文件就可以成功拿到 Shell 了。 + +那么Java 中有没有类似的包含漏洞呢?回答这个问题前首先来看看 Java 中原生的包含其他文件的方式。 + +JSP 的文件包含分为静态包含和动态包含两种。 + +第一种是静态包含:`<%@include file="test.jsp"%>` + +所谓的静态包含就是指包含在其中的参数值, 如上述的`file`参数,不能动态赋值,定义的时候写的是什么,那就是什么,而不能够在项目运行时,动态的赋值给它。因此,通常我们认为,静态包含并不含有文件包含漏洞,当然,不排除和其他漏洞结合而产生的奇妙反应造成包含漏洞产生的可能性,但这里我们不谈。 + +有静必有动,第二种便是动态包含,动态包含的形式有如下两种: +``` + + +``` + +``` + +``` + +来看看第一种形式,这种形式相对静态包含来讲, 要复杂一点,因为在静态包含中其只属于一个include指令元素, 并且只有一个file的属性, 只是写上路径就行了, 路径可以是相对路径也可以是绝对路径, 但不能是`<%=...%>`代表的表达式,但在这里,file 属性可以是`<%=...%>`代表的表达式。 + +第二种形式其实和第一种形式并无本质上的区别,core 库 的``和 `` 一样,也是一种请求时操作,它的目的就是将其它一些 Web 资源的内容插入到当前的 JSP 页面中,这些 Web 资源就是通过url 属性来指定的,这也是`` 的唯一一个必选属性。值得一提的是,这里允许使用相对 URL,并且根据当前页面的 URL 来解析这个相对 URL。 + +举个例子,如果我们当前页面的 URL 地址是`http://127.0.0.1/admin/index.jsp`,那么如果我们引用的 URL 属性值为`/user/edit.jsp`,那么其实最终解析的 URL 就是`http://127.0.0.1/admin/user/edit.jsp` + +所以,如果 url 属性的值以斜杠开始,那么它就被解释成本地 JSP 容器内的绝对 URL。如果没有为 `context` 属性指定值,那么就认为这样的绝对 URL 引用当前 servlet 上下文内的资源。如果通过`context` 属性显式地指定了上下文,那么就根据指定的 servlet 上下文 解析绝对(本地)URL。  + +当然,`` 操作并不仅仅限于访问本地内容,也可以为具体协议和主机名的完整 URI 。并且实际上,协议甚至不仅局限于 HTTP。 `` 的 url 属性值可以使用 [`java.net.URL`](https://docs.oracle.com/javase/7/docs/api/java/net/URL.html) 类所支持的任何协议(也就是`http`, `https`, `ftp`, `file`,`jar`,`mailto`,`netdoc`)。 + +由于这些特性,导致**动态包含可能会出现文件包含漏洞**, 但这种包含和 PHP 中的包含存在很大的差别,**对于 Java 的本地文件包含来说,造成的危害只有文件读取或下载,`一般情况下`不会造成命令执行或代码执行**。因为一般情况下 Java 中对于文件的包含并不是将非 jsp 文件当成 Java 代码去执行,如果这个 JSP 文件是一个一句话木马文件,我们可以直接去访问利用,并不需要多此一举去包含它来使用了,除非在某些特殊场景下,如某些目录下权限不够可以尝试利用包含来绕过(理论上)。 + +通常情况下 Java 并不会把非 jsp 文件当成 Java 去解析执行,但是可以利用服务容器本身的一些特性(如将指定目录下的文件全部作为 jsp 文件解析),来实现任意后缀的文件包含,如 Apache Tomcat Ajp(CVE-2020-1938)漏洞,利用 Tomcat 的 AJP(定向包协议)协议实现了任意后缀名文件当成 jsp 文件去解析,从而导致 RCE 漏洞。 + +除此之外,另外提一点,静态包含和动态包含在`执行时间上`有很大的区别。**静态包含是翻译阶段执行的**,即被包含的文件和被插入到的页面会被 JSP 编译器合成编译,最终编译后的文件实际上只有一个。而**动态包含实际是在请求处理阶段执行的**,JSP程序会将请求转发到(注意不是重定向)被包含页面,并将执行结果输出到浏览器中,然后返回页面继续执行后面的代码,即被包含的文件和被插入到的页面会被JSP编译器单独编译。 + +好了,说了那么多,来看看我们写的例子吧。 + +首先是本地文件包含: + +```java +<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> +<% + String file = request.getParameter("file"); +%> + + + + + + + JSP 文件包含测试(本地) + + +File Include Test Page.
+ + +``` + +当我们令`file`的参数值为`data.txt`时,可以得到该文件的内容,如下图所示: + +![3.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/3.png) + +但是这里有个问题,就是这里包含的路径实际上只能是该 web 路径下的文件,并且该文件的类型只能是文本类型,如`jsp`、`txt`等,不支持图片等类型的文件。 + +当尝试访问一个图片资源的时候,就会报错: + +![4.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/4.png) + +并且不支持解析.java 文件(原理上面已说过): + +![5.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/5.png) + +其次再来看看远程包含: + +```java +<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + 远程文件包含测试 + <% String url = request.getParameter("url"); %> + + + + + + + +This is my JSP page.
+ + +``` + +远程包含不但可以包含远程文件,同时可以包含本地文件,如下: + +![6.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/6.png) + +![7.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/7.png) + +包括图片资源(不解析图片,但是有图片的数据): + +![8.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/8.png) + +解析远程文件: + +![9.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/9.png) + +![10.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/10.png) + +深入利用,首先在 XSS 平台生成一个利用的 xss payload,然后在远程创建一个 html 页面,这个 html 里面镶嵌了这个 xss js,然后利用包含漏洞远程访问: + +![11.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/11.png) + +成功获取到了 cookie + +![12.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/12.png) + +除此之外,还可以利用 file、netdoc 协议来实现任意文件读取的目的: + +![13.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/13.png) + +![14.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/14.png) + +那么 java 文件包含漏洞做到的仅仅如此而已吗? + +答案是否定的,在前文中我提到 `` 的 url 属性值可以使用 `java.net.URL`类所支持的任何协议,因此 jar 协议也自然在其中,对 jar 协议的利用,通常是在 XXE 漏洞中,实际上在 java 的文件包含漏洞中也可以利用。 + +利用方式和`K0rz3n`师傅提到的[利用 jar 上传文件](https://xz.aliyun.com/t/3357)大差不差,同样是利用临时文件,然后报错获取临时文件的路径,由于时间关系,我这里只是做了个简单的测试: + +![15.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/15.png) + +![16.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/16.png) + +可以看到临时文件确实存在于目录下,只不过由于是临时的,所以很快自动删除了,只要使用某种技巧(`K0rz3n`师傅提到),就能够使得文件长时间存在于目标服务器中,但是如何利用上传的文件,也是一个问题,这里我也没深入思考其利用方式,有兴趣的朋友可以思考一番 + +除了原生的 java 文件包含,实际上还有框架层面的文件包含漏洞,这里就简单举个例子来说明一下。 + +我们理解的 JSP 文件包含是可控` markupSelectorsToRender, Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { + String templateName; + Set markupSelectors, processMarkupSelectors; + ServletContext servletContext = getServletContext(); + String viewTemplateName = getTemplateName(); + ISpringTemplateEngine viewTemplateEngine = getTemplateEngine(); + + ... + + try { + fragmentExpression = (FragmentExpression)parser.parseExpression((IExpressionContext)context, "~{" + viewTemplateName + "}"); + } catch (TemplateProcessingException e) { + throw new IllegalArgumentException("Invalid template name specification: '" + viewTemplateName + "'"); + } + + FragmentExpression.ExecutedFragmentExpression fragment = FragmentExpression.createExecutedFragmentExpression((IExpressionContext)context, fragmentExpression); + + templateName = FragmentExpression.resolveTemplateName(fragment); + markupSelectors = FragmentExpression.resolveFragments(fragment); + Map nameFragmentParameters = fragment.getFragmentParameters(); + + if (nameFragmentParameters != null) { + + if (fragment.hasSyntheticParameters()) + { + + throw new IllegalArgumentException("Parameters in a view specification must be named (non-synthetic): '" + viewTemplateName + "'"); + } + + context.setVariables(nameFragmentParameters); + } + } + + ... + } +``` + +可以发现,这里将模板名称(`viewTemplateName`) 进行拼接 `"~{" + viewTemplateName + "}"`,然后使用`parseExpression`进行解析,继续跟进`parseExpression`就可以发现会对传入的参数进行预处理,最终使用SpEL执行表达式。 + +所以我们直接令`language`参数的值为一个我们指定的SpEL表达式,就可以实现 RCE: + +![20.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/20.png) + +那么如果我们假设存在一个可以上传非 jsp 类型文件的漏洞,并且上传的位置可控,控制器的逻辑如下: + +```java +@GetMapping("/test") +public String test(@RequestParam String path) { + return "/" + path; +} +``` + +因此就可能发生以下情况: + +将`test.html`上传到模板文件夹`template`根目录下: +`test.html`内容如下: +```html + + + + Hello World! + + +

Hello

+

+ + +``` + +访问即可达到PHP 中的文件包含效果: + +![21.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/21.png) + +这种情况,在实际情况下我遇到过,只不过非 jsp文件 类型的任意位置的文件上传漏洞比较少见,可能遇到这种情况的人比较少,所以也不具有代表性。 + +此外,我们知道Thymeleaf模板的语法有以下几种常用的表达式: + +> ${…}: 变量表达式 +> *{…}: 选择表达式 + #{…}: 消息表达式 + @{…}: 链接表达式 + ~{…}: 片段表达式 + +所以在这里,如果存在一个模板文件中的参数可控,即: + +![22.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/22.png) + +并且控制器中的逻辑为: + +```java +@GetMapping("/page") +public String path(@RequestParam String exp, Model model) { + model.addAttribute("exp", exp); + return "exp"; +} +``` + +同样可以实现 RCE 效果: + +![23.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/23.png) + +这里介绍的仅仅是原理是类似于文件包含的 thymeleaf 漏洞,实际上这类的漏洞有专门的名称——SSTI(模板注入漏洞) + +不过之所以在这里把这个漏洞归于文件包含,是因为见过这种漏洞式实例,所以只是简单提一下,大家可以举一反三,思考其他框架出现这种漏洞的可能性。 + +那么,这类的漏洞应该如何修复或者如何避免呢? + +## 0x03 修复方案 + +对于 JSP 文件包含来说,其所造成的影响有限,出现的频率基本上可以忽略不计(基本上没人这样写代码,import 引用的资源一般都是写死的) + +但对于thymeleaf等模板框架来说,出现这种情况的漏洞还是极有可能的,所以这里简单说说thymeleaf修复方式,其他模板也是同理,根据模板的特性来修复即可。 + +在上文中我们提到,`createView()`方法的作用是根据视图名创建对应的`View`,实际上 在该方法中,Thymeleaf 对`redirect:`和`forward:`有特殊处理: + +![24.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/24.png) + +跟进RedirectView这个重定向类,然后可以发现: + +![25.png](https://github.com/cn-panda/JavaCodeAudit/blob/master/%E3%80%9006%E3%80%91%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E9%99%85%E6%A1%88%E4%BE%8B%E4%BB%8B%E7%BB%8D/img/25.png) + +简单来说这里的逻辑会根据填写的返回值来判断是重定向(`redirect:`)还是请求转发(`forward:`),然后调用原生的Servlet的重定向或者请求转发方法,从而就不会进入执行SpEL表达式的流程,也就不会产生所谓的漏洞了。 + +因此在视图名称可控的情况下,使用了如下几种方式的代码不受影响: +- 使用`@ResponseBody`注解 + +- `rerturn` 时的内容 由`redirect:`或`forward:`开头 + +- 参数中有`HttpServletResponse`,response已经被处理 + +- Thymeleaf 使用最新版,新版已经修复了这两个问题(视图名称可控、模板预处理变量可控) + +jsp 的文件包含实际上不好找,我在 CVE 官网上找到的基本上都是任意文件读取漏洞,之前遇到的实例也不好发出来,因此也就不在这里举实际例子了 + +## 0x05 总结 +这篇文章实际上拖了很久,实质性的内容也不是很多,顶多是一个思维发散的理解,希望对新入门的童鞋有所收获 + +## 0x06 参考 +https://vulncat.fortify.com/zh-cn/detail?id=desc.dataflow.dotnet.dangerous_file_inclusion +https://xz.aliyun.com/t/3357 +http://x2y.pw/2020/11/15/Thymeleaf-模板漏洞分析/ +https://waylau.gitbooks.io/thymeleaf-tutorial/content/docs/standard-expression-syntax.html