New file |
| | |
| | | HELP.md |
| | | target/ |
| | | !.mvn/wrapper/maven-wrapper.jar |
| | | !**/src/main/** |
| | | !**/src/test/** |
| | | |
| | | ### 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/ |
| | | |
| | | ### VS Code ### |
| | | .vscode/ |
New file |
| | |
| | | /* |
| | | * 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(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip |
| | | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar |
New file |
| | |
| | | #!/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 "$@" |
New file |
| | |
| | | @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% |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-parent</artifactId> |
| | | <version>2.0.4.RELEASE</version> |
| | | <relativePath/> <!-- lookup parent from repository --> |
| | | </parent> |
| | | <groupId>com.sinata</groupId> |
| | | <artifactId>demo</artifactId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | <name>eureka</name> |
| | | <description>Eureka project for Spring Boot</description> |
| | | |
| | | <packaging>jar</packaging> |
| | | |
| | | <properties> |
| | | <java.version>1.8</java.version> |
| | | <spring-cloud.version>Finchley.SR1</spring-cloud.version> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.springframework.cloud</groupId> |
| | | <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> |
| | | </dependency> |
| | | <!-- 添加安全认证依赖 --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-security</artifactId> |
| | | </dependency> |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-tomcat</artifactId> |
| | | <scope>provided</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>javax.servlet</groupId> |
| | | <artifactId>javax.servlet-api</artifactId> |
| | | <version>3.1.0</version> |
| | | <scope>provided</scope> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-test</artifactId> |
| | | <scope>test</scope> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.junit.vintage</groupId> |
| | | <artifactId>junit-vintage-engine</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <dependencyManagement> |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.springframework.cloud</groupId> |
| | | <artifactId>spring-cloud-dependencies</artifactId> |
| | | <version>${spring-cloud.version}</version> |
| | | <type>pom</type> |
| | | <scope>import</scope> |
| | | </dependency> |
| | | </dependencies> |
| | | </dependencyManagement> |
| | | |
| | | <build> |
| | | <plugins> |
| | | <plugin> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-maven-plugin</artifactId> |
| | | </plugin> |
| | | </plugins> |
| | | </build> |
| | | |
| | | </project> |
New file |
| | |
| | | package com.sinata.eureka; |
| | | |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | import org.springframework.boot.builder.SpringApplicationBuilder; |
| | | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
| | | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; |
| | | |
| | | @EnableEurekaServer//开启服务治理 |
| | | @SpringBootApplication |
| | | public class EurekaApplication extends SpringBootServletInitializer { |
| | | |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(EurekaApplication.class, args); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { |
| | | return builder.sources(EurekaApplication.class); |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.eureka.config; |
| | | |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
| | | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
| | | import org.springframework.security.config.http.SessionCreationPolicy; |
| | | |
| | | /** |
| | | * 基于web安全认证 |
| | | */ |
| | | @Configuration |
| | | @EnableWebSecurity |
| | | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { |
| | | @Override |
| | | public void configure(HttpSecurity http) throws Exception { |
| | | // Configure HttpSecurity as needed (e.g. enable http basic). |
| | | http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER); |
| | | http.csrf().disable(); |
| | | //注意:为了可以使用 http://${user}:${password}@${host}:${port}/eureka/ 这种方式登录,所以必须是httpBasic, |
| | | // 如果是form方式,不能使用url格式登录 |
| | | http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); |
| | | } |
| | | } |
New file |
| | |
| | | server: |
| | | port: 8000 #服务端口号 |
| | | |
| | | spring: |
| | | application: |
| | | name: eureka-center #服务名称 |
| | | security: |
| | | basic: |
| | | enable: true #开启基于HTTP basic的认证 |
| | | user: #配置用户的账号信息 |
| | | name: sinata |
| | | password: sinata |
| | | |
| | | eureka: |
| | | instance: |
| | | hostname: 127.0.0.1 #注册中心地址 |
| | | client: |
| | | service-url: #客户端调用地址 |
| | | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ |
| | | register-with-eureka: false #是否将自己注册到Eureka服务中,因为该应用本身就是注册中心,不需要再注册自己(集群的时候为true) |
| | | fetch-registry: false #是否从Eureka中获取注册信息,因为自己为注册中心,不会在该应用中的检索服务信息 |
| | | server: |
| | | enable-self-preservation: false #禁用自我保护模式,服务不可用时及时从注册中心剔除 |
| | | eviction-interval-timer-in-ms: 4000 |
New file |
| | |
| | | HELP.md |
| | | target/ |
| | | !.mvn/wrapper/maven-wrapper.jar |
| | | !**/src/main/** |
| | | !**/src/test/** |
| | | |
| | | ### 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/ |
| | | |
| | | ### VS Code ### |
| | | .vscode/ |
New file |
| | |
| | | /* |
| | | * 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(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip |
| | | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar |
New file |
| | |
| | | #!/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 "$@" |
New file |
| | |
| | | @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% |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-parent</artifactId> |
| | | <version>2.0.4.RELEASE</version> |
| | | <relativePath/> <!-- lookup parent from repository --> |
| | | </parent> |
| | | <groupId>com.sinata</groupId> |
| | | <artifactId>zuul</artifactId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | <name>zuul</name> |
| | | <description>Zuul project for Spring Boot</description> |
| | | |
| | | <packaging>jar</packaging> |
| | | |
| | | <properties> |
| | | <java.version>1.8</java.version> |
| | | <spring-cloud.version>Finchley.SR1</spring-cloud.version> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.springframework.cloud</groupId> |
| | | <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.cloud</groupId> |
| | | <artifactId>spring-cloud-starter-netflix-zuul</artifactId> |
| | | </dependency> |
| | | |
| | | <!--引入swagger--> |
| | | <dependency> |
| | | <groupId>com.spring4all</groupId> |
| | | <artifactId>swagger-spring-boot-starter</artifactId> |
| | | <version>1.7.0.RELEASE</version> |
| | | </dependency> |
| | | <!-- jedis --> |
| | | <dependency> |
| | | <groupId>redis.clients</groupId> |
| | | <artifactId>jedis</artifactId> |
| | | <version>2.9.0</version> |
| | | </dependency> |
| | | |
| | | <!--<dependency>--> |
| | | <!--<groupId>org.springframework.boot</groupId>--> |
| | | <!--<artifactId>spring-boot-starter-tomcat</artifactId>--> |
| | | <!--<scope>provided</scope>--> |
| | | <!--</dependency>--> |
| | | <!--<dependency>--> |
| | | <!--<groupId>javax.servlet</groupId>--> |
| | | <!--<artifactId>javax.servlet-api</artifactId>--> |
| | | <!--<version>3.1.0</version>--> |
| | | <!--<scope>provided</scope>--> |
| | | <!--</dependency>--> |
| | | |
| | | |
| | | <!-- netty --> |
| | | <dependency> |
| | | <groupId>io.netty</groupId> |
| | | <artifactId>netty-all</artifactId> |
| | | <version>4.1.27.Final</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>fastjson</artifactId> |
| | | <version>1.2.47</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-test</artifactId> |
| | | <scope>test</scope> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.junit.vintage</groupId> |
| | | <artifactId>junit-vintage-engine</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <dependencyManagement> |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.springframework.cloud</groupId> |
| | | <artifactId>spring-cloud-dependencies</artifactId> |
| | | <version>${spring-cloud.version}</version> |
| | | <type>pom</type> |
| | | <scope>import</scope> |
| | | </dependency> |
| | | </dependencies> |
| | | </dependencyManagement> |
| | | |
| | | <build> |
| | | <plugins> |
| | | <plugin> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-maven-plugin</artifactId> |
| | | </plugin> |
| | | </plugins> |
| | | </build> |
| | | |
| | | </project> |
New file |
| | |
| | | package com.sinata.zuul; |
| | | |
| | | import com.sinata.zuul.util.applets.NettyServer0; |
| | | import com.sinata.zuul.util.echo.NettyServer; |
| | | import com.spring4all.swagger.EnableSwagger2Doc; |
| | | import org.apache.http.client.HttpClient; |
| | | import org.apache.http.config.SocketConfig; |
| | | import org.apache.http.impl.client.HttpClientBuilder; |
| | | import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | import org.springframework.boot.builder.SpringApplicationBuilder; |
| | | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
| | | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; |
| | | import org.springframework.cloud.client.loadbalancer.LoadBalanced; |
| | | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Primary; |
| | | import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; |
| | | import org.springframework.http.converter.StringHttpMessageConverter; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.client.RestTemplate; |
| | | import org.springframework.web.cors.CorsConfiguration; |
| | | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
| | | import org.springframework.web.filter.CorsFilter; |
| | | import springfox.documentation.swagger.web.SwaggerResource; |
| | | import springfox.documentation.swagger.web.SwaggerResourcesProvider; |
| | | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | |
| | | @EnableSwagger2Doc |
| | | @EnableZuulProxy//开启网关服务 |
| | | @EnableDiscoveryClient//开启eureka客户端的消费者 |
| | | @SpringBootApplication |
| | | public class ZuulApplication /*extends SpringBootServletInitializer*/ { |
| | | |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(ZuulApplication.class, args); |
| | | NettyServer nettyServer = new NettyServer(); |
| | | nettyServer.bind(); |
| | | NettyServer0 nettyServer0 = new NettyServer0(); |
| | | nettyServer0.bind(); |
| | | } |
| | | |
| | | |
| | | @Bean //SpringCloud内部服务质检使用服务名调用 |
| | | @LoadBalanced |
| | | public RestTemplate internalRestTemplate() { |
| | | PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); |
| | | connectionManager.setDefaultSocketConfig(SocketConfig.custom().setTcpNoDelay(true).build()); |
| | | connectionManager.setDefaultMaxPerRoute(100);//最大并发连接 |
| | | connectionManager.setMaxTotal(200); // 总的最大连接数 |
| | | HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager).build(); |
| | | HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); |
| | | httpRequestFactory.setConnectionRequestTimeout(30 * 1000); |
| | | httpRequestFactory.setConnectTimeout(30 * 3000); |
| | | httpRequestFactory.setReadTimeout(30 * 3000); |
| | | RestTemplate restTemplate = new RestTemplate(httpRequestFactory); |
| | | restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); |
| | | return restTemplate; |
| | | } |
| | | |
| | | |
| | | |
| | | // /** |
| | | // * 向Spring容器中定义RestTemplate对象 |
| | | // * @return |
| | | // */ |
| | | // @Bean //必须new 一个RestTemplate并放入spring容器当中,否则启动时报错 |
| | | // public RestTemplate restTemplate() { |
| | | // PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); |
| | | // connectionManager.setDefaultSocketConfig(SocketConfig.custom().setTcpNoDelay(true).build()); |
| | | // connectionManager.setDefaultMaxPerRoute(100);//最大并发连接 |
| | | // connectionManager.setMaxTotal(200); // 总的最大连接数 |
| | | // HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager).build(); |
| | | // HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); |
| | | // httpRequestFactory.setConnectionRequestTimeout(30 * 1000); |
| | | // httpRequestFactory.setConnectTimeout(30 * 3000); |
| | | // httpRequestFactory.setReadTimeout(30 * 3000); |
| | | // RestTemplate restTemplate = new RestTemplate(httpRequestFactory); |
| | | // restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); |
| | | // return restTemplate; |
| | | // } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 配置Swagger |
| | | */ |
| | | @Component |
| | | @Primary |
| | | class DocumentationConfig implements SwaggerResourcesProvider { |
| | | @Override |
| | | public List<SwaggerResource> get() { |
| | | List resource=new ArrayList<>(); |
| | | //name可以随便写,location前缀要与zuul配置的path一致。zuul开了token验证,要加上token,否则不用加?token=1 |
| | | resource.add(swaggerResource("user","/user-server/v2/api-docs","1.0")); |
| | | resource.add(swaggerResource("driver","/driver-server/v2/api-docs","1.0")); |
| | | // resource.add(swaggerResource("dispatch","/dispatch-server/v2/api-docs","1.0")); |
| | | return resource; |
| | | } |
| | | |
| | | //name可以随便写,location前缀要与zuul配置的path一致 |
| | | private SwaggerResource swaggerResource(String name, String location, String version){ |
| | | SwaggerResource swaggerResource=new SwaggerResource(); |
| | | swaggerResource.setName(name); |
| | | swaggerResource.setLocation(location); |
| | | swaggerResource.setSwaggerVersion(version); |
| | | return swaggerResource; |
| | | } |
| | | } |
| | | |
| | | |
| | | // @Override |
| | | // protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { |
| | | // return builder.sources(ZuulApplication.class); |
| | | // } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.config; |
| | | |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.context.annotation.PropertySource; |
| | | import redis.clients.jedis.JedisPool; |
| | | import redis.clients.jedis.JedisPoolConfig; |
| | | |
| | | @Configuration |
| | | @PropertySource("classpath:redis.properties") |
| | | public class RedisConfig { |
| | | @Value("${spring.redis.host}") |
| | | private String host; |
| | | |
| | | @Value("${spring.redis.port}") |
| | | private int port; |
| | | |
| | | @Value("${spring.redis.timeout}") |
| | | private int timeout; |
| | | |
| | | @Value("${spring.redis.jedis.pool.max-idle}") |
| | | private int maxIdle; |
| | | |
| | | @Value("${spring.redis.jedis.pool.min-idle}") |
| | | private int minIdle; |
| | | |
| | | @Value("${spring.redis.jedis.pool.max-wait}") |
| | | private long maxWaitMillis; |
| | | |
| | | @Value("${spring.redis.jedis.pool.max-active}") |
| | | private int maxTotal; |
| | | |
| | | @Value("${spring.redis.password}") |
| | | private String password; |
| | | |
| | | @Value("${spring.redis.block-when-exhausted}") |
| | | private boolean blockWhenExhausted; |
| | | |
| | | @Bean |
| | | public JedisPool redisPoolFactory() throws Exception{ |
| | | JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); |
| | | jedisPoolConfig.setMaxIdle(maxIdle); |
| | | jedisPoolConfig.setMinIdle(minIdle); |
| | | jedisPoolConfig.setMaxTotal(maxTotal); |
| | | jedisPoolConfig.setMaxWaitMillis(maxWaitMillis); |
| | | // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true |
| | | jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted); |
| | | // 是否启用pool的jmx管理功能, 默认true |
| | | jedisPoolConfig.setJmxEnabled(true); |
| | | JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password); |
| | | return jedisPool; |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.controller; |
| | | |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.sinata.zuul.util.ResultUtil; |
| | | import com.sinata.zuul.util.applets.NettyWebSocketController; |
| | | import com.sinata.zuul.util.echo.NettyChannelMap; |
| | | import com.sinata.zuul.util.echo.NettyServerController; |
| | | import io.netty.channel.ChannelHandlerContext; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.ResponseBody; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | @RestController |
| | | @RequestMapping("/netty") |
| | | public class NettyController { |
| | | |
| | | |
| | | /** |
| | | * 向客户端推送消息 |
| | | * @param id |
| | | * @param msg |
| | | */ |
| | | @ResponseBody |
| | | @PostMapping("/sendMsgToClient") |
| | | public String sendMsgToClient(Integer id, Integer type, String msg){ |
| | | if(type == 1){//用户端 |
| | | ChannelHandlerContext channel = NettyChannelMap.getData("Applets" + id);//小程序 |
| | | if(null != channel){ |
| | | NettyWebSocketController.sendMsgToClient(channel, msg); |
| | | return JSON.toJSONString(ResultUtil.success()); |
| | | } |
| | | channel = NettyChannelMap.getData("USER" + id); |
| | | if(null != channel){ |
| | | NettyServerController.sendMsgToClient(channel, msg); |
| | | return JSON.toJSONString(ResultUtil.success()); |
| | | } |
| | | return JSON.toJSONString(ResultUtil.error("推送失败-----用户id=" + id)); |
| | | |
| | | } |
| | | |
| | | if(type == 2){//司机端 |
| | | ChannelHandlerContext channel = NettyChannelMap.getData("DRIVER" + id); |
| | | if(null != channel){ |
| | | NettyServerController.sendMsgToClient(channel, msg); |
| | | return JSON.toJSONString(ResultUtil.success()); |
| | | } |
| | | return JSON.toJSONString(ResultUtil.error("推送失败-----司机id=" + id)); |
| | | } |
| | | |
| | | return JSON.toJSONString(ResultUtil.error("推送失败")); |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.controller; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.sinata.zuul.util.RedisUtil; |
| | | import com.sinata.zuul.util.ResultUtil; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.ResponseBody; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | @RestController |
| | | @RequestMapping("/redis") |
| | | public class RedisController { |
| | | |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | |
| | | /** |
| | | * 从redis中获取数据 |
| | | * @param key |
| | | * @return |
| | | */ |
| | | @ResponseBody |
| | | @PostMapping("/getValue") |
| | | public String getValue(String key){ |
| | | String value = redisUtil.getValue(key); |
| | | return JSON.toJSONString(ResultUtil.success(value)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 批量获取 |
| | | * @param keys |
| | | * @return |
| | | */ |
| | | @ResponseBody |
| | | @PostMapping("/getValues") |
| | | public String getValues(String keys){ |
| | | String[] split = keys.split(","); |
| | | List<String> list = Arrays.asList(split); |
| | | List<Object> values = redisUtil.getValues(list); |
| | | return JSON.toJSONString(ResultUtil.success(values)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 存值 |
| | | * @param key |
| | | * @param value |
| | | * @param time |
| | | */ |
| | | @ResponseBody |
| | | @PostMapping("/setValue") |
| | | public String setValue(String key, String value, int time){ |
| | | redisUtil.setStrValue(key, value, time); |
| | | return JSON.toJSONString(ResultUtil.success()); |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/setValue_") |
| | | public String setValue_(String key, String value){ |
| | | redisUtil.setStrValue(key, value); |
| | | return JSON.toJSONString(ResultUtil.success()); |
| | | } |
| | | |
| | | /** |
| | | * 删除redis数据 |
| | | * @param key |
| | | * @return |
| | | */ |
| | | @ResponseBody |
| | | @PostMapping("/remove") |
| | | public String remove(String key){ |
| | | redisUtil.remove(key); |
| | | return JSON.toJSONString(ResultUtil.success()); |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util; |
| | | |
| | | |
| | | import org.springframework.boot.web.servlet.ServletComponentScan; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.*; |
| | | import javax.servlet.annotation.WebFilter; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * 统一配置跨域处理 |
| | | */ |
| | | @Order(-100) |
| | | @Component |
| | | @ServletComponentScan |
| | | @WebFilter(urlPatterns = "/*",filterName = "crossOriginFilter") |
| | | public class CrossOriginFilter implements Filter { |
| | | @Override |
| | | public void init(FilterConfig filterConfig) throws ServletException { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { |
| | | HttpServletResponse response = (HttpServletResponse) servletResponse; |
| | | HttpServletRequest request = (HttpServletRequest) servletRequest; |
| | | // 允许哪些Origin发起跨域请求 |
| | | // response.setHeader( "Access-Control-Allow-Origin", config.getInitParameter( "AccessControlAllowOrigin" ) ); |
| | | response.setHeader( "Access-Control-Allow-Origin", "*" ); |
| | | // 允许请求的方法 |
| | | response.setHeader( "Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PUT" ); |
| | | //多少秒内,不需要再发送预检验请求,可以缓存该结果 |
| | | response.setHeader( "Access-Control-Max-Age", "3600" ); |
| | | // 表明它允许跨域请求包含xxx头 |
| | | response.setHeader( "Access-Control-Allow-Headers", "x-auth-token,Origin,Access-Token,X-Requested-With,Content-Type, Accept, Authorization" ); |
| | | //是否允许浏览器携带用户身份信息(cookie) |
| | | response.setHeader( "Access-Control-Allow-Credentials", "true" ); |
| | | //prefight请求 |
| | | if (request.getMethod().equals( "OPTIONS" )) { |
| | | response.setStatus( 204 ); |
| | | return; |
| | | } |
| | | filterChain.doFilter( servletRequest, response ); |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 高德地图的地理编码工具类 |
| | | */ |
| | | @Component |
| | | public class GDMapGeocodingUtil { |
| | | |
| | | private String key = "79293423abef825bf17db8568fa93d98"; |
| | | |
| | | @Autowired |
| | | private RestTemplate restTemplate; |
| | | |
| | | |
| | | /** |
| | | * 将行政区域名称转化为坐标 |
| | | * @param province |
| | | * @param city |
| | | * @param county |
| | | * @param address |
| | | * @return |
| | | */ |
| | | public Map<String, Object> geocoding(String province, String city, String county, String address){ |
| | | Map<String, Object> map = new HashMap<>(); |
| | | if(StringUtil.isEmpty(province)){ |
| | | map.put("status", -1); |
| | | map.put("data", "省不能为空"); |
| | | return map; |
| | | } |
| | | if((StringUtil.isEmpty(city) && StringUtil.isNotEmpty(county)) || (StringUtil.isEmpty(city) && StringUtil.isNotEmpty(address))){ |
| | | map.put("status", -1); |
| | | map.put("data", "市不能为空"); |
| | | return map; |
| | | } |
| | | if((StringUtil.isEmpty(county) && StringUtil.isNotEmpty(address))){ |
| | | map.put("status", -1); |
| | | map.put("data", "县/区不能为空"); |
| | | return map; |
| | | } |
| | | |
| | | String url = "https://restapi.amap.com/v3/geocode/geo?key=" + key + "&output=JSON"; |
| | | url += "&address=" + province + (StringUtil.isNotEmpty(city) ? city : "") + (StringUtil.isNotEmpty(county) ? county : "") + (StringUtil.isNotEmpty(address) ? address : ""); |
| | | String forObject = restTemplate.getForObject(url, String.class); |
| | | JSONObject jsonObject = JSON.parseObject(forObject); |
| | | String status = jsonObject.getString("status"); |
| | | List<String> list = new ArrayList<>(); |
| | | if(status.equals("1")){ |
| | | JSONArray geocodes = jsonObject.getJSONArray("geocodes"); |
| | | for(int i = 0; i < geocodes.size(); i++){ |
| | | String location = geocodes.getJSONObject(i).getString("location"); |
| | | list.add(location); |
| | | } |
| | | } |
| | | map.put("status", 0); |
| | | map.put("data", list); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据经纬度获取行政区域信息 |
| | | * @param lon |
| | | * @param lan |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public Map<String, String> geocode(String lon, String lan) throws Exception{ |
| | | String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + key + "&location=" + lon + "," + lan; |
| | | String forObject = restTemplate.getForObject(url, String.class); |
| | | JSONObject jsonObject = JSON.parseObject(forObject); |
| | | Map<String, String> map = new HashMap<>(); |
| | | if(jsonObject.getString("status").equals("1")){ |
| | | JSONObject regeocode = jsonObject.getJSONObject("regeocode"); |
| | | JSONObject addressComponent = regeocode.getJSONObject("addressComponent"); |
| | | String address = regeocode.getString("formatted_address"); |
| | | map.put("address", address); |
| | | String code = addressComponent.getString("adcode"); |
| | | String province = addressComponent.getString("province"); |
| | | String city = addressComponent.getString("city"); |
| | | String district = addressComponent.getString("district"); |
| | | map.put("province", province); |
| | | map.put("provinceCode", code.substring(0, 2) + "0000"); |
| | | map.put("city", city); |
| | | map.put("cityCode", code.substring(0, 4) + "00"); |
| | | map.put("district", district); |
| | | map.put("districtCode", code); |
| | | } |
| | | return map; |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util; |
| | | |
| | | import com.sinata.zuul.util.applets.NettyServer0; |
| | | import com.sinata.zuul.util.echo.NettyServer; |
| | | |
| | | import javax.servlet.ServletContextEvent; |
| | | import javax.servlet.ServletContextListener; |
| | | import javax.servlet.annotation.WebListener; |
| | | |
| | | /** |
| | | * 启动netty监听器 |
| | | */ |
| | | @WebListener |
| | | public class NettyStartListener implements ServletContextListener { |
| | | |
| | | |
| | | @Override |
| | | public void contextInitialized(ServletContextEvent sce) { |
| | | Thread thread = new Thread(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | // NettyServer nettyServer = new NettyServer(); |
| | | // nettyServer.bind(); |
| | | // |
| | | // NettyServer0 nettyServer0 = new NettyServer0(); |
| | | // nettyServer0.bind(); |
| | | } |
| | | }); |
| | | thread.start(); |
| | | } |
| | | |
| | | @Override |
| | | public void contextDestroyed(ServletContextEvent sce) { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import redis.clients.jedis.Jedis; |
| | | import redis.clients.jedis.JedisPool; |
| | | import redis.clients.jedis.Pipeline; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * Redis工具类 |
| | | */ |
| | | @Component |
| | | public class RedisUtil { |
| | | |
| | | @Autowired |
| | | private JedisPool jedisPool; |
| | | |
| | | |
| | | /** |
| | | * 向redis中存储字符串没有过期时间 |
| | | * @param key |
| | | * @param value |
| | | */ |
| | | public void setStrValue(String key, String value){ |
| | | if(StringUtil.isNotEmpty(key)){ |
| | | Jedis resource = jedisPool.getResource(); |
| | | String set = resource.set(key, value); |
| | | closeJedis(resource); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 以分钟为单位设置存储值(设置过期时间) |
| | | * @param key |
| | | * @param value |
| | | * @param time 秒 |
| | | */ |
| | | public void setStrValue(String key, String value, int time){ |
| | | if(StringUtil.isNotEmpty(key)){ |
| | | Jedis resource = jedisPool.getResource(); |
| | | String setex = resource.setex(key, time, value); |
| | | closeJedis(resource); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 从redis中获取值 |
| | | * @param key |
| | | * @return |
| | | */ |
| | | public String getValue(String key){ |
| | | if(StringUtil.isNotEmpty(key)){ |
| | | Jedis resource = jedisPool.getResource(); |
| | | String data = resource.get(key); |
| | | closeJedis(resource); |
| | | return data; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 批量获取 |
| | | * @param kes |
| | | * @return |
| | | */ |
| | | public List<Object> getValues(List<String> kes){ |
| | | if(null != kes){ |
| | | Jedis resource = jedisPool.getResource(); |
| | | Pipeline pipelined = resource.pipelined(); |
| | | for(String key : kes){ |
| | | pipelined.get(key); |
| | | } |
| | | List<Object> list = pipelined.syncAndReturnAll(); |
| | | |
| | | closeJedis(resource); |
| | | pipelined.clear(); |
| | | try { |
| | | pipelined.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | List<Object> data = new ArrayList<>(); |
| | | for(Object o : list){ |
| | | if(null != o){ |
| | | data.add(o); |
| | | } |
| | | } |
| | | return data; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 删除key |
| | | * @param key |
| | | */ |
| | | public void remove(String key){ |
| | | if(StringUtil.isNotEmpty(key)){ |
| | | Jedis resource = jedisPool.getResource(); |
| | | Long del = resource.del(key); |
| | | closeJedis(resource); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 删除资源 |
| | | * @param jedis |
| | | */ |
| | | public void closeJedis(Jedis jedis){ |
| | | if(null != jedis){ |
| | | jedis.close(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | |
| | | /** |
| | | * 定义统一返回对象 |
| | | */ |
| | | @ApiModel(value = "统一返回结果集") |
| | | public class ResultUtil<T> { |
| | | |
| | | public static final Integer SUCCESS = 200; |
| | | |
| | | public static final Integer PARAM_ERROR = 300; |
| | | |
| | | public static final Integer RUNTIME_ERROR = 400; |
| | | |
| | | public static final Integer ERROR = 500; |
| | | |
| | | public static final Integer TOKEN_ERROR = 600; |
| | | |
| | | public static final Integer SIGN_ERROR = 700; |
| | | |
| | | public static final String Token = "TOKEN_INVALID"; |
| | | |
| | | public static final String SIGN = "SIGN_INVALID"; |
| | | |
| | | @ApiModelProperty(name = "code", value = "业务状态码 200:成功,300:参数错误,400:运行异常,500:其他异常, 600:token无效,需重新登录,700:签名无效") |
| | | private Integer code;//备用状态码 |
| | | |
| | | @ApiModelProperty(name = "msg", value = "返回结果说明") |
| | | private String msg;//返回说明 |
| | | |
| | | @ApiModelProperty(name = "data", value = "返回结果值") |
| | | private T data;//返回数据 |
| | | |
| | | |
| | | |
| | | public String getMsg() { |
| | | return msg; |
| | | } |
| | | |
| | | public T getData() { |
| | | return data; |
| | | } |
| | | |
| | | |
| | | public Integer getCode() { |
| | | return code; |
| | | } |
| | | |
| | | private ResultUtil(Integer code, String msg) { |
| | | this.code = code; |
| | | this.msg = msg; |
| | | } |
| | | |
| | | private ResultUtil(Integer code, String msg, T data) { |
| | | this.code = code; |
| | | this.msg = msg; |
| | | this.data = data; |
| | | } |
| | | |
| | | |
| | | public static <T> ResultUtil<T> getResult(Integer code, String msg){ |
| | | return new ResultUtil<>(code, msg); |
| | | } |
| | | |
| | | public static <T> ResultUtil<T> getResult(Integer code, String msg, T data){ |
| | | return new ResultUtil<>(code, msg, data); |
| | | } |
| | | |
| | | /** |
| | | * 错误信息 |
| | | * @return |
| | | */ |
| | | public static ResultUtil error(String mag){ |
| | | return ResultUtil.getResult(ResultUtil.ERROR, mag, new JSONObject()); |
| | | } |
| | | |
| | | /** |
| | | * 错误信息 |
| | | * @return |
| | | */ |
| | | public static <T> ResultUtil <T> error(String mag, T obj){ |
| | | return ResultUtil.getResult(ResultUtil.ERROR, mag, obj); |
| | | } |
| | | |
| | | /** |
| | | * token失效 |
| | | * @return |
| | | */ |
| | | public static ResultUtil tokenErr(){ |
| | | return ResultUtil.getResult(ResultUtil.TOKEN_ERROR, ResultUtil.Token, new JSONObject()); |
| | | } |
| | | |
| | | /** |
| | | * token失效 |
| | | * @return |
| | | */ |
| | | public static ResultUtil tokenErr(String msg){ |
| | | return ResultUtil.getResult(ResultUtil.TOKEN_ERROR, msg, new JSONObject()); |
| | | } |
| | | |
| | | /** |
| | | * 参数异常 |
| | | * @return |
| | | */ |
| | | public static ResultUtil paranErr(){ |
| | | return ResultUtil.getResult(ResultUtil.PARAM_ERROR, "PARAM_ERROR", new JSONObject()); |
| | | } |
| | | |
| | | /** |
| | | * 参数异常 |
| | | * @return |
| | | */ |
| | | public static <T> ResultUtil<T> paranErr(T data){ |
| | | return ResultUtil.getResult(ResultUtil.PARAM_ERROR, "SYSTEM_RUN_ERROR", data); |
| | | } |
| | | |
| | | /** |
| | | * 运行异常 |
| | | * @return |
| | | */ |
| | | public static ResultUtil runErr(){ |
| | | return ResultUtil.getResult(ResultUtil.RUNTIME_ERROR, "SYSTEM_RUN_ERROR", new JSONObject()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 运行异常 |
| | | * @return |
| | | */ |
| | | public static <T>ResultUtil<T> runErr(T data){ |
| | | return ResultUtil.getResult(ResultUtil.RUNTIME_ERROR, "SYSTEM_RUN_ERROR", data); |
| | | } |
| | | |
| | | /** |
| | | * 运行异常 |
| | | * @return |
| | | */ |
| | | public static <T>ResultUtil<T> runErr(T data, String msg){ |
| | | return ResultUtil.getResult(ResultUtil.RUNTIME_ERROR, msg, data); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 返回成功 |
| | | * @param |
| | | * @return |
| | | */ |
| | | public static ResultUtil success(){ |
| | | return ResultUtil.getResult(ResultUtil.SUCCESS, "SUCCESS", new JSONObject()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 返回成功 |
| | | * @param data |
| | | * @param <T> |
| | | * @return |
| | | */ |
| | | public static <T> ResultUtil<T> success(T data){ |
| | | return ResultUtil.getResult(ResultUtil.SUCCESS, "SUCCESS", data); |
| | | } |
| | | |
| | | /** |
| | | * 返回成功 |
| | | * @param msg |
| | | * @param data |
| | | * @param <T> |
| | | * @return |
| | | */ |
| | | public static <T> ResultUtil<T> success(String msg, T data){ |
| | | return ResultUtil.getResult(ResultUtil.SUCCESS, msg, data); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 签名无效 |
| | | * @param <T> |
| | | * @return |
| | | */ |
| | | public static <T> ResultUtil<T> sign(){ |
| | | return ResultUtil.getResult(ResultUtil.SIGN_ERROR, SIGN); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util; |
| | | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.text.DecimalFormat; |
| | | import java.text.NumberFormat; |
| | | import java.util.*; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * 基本数据处理工具类 |
| | | */ |
| | | public class SinataUtil { |
| | | /** |
| | | * List集合分页<br/> |
| | | * 创建人:Mryang<br/> |
| | | * 时间:2016年7月28日-下午2:58:14 <br/> |
| | | * @param <T> |
| | | * @param pageNo |
| | | * @param pageSize |
| | | * @param list |
| | | * @throws Exception List<UserOrderList> <br/> |
| | | */ |
| | | public static <T> List<T> listpage(int pageNo, int pageSize, List<T> list) throws Exception { |
| | | List<T> result = new ArrayList<T>(); |
| | | if (list != null && list.size() > 0) { |
| | | int allCount = list.size(); |
| | | if(pageNo > 1 && allCount < pageSize) { |
| | | return new ArrayList<>(); |
| | | } |
| | | int pageCount = (allCount + pageSize - 1) / pageSize; |
| | | if (pageNo >= pageCount) { |
| | | pageNo = pageCount; |
| | | } |
| | | int start = (pageNo - 1) * pageSize; |
| | | int end = pageNo * pageSize; |
| | | if (end >= allCount) { |
| | | end = allCount; |
| | | } |
| | | for (int i = start; i < end; i++) { |
| | | result.add(list.get(i)); |
| | | } |
| | | } |
| | | return (result != null && result.size() > 0) ? result : new ArrayList<T>(); |
| | | } |
| | | |
| | | /** |
| | | * Double类型取整 |
| | | * @param num |
| | | * @return |
| | | */ |
| | | public static String doubleTrans(double num) { |
| | | return String.valueOf((long) num); |
| | | } |
| | | |
| | | /** |
| | | * Double类型保留1位小数 |
| | | * |
| | | * @param num |
| | | * @return |
| | | */ |
| | | public static String doubleRetainOne(double num) { |
| | | DecimalFormat dfs = new DecimalFormat("0.0"); |
| | | return dfs.format(num); |
| | | } |
| | | |
| | | /** |
| | | * Double类型保留2位小数 |
| | | * |
| | | * @param num |
| | | * @return |
| | | */ |
| | | public static String doubleRetainTwo(double num) { |
| | | DecimalFormat dfs = new DecimalFormat("0.00"); |
| | | String.format("%.2f", num); |
| | | return dfs.format(num); |
| | | } |
| | | |
| | | /** |
| | | * Double类型保留1位小数(四舍五入) |
| | | * |
| | | * @param num |
| | | * @return |
| | | */ |
| | | public static String doubleForwardOne(double num) { |
| | | return String.format("%.1f", num); |
| | | } |
| | | |
| | | /** |
| | | * Double类型保留2位小数(四舍五入) |
| | | * |
| | | * @param num |
| | | * @return |
| | | */ |
| | | public static String doubleForwardTwo(double num) { |
| | | return String.format("%.2f", num); |
| | | } |
| | | |
| | | /** |
| | | * 字符串转换成Ascii |
| | | * |
| | | * @param value |
| | | * @return |
| | | */ |
| | | public static String stringToAscii(String value) { |
| | | StringBuffer sbu = new StringBuffer(); |
| | | char[] chars = value.toCharArray(); |
| | | for (int i = 0; i < chars.length; i++) { |
| | | if (i != chars.length - 1) { |
| | | sbu.append((int) chars[i]); |
| | | } else { |
| | | sbu.append((int) chars[i]); |
| | | } |
| | | } |
| | | return sbu.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 小数转换为百分比 |
| | | * |
| | | * @param decimal |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static String decTurnPercent(double decimal) { |
| | | NumberFormat num = NumberFormat.getPercentInstance(); |
| | | num.setMaximumIntegerDigits(3); |
| | | num.setMaximumFractionDigits(2); |
| | | return num.format(decimal); |
| | | } |
| | | |
| | | /** |
| | | * Ascii转换成字符串 |
| | | * |
| | | * @param value |
| | | * @return |
| | | */ |
| | | public static String asciiToString(String value) { |
| | | String[] chars = value.split(","); |
| | | StringBuffer sbu = new StringBuffer(); |
| | | for (int i = 0; i < chars.length; i++) { |
| | | sbu.append((char) Integer.parseInt(chars[i])); |
| | | } |
| | | return sbu.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 字符串转换unicode |
| | | * |
| | | * @param string |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static String string2Unicode(String string) { |
| | | StringBuffer unicode = new StringBuffer(); |
| | | for (int i = 0; i < string.length(); i++) { |
| | | // 取出每一个字符 |
| | | char c = string.charAt(i); |
| | | // 转换为unicode |
| | | unicode.append("\\u" + Integer.toHexString(c)); |
| | | } |
| | | return unicode.toString(); |
| | | } |
| | | |
| | | /** |
| | | * unicode 转字符串 |
| | | * |
| | | * @param unicode |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static String unicode2String(String unicode) { |
| | | StringBuffer string = new StringBuffer(); |
| | | String[] hex = unicode.split("\\\\u"); |
| | | for (int i = 1; i < hex.length; i++) { |
| | | // 转换出每一个代码点 |
| | | int data = Integer.parseInt(hex[i], 16); |
| | | // 追加成string |
| | | string.append((char) data); |
| | | } |
| | | return string.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 字符串编码转换的实现方法 |
| | | * |
| | | * @param str |
| | | * 待转换编码的字符串 |
| | | * @param newCharset |
| | | * 目标编码 |
| | | * @return |
| | | * @throws UnsupportedEncodingException |
| | | */ |
| | | public static String changeCharset(String str, String newCharset) throws UnsupportedEncodingException { |
| | | if (str != null) { |
| | | // 用默认字符编码解码字符串。 |
| | | byte[] bs = str.getBytes(); |
| | | // 用新的字符编码生成字符串 |
| | | return new String(bs, newCharset); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 注: \n 回车( ) \t 水平制表符( ) \s 空格(\u0008) \r 换行( ) |
| | | * |
| | | * @param str |
| | | * @return |
| | | */ |
| | | public static String replaceBlank(String str) { |
| | | String dest = ""; |
| | | if (str != null) { |
| | | Pattern p = Pattern.compile("\\s*|\t|\r|\n"); |
| | | Matcher m = p.matcher(str); |
| | | dest = m.replaceAll(""); |
| | | } |
| | | return dest; |
| | | } |
| | | |
| | | /** |
| | | * 判断该字符串不能为空 |
| | | * |
| | | * @param str |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static boolean isNotEmpty(Object str) { |
| | | return !isEmpty(str); |
| | | } |
| | | |
| | | |
| | | public static boolean isNotEmptyUndefined(Object str) { |
| | | return !isEmpty(str) && !str.toString().equals("undefined"); |
| | | } |
| | | |
| | | /** |
| | | * 字符串编码转换的实现方法 |
| | | * |
| | | * @param str |
| | | * 待转换编码的字符串 |
| | | * @param oldCharset |
| | | * 原编码 |
| | | * @param newCharset |
| | | * 目标编码 |
| | | * @return |
| | | * @throws UnsupportedEncodingException |
| | | */ |
| | | public static String changeCharset(String str, String oldCharset, String newCharset) throws UnsupportedEncodingException { |
| | | if (str != null) { |
| | | // 用旧的字符编码解码字符串。解码可能会出现异常。 |
| | | byte[] bs = str.getBytes(oldCharset); |
| | | // 用新的字符编码生成字符串 |
| | | return new String(bs, newCharset); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 给手机号码加分割符 |
| | | * |
| | | * @param phone |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static String splitPhone(String phone) { |
| | | if (isNotEmpty(phone)) { |
| | | String strone = phone.substring(0, 3); |
| | | String strtwo = phone.substring(strone.length(), 7); |
| | | String strthree = phone.substring(strtwo.length() + strone.length(), phone.length()); |
| | | return strone + "-" + strtwo + "-" + strthree; |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | /** |
| | | * 非空判断 |
| | | * |
| | | * @param str |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static boolean isEmpty(Object str) { |
| | | return str == null || str.toString().length() == 0 || str.equals("") || str.toString().matches("\\s*"); |
| | | } |
| | | |
| | | /** |
| | | * 把米转换成公里 |
| | | * |
| | | * @param km |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static Double kmTransKilo(Integer m) { |
| | | return Math.round(m / 100d) / 10d; |
| | | } |
| | | |
| | | /** |
| | | * 将List<{@link Object}>转换成List<{@link T}> |
| | | * |
| | | * @param list |
| | | * 将要转换的对象 |
| | | * @param clazs |
| | | * 需要转换的泛型对象 |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> List<T> fromToObject(List<?> list, Class<T> clazs) { |
| | | List<T> t = new ArrayList<T>(); |
| | | for (Object object : list) { |
| | | t.add((T) object); |
| | | } |
| | | return t; |
| | | } |
| | | |
| | | /** |
| | | * 生成 uuid, 即用来标识一笔单,也用做 nonce_str |
| | | * @return |
| | | */ |
| | | public static String generateUUID() { |
| | | return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32); |
| | | } |
| | | |
| | | /** |
| | | * 将List<{@link Object}>转换成List<{@link Map<String, Object>}> |
| | | * |
| | | * @param list |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static List<Map<String, Object>> fromToObject_M(List<?> list) { |
| | | List<Map<String, Object>> t = new ArrayList<Map<String, Object>>(); |
| | | for (Object object : list) { |
| | | t.add((Map<String, Object>) object); |
| | | } |
| | | return t; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 将对象中的null转换为空 |
| | | * @param obj |
| | | * @return |
| | | * @throws IllegalAccessException |
| | | */ |
| | | |
| | | public static Object checkObjFieldIsNull(Object obj) throws IllegalAccessException { |
| | | if(obj!=null){ |
| | | for(java.lang.reflect.Field f : obj.getClass().getDeclaredFields()){ |
| | | f.setAccessible(true); |
| | | if(f.get(obj) == null){ |
| | | if(f.getType()==String.class){ |
| | | f.set(obj, ""); |
| | | } |
| | | if(f.getType()==Double.class){ |
| | | f.set(obj, 0d); |
| | | } |
| | | if(f.getType()==Integer.class){ |
| | | f.set(obj, 0); |
| | | } |
| | | if(f.getType()==Date.class){ |
| | | f.set(obj, new Date()); |
| | | } |
| | | } |
| | | } |
| | | return obj; |
| | | } |
| | | return obj; |
| | | } |
| | | /** |
| | | * 获取六位标识码 |
| | | * @param length |
| | | * @return |
| | | */ |
| | | public static String createRandomCharData() |
| | | { |
| | | StringBuilder sb=new StringBuilder(); |
| | | Random rand=new Random();//随机用以下三个随机生成器 |
| | | Random randdata=new Random(); |
| | | int data=0; |
| | | for(int i=0;i<6;i++) |
| | | { |
| | | int index=rand.nextInt(3); |
| | | //目的是随机选择生成数字,大小写字母 |
| | | switch(index) |
| | | { |
| | | case 0: |
| | | data=randdata.nextInt(10);//仅仅会生成0~9 |
| | | sb.append(data); |
| | | break; |
| | | case 1: |
| | | data=randdata.nextInt(26)+65;//保证只会产生65~90之间的整数 |
| | | sb.append((char)data); |
| | | break; |
| | | case 2: |
| | | data=randdata.nextInt(26)+97;//保证只会产生97~122之间的整数 |
| | | sb.append((char)data); |
| | | break; |
| | | } |
| | | } |
| | | String result=sb.toString().toLowerCase(); |
| | | return result; |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util; |
| | | |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component |
| | | public class SpringUtil implements ApplicationContextAware { |
| | | @Autowired |
| | | private static ApplicationContext applicationContext; |
| | | |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext applicationContextParam) throws BeansException { |
| | | applicationContext = applicationContextParam; |
| | | } |
| | | public static Object getObject(String id) { |
| | | Object object = null; |
| | | object = applicationContext.getBean(id); |
| | | return object; |
| | | } |
| | | public static <T> T getObject(Class<T> tClass) { |
| | | return applicationContext.getBean(tClass); |
| | | } |
| | | |
| | | public static Object getBean(String tClass) { |
| | | return applicationContext.getBean(tClass); |
| | | } |
| | | |
| | | public <T> T getBean(Class<T> tClass) { |
| | | return applicationContext.getBean(tClass); |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util; |
| | | |
| | | import org.apache.commons.lang.StringUtils; |
| | | |
| | | public class StringUtil { |
| | | |
| | | /** |
| | | * 判断字符串中是否包含表情 |
| | | * @param source |
| | | * @return |
| | | */ |
| | | public static boolean containsEmoji(String source) { |
| | | int len = 0; |
| | | if(null != source){ |
| | | len = source.length(); |
| | | } |
| | | boolean isEmoji = false; |
| | | for (int i = 0; i < len; i++) { |
| | | char hs = source.charAt(i); |
| | | if (0xd800 <= hs && hs <= 0xdbff) { |
| | | if (source.length() > 1) { |
| | | char ls = source.charAt(i + 1); |
| | | int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000; |
| | | if (0x1d000 <= uc && uc <= 0x1f77f) { |
| | | return true; |
| | | } |
| | | } |
| | | } else { |
| | | // non surrogate |
| | | if (0x2100 <= hs && hs <= 0x27ff && hs != 0x263b) { |
| | | return true; |
| | | } else if (0x2B05 <= hs && hs <= 0x2b07) { |
| | | return true; |
| | | } else if (0x2934 <= hs && hs <= 0x2935) { |
| | | return true; |
| | | } else if (0x3297 <= hs && hs <= 0x3299) { |
| | | return true; |
| | | } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d |
| | | || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c |
| | | || hs == 0x2b1b || hs == 0x2b50 || hs == 0x231a) { |
| | | return true; |
| | | } |
| | | if (!isEmoji && source.length() > 1 && i < source.length() - 1) { |
| | | char ls = source.charAt(i + 1); |
| | | if (ls == 0x20e3) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return isEmoji; |
| | | } |
| | | |
| | | /** |
| | | * 判断某个字符是不是表情 |
| | | * @param codePoint |
| | | * @return |
| | | */ |
| | | private static boolean isEmojiCharacter(char codePoint) { |
| | | return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) |
| | | || (codePoint == 0xD) |
| | | || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) |
| | | || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) |
| | | || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 过滤掉字符串中的表情 |
| | | * @param source |
| | | * @return |
| | | */ |
| | | public static String filterEmoji(String source) { |
| | | if (StringUtils.isBlank(source)) { |
| | | return source; |
| | | } |
| | | StringBuilder buf = null; |
| | | int len = source.length(); |
| | | for (int i = 0; i < len; i++) { |
| | | char codePoint = source.charAt(i); |
| | | if (isEmojiCharacter(codePoint)) { |
| | | if (buf == null) { |
| | | buf = new StringBuilder(source.length()); |
| | | } |
| | | buf.append(codePoint); |
| | | } |
| | | } |
| | | if (buf == null) { |
| | | return source; |
| | | } else { |
| | | if (buf.length() == len) { |
| | | buf = null; |
| | | return source; |
| | | } else { |
| | | return buf.toString(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断字符串为空 |
| | | * @param value |
| | | * @return |
| | | */ |
| | | public static boolean isEmpty(String value){ |
| | | if(null == value || value.trim().equals("")){ |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 判断字符串非空 |
| | | * @param value |
| | | * @return |
| | | */ |
| | | public static boolean isNotEmpty(String value){ |
| | | return !isEmpty(value); |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.applets; |
| | | |
| | | /** |
| | | * 缓存消息类型 |
| | | * |
| | | * @author TaoNingBo |
| | | * @data 2016年9月21日 |
| | | * @version 1.0 |
| | | */ |
| | | public class CacheType { |
| | | |
| | | /** |
| | | * 用户通讯通道标识 |
| | | */ |
| | | public static final String userCtx = "USER_CTX_"; |
| | | |
| | | /** |
| | | * 司机通讯通道标识 |
| | | */ |
| | | public static final String driverCtx = "DRIVER_CTX_"; |
| | | |
| | | /** |
| | | * 出行-快车/专车/代驾-订单消息队列-自营车辆 |
| | | */ |
| | | public static final String travelOrder1 = "TRAVEL_ORDER1_"; |
| | | |
| | | /** |
| | | * 出行-快车/专车/代驾-订单消息队列-外来车辆 |
| | | */ |
| | | public static final String travelOrder2 = "TRAVEL_ORDER2_"; |
| | | |
| | | /** |
| | | * 快车-司机位置-自营车辆 |
| | | */ |
| | | public static final String location1 = "_LOCATION1"; |
| | | |
| | | /** |
| | | * 快车-司机位置-外来车辆 |
| | | */ |
| | | public static final String location2 = "_LOCATION2"; |
| | | |
| | | /** |
| | | * 快车-司机抢单成功后的消息 |
| | | */ |
| | | public static final String travelOrder = "TRAVEL_ORDER_"; |
| | | |
| | | /** |
| | | * 开始服务时间 |
| | | */ |
| | | public static final String startServerT = "START_SERVER_TIME_"; |
| | | |
| | | /** |
| | | * 司机上一次的位置(经纬度) |
| | | */ |
| | | public static final String location = "LAST_DRIVER_LOCATION_"; |
| | | |
| | | /** |
| | | * 司机上一次总共行驶距离 |
| | | */ |
| | | public static final String triverd = "LAST_TRIVER_Distance_"; |
| | | |
| | | /** |
| | | * 记录订单数据 司机 异常处理 |
| | | */ |
| | | public static final String dreco = "DRIVER_DATA_RECO"; |
| | | |
| | | /** |
| | | * 记录订单数据 用户 异常处理 |
| | | */ |
| | | public static final String ureco = "USER_DATA_RECO"; |
| | | |
| | | /** |
| | | * 记录司机跟用户的关系ID |
| | | */ |
| | | public final static String udID = "USER_DRIVER_ID_"; |
| | | |
| | | /** |
| | | * 记录下单乘客的出发点位置坐标 |
| | | */ |
| | | public final static String userLoc = "USER_LOCATION_"; |
| | | |
| | | /** |
| | | * 记录计费规则【用订单号获取】 |
| | | */ |
| | | public final static String rules = "RULES_ORDER_"; |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.applets; |
| | | |
| | | import io.netty.channel.ChannelInitializer; |
| | | import io.netty.channel.socket.SocketChannel; |
| | | import io.netty.handler.codec.http.HttpObjectAggregator; |
| | | import io.netty.handler.codec.http.HttpServerCodec; |
| | | import io.netty.handler.ssl.SslHandler; |
| | | import io.netty.handler.stream.ChunkedWriteHandler; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.net.ssl.SSLEngine; |
| | | |
| | | public class ChildChannelHandler extends ChannelInitializer<SocketChannel> { |
| | | @Override |
| | | protected void initChannel(SocketChannel socketChannel) throws Exception { |
| | | // String path = "C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\cert\\SHA256withRSA_lzhyc.cn.pfx"; |
| | | // String path = "/usr/local/server/apache-tomcat-80/conf/cert/6064978_okyueche.com.pfx"; |
| | | // SSLContext sslContext = createSSLContext.createSSLContext("PKCS12" |
| | | // , path, "lio03Bb9"); |
| | | // //SSLEngine 此类允许使用ssl安全套接层协议进行安全通信 |
| | | // SSLEngine engine = sslContext.createSSLEngine(); |
| | | // engine.setUseClientMode(false); |
| | | // socketChannel.pipeline().addLast("ssl", new SslHandler(engine)); |
| | | |
| | | // 设置30秒没有读到数据,则触发一个READER_IDLE事件。 |
| | | // pipeline.addLast(new IdleStateHandler(30, 0, 0)); |
| | | // HttpServerCodec:将请求和应答消息解码为HTTP消息 |
| | | socketChannel.pipeline().addLast("http-codec", new HttpServerCodec()); |
| | | // HttpObjectAggregator:将HTTP消息的多个部分合成一条完整的HTTP消息 |
| | | socketChannel.pipeline().addLast("aggregator", new HttpObjectAggregator(65536)); |
| | | // ChunkedWriteHandler:向客户端发送HTML5文件 |
| | | socketChannel.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); |
| | | // 在管道中添加我们自己的接收数据实现方法 |
| | | socketChannel.pipeline().addLast("handler", new WebSocketHandler()); |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.applets; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 客户端心跳消息处理 |
| | | * |
| | | * @author TaoNingBo |
| | | * @data 2016年7月26日 |
| | | * @version 1.0 |
| | | */ |
| | | public class ClientPingMessage implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -4953410803742767757L; |
| | | |
| | | /** |
| | | * 客户端标识ID |
| | | */ |
| | | private Integer id; |
| | | |
| | | /** |
| | | * 角色【0:用户,1:司机】 |
| | | */ |
| | | private Integer role; |
| | | |
| | | /** |
| | | * 客户端单点登录标识TOKEN |
| | | */ |
| | | private String token; |
| | | |
| | | public ClientPingMessage() { |
| | | |
| | | } |
| | | |
| | | public Integer getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Integer id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public Integer getRole() { |
| | | return role; |
| | | } |
| | | |
| | | public void setRole(Integer role) { |
| | | this.role = role != null ? role : 0; |
| | | } |
| | | |
| | | public String getToken() { |
| | | return token; |
| | | } |
| | | |
| | | public void setToken(String token) { |
| | | this.token = token; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.applets; |
| | | |
| | | import io.netty.channel.group.ChannelGroup; |
| | | import io.netty.channel.group.DefaultChannelGroup; |
| | | import io.netty.util.concurrent.GlobalEventExecutor; |
| | | |
| | | public class Global { |
| | | public static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.applets; |
| | | |
| | | import io.netty.bootstrap.ServerBootstrap; |
| | | import io.netty.channel.Channel; |
| | | import io.netty.channel.EventLoopGroup; |
| | | import io.netty.channel.nio.NioEventLoopGroup; |
| | | import io.netty.channel.socket.nio.NioServerSocketChannel; |
| | | |
| | | import java.util.Timer; |
| | | import java.util.TimerTask; |
| | | |
| | | |
| | | /** |
| | | * 即时通讯服务启动类 |
| | | * |
| | | * @date 2016年6月25日 |
| | | * @version 1.0 |
| | | */ |
| | | public class NettyServer0 { |
| | | |
| | | /** |
| | | * 延迟启动设置 |
| | | * |
| | | * NettyServer启动方法. |
| | | */ |
| | | public void bind() { |
| | | final Thread thread = new Thread(new NettyRunnable()); |
| | | Timer timer = new Timer(); |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | thread.start(); |
| | | } |
| | | }, 1000 * 2); |
| | | } |
| | | |
| | | /** |
| | | * 即时通讯服务启动 |
| | | * |
| | | * @date 2016年6月24日 |
| | | * @version 1.0 |
| | | */ |
| | | public class NettyRunnable implements Runnable { |
| | | |
| | | /** |
| | | * 获取即时通讯启动端口 |
| | | */ |
| | | @Override |
| | | public void run() { |
| | | System.out.println("===========================Netty端口启动========"); |
| | | // Boss线程:由这个线程池提供的线程是boss种类的,用于创建、连接、绑定socket, |
| | | // (有点像门卫)然后把这些socket传给worker线程池。 |
| | | // 在服务器端每个监听的socket都有一个boss线程来处理。在客户端,只有一个boss线程来处理所有的socket。 |
| | | EventLoopGroup bossGroup = new NioEventLoopGroup(); |
| | | // Worker线程:Worker线程执行所有的异步I/O,即处理操作 |
| | | EventLoopGroup workrGroup = new NioEventLoopGroup(); |
| | | try { |
| | | |
| | | // ServerBootstrap 启动NIO服务的辅助启动类,负责初始话netty服务器,并且开始监听端口的socket请求 |
| | | ServerBootstrap b = new ServerBootstrap(); |
| | | b.group(bossGroup, workrGroup); |
| | | // 设置非阻塞,用它来建立新accept的连接,用于构造serversocketchannel的工厂类 |
| | | b.channel(NioServerSocketChannel.class); |
| | | // ChildChannelHandler 对出入的数据进行的业务操作,其继承ChannelInitializer |
| | | b.childHandler(new ChildChannelHandler()); |
| | | System.out.println("服务端开启等待客户端连接 ... ..."); |
| | | Channel ch = b.bind(9090).sync().channel(); |
| | | ch.closeFuture().sync(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | bossGroup.shutdownGracefully(); |
| | | workrGroup.shutdownGracefully(); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.applets; |
| | | |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.sinata.zuul.util.RedisUtil; |
| | | import com.sinata.zuul.util.SinataUtil; |
| | | import com.sinata.zuul.util.SpringUtil; |
| | | import com.sinata.zuul.util.StringUtil; |
| | | import com.sinata.zuul.util.echo.Method; |
| | | import com.sinata.zuul.util.echo.NettyChannelMap; |
| | | import com.sinata.zuul.util.echo.NettyMsg; |
| | | import io.netty.buffer.ByteBuf; |
| | | import io.netty.buffer.Unpooled; |
| | | import io.netty.channel.ChannelFuture; |
| | | import io.netty.channel.ChannelHandlerContext; |
| | | import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Hashtable; |
| | | import java.util.Timer; |
| | | import java.util.TimerTask; |
| | | |
| | | public class NettyWebSocketController { |
| | | |
| | | public static Hashtable<String, Hashtable<ChannelHandlerContext, String>> map = new Hashtable<String, Hashtable<ChannelHandlerContext, String>>(); |
| | | |
| | | private RedisUtil redisUtil = SpringUtil.getObject(RedisUtil.class); |
| | | |
| | | public static Hashtable<String, String> table; |
| | | |
| | | static { |
| | | if (table == null) { |
| | | table = new Hashtable<>(); |
| | | } |
| | | } |
| | | |
| | | public static boolean isdebug = false; |
| | | public static int i = 0; |
| | | |
| | | |
| | | /** |
| | | * 判断客户端要执行什么操作 |
| | | * |
| | | * @param ctx |
| | | * @param msg |
| | | * @author TaoNingBo |
| | | */ |
| | | public void JudgeOperation(ChannelHandlerContext ctx, String msg) { |
| | | try { |
| | | // 验证即时通讯命令是否正确有效 |
| | | if (SinataUtil.isEmpty(msg)) { |
| | | return; |
| | | } |
| | | String msgStr = msg.toString(); |
| | | if (msgStr.indexOf("{") == -1 || msgStr.indexOf("}") == -1 || msgStr.indexOf("code") == -1 || msgStr.indexOf("msg") == -1 || msgStr.indexOf("data") == -1 || msgStr.indexOf("method") == -1) { |
| | | return; |
| | | } |
| | | if (isdebug) { |
| | | // System.out.println("<<<--receive-->>>111" + msg); |
| | | } |
| | | |
| | | // 获取socket信息,保存相应的socket |
| | | JSONObject jsonMsg = JSONObject.parseObject(msg.toString()); |
| | | int code = jsonMsg.getIntValue("code"); |
| | | String message = jsonMsg.getString("msg"); |
| | | String method = jsonMsg.getString("method"); |
| | | if (code != 200 || !message.equals("SUCCESS")) { |
| | | return; |
| | | } |
| | | JSONObject jsonCon = JSONObject.parseObject(jsonMsg.get("data").toString()); |
| | | |
| | | if (null != ctx && ctx.channel().isActive()) { |
| | | jsonMsg.put("method", Method.pong); |
| | | sendMsgToClient(ctx, jsonMsg.toJSONString()); |
| | | } |
| | | |
| | | |
| | | // ############################### 心跳 ############################ |
| | | // 心跳 |
| | | if (method.equals(Method.ping)) { |
| | | String token = jsonCon.getString("token"); |
| | | String userId1 = jsonCon.getString("userId"); |
| | | if (StringUtil.isNotEmpty(userId1)) { |
| | | //确保账号在单个设备上登录 |
| | | if (StringUtil.isNotEmpty(token)) { |
| | | String token_ = redisUtil.getValue("USER_Applets_" + userId1);//获取缓存中最新的数据 |
| | | if (StringUtil.isNotEmpty(token_) && !token.equals(token_)) {//不在同一设备上登录,向其他设备发送数据 |
| | | ChannelHandlerContext data_ = NettyChannelMap.getData_(token_.substring(0, 23)); |
| | | |
| | | JSONObject msg_ = new JSONObject(); |
| | | msg_.put("code", 200); |
| | | msg_.put("msg", "SUCCESS"); |
| | | msg_.put("method", "OFFLINE"); |
| | | msg_.put("data", new Object()); |
| | | this.sendMsgToClient(data_, msg_.toJSONString());//给当前通道发送消息 |
| | | TimerTask timerTask = new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | NettyChannelMap.remove_(data_); |
| | | NettyChannelMap.remove(data_); |
| | | } |
| | | }; |
| | | Timer timer = new Timer(); |
| | | timer.schedule(timerTask, 3000); |
| | | timer.cancel(); |
| | | } |
| | | |
| | | NettyChannelMap.update_(token.substring(0, 23), ctx); |
| | | NettyChannelMap.update("Applets" + userId1, ctx); |
| | | String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); |
| | | ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); |
| | | |
| | | if (StringUtil.isEmpty(token_)) {//确保登录的时候存储token失败的情况 |
| | | redisUtil.setStrValue("USER_Applets_" + userId1, token); |
| | | } |
| | | } |
| | | |
| | | //存储业务使用的通道 |
| | | if (null != ctx && ctx.channel().isActive()) { |
| | | NettyChannelMap.update("Applets" + userId1, ctx); |
| | | // String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); |
| | | // ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | } catch (Exception e) { |
| | | if (isdebug) { |
| | | NettyWebSocketController.sendMsgToClient(ctx, "__error__" + msg.toString()); |
| | | } |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 向客户端发送消息 |
| | | * |
| | | * @param ctx |
| | | * @param msg |
| | | * @author TaoNingBo |
| | | */ |
| | | public static void sendMsgToClient(ChannelHandlerContext ctx, String msg) { |
| | | // System.out.println(ctx.channel().isActive()); |
| | | if (ctx != null && ctx.channel().isActive()) { |
| | | ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes()); |
| | | ChannelFuture sync; |
| | | try { |
| | | sync = ctx.channel().writeAndFlush(new TextWebSocketFrame(msg)).sync(); |
| | | if (!sync.isSuccess()) { |
| | | boolean b = true; |
| | | for (int i = 0; i < 10; i++) { |
| | | ctx.wait(3000); |
| | | sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync(); |
| | | if (sync.isSuccess()) { |
| | | b = false; |
| | | break; |
| | | } |
| | | System.err.println("小程序-》推送不成功,将继续推送" + msg); |
| | | } |
| | | if (b) { |
| | | NettyChannelMap.remove(ctx); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | System.err.println("小程序-》推送发生异常,记录:" + msg); |
| | | NettyChannelMap.remove(ctx); |
| | | } |
| | | if (isdebug) { |
| | | System.err.println("小程序-》 <<<--send-->>>" + msg); |
| | | } |
| | | } else { |
| | | System.err.println("小程序-》推送失败,长连接不存在"); |
| | | NettyChannelMap.remove(ctx); |
| | | } |
| | | } |
| | | |
| | | // **链接断开 将推送消息记录 |
| | | public static void sendMsgToClient(String cacheType, Integer id, String msg) { |
| | | ChannelHandlerContext ctx = NettyChannelMap.getData(cacheType + id); |
| | | if (ctx != null) { |
| | | ChannelFuture sync; |
| | | try { |
| | | sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync(); |
| | | if (!sync.isSuccess()) { |
| | | for (int i = 0; i < 10; i++) { |
| | | sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync(); |
| | | ; |
| | | if (!sync.isSuccess()) { |
| | | sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync(); |
| | | ; |
| | | System.err.println("推送不成功,将继续推送" + msg); |
| | | if (i == 9) { |
| | | table.put(cacheType + id, msg); |
| | | ctx.close(); |
| | | System.err.println("推送发生异常,记录:" + msg); |
| | | } |
| | | } else { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | table.put(cacheType + id, msg); |
| | | System.err.println("推送发生异常,记录:" + msg); |
| | | } |
| | | if (isdebug) { |
| | | System.err.println("<<<--send-->>>" + msg); |
| | | } |
| | | } else { |
| | | table.put(cacheType + id, msg); |
| | | System.err.println("链接断开,记录:id=" + cacheType + id + ",消息:" + msg); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.applets; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.sinata.zuul.util.echo.Method; |
| | | import com.sinata.zuul.util.echo.NettyChannelMap; |
| | | import com.sinata.zuul.util.echo.NettyMsg; |
| | | import io.netty.buffer.ByteBuf; |
| | | import io.netty.buffer.Unpooled; |
| | | import io.netty.channel.ChannelFuture; |
| | | import io.netty.channel.ChannelFutureListener; |
| | | import io.netty.channel.ChannelHandlerContext; |
| | | import io.netty.channel.SimpleChannelInboundHandler; |
| | | import io.netty.handler.codec.http.*; |
| | | import io.netty.handler.codec.http.websocketx.*; |
| | | import io.netty.handler.timeout.IdleState; |
| | | import io.netty.handler.timeout.IdleStateEvent; |
| | | import io.netty.util.CharsetUtil; |
| | | |
| | | import java.util.HashMap; |
| | | |
| | | |
| | | public class WebSocketHandler extends SimpleChannelInboundHandler<Object> { |
| | | //用于websocket握手的处理类 |
| | | private WebSocketServerHandshaker handshaker; |
| | | |
| | | private static final String WEB_SOCKET_URL = "wss://localhost:9090/websocket"; |
| | | |
| | | |
| | | |
| | | // @Override |
| | | // protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { |
| | | // if (msg instanceof FullHttpRequest) { |
| | | // // websocket连接请求 |
| | | // handleHttpRequest(ctx, (FullHttpRequest)msg); |
| | | // } else if (msg instanceof WebSocketFrame) { |
| | | // // websocket业务处理 |
| | | // handleWebSocketRequest(ctx, (WebSocketFrame)msg); |
| | | // } |
| | | // } |
| | | |
| | | @Override |
| | | public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { |
| | | ctx.flush(); |
| | | } |
| | | |
| | | /** 心跳 */ |
| | | @Override |
| | | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { |
| | | if (evt instanceof IdleStateEvent) { |
| | | IdleStateEvent event = (IdleStateEvent) evt; |
| | | if (event.state().equals(IdleState.READER_IDLE)) |
| | | { |
| | | // |
| | | } |
| | | else if (event.state().equals(IdleState.WRITER_IDLE)) |
| | | { |
| | | // |
| | | } |
| | | else if (event.state().equals(IdleState.ALL_IDLE)) |
| | | { |
| | | String msg = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); |
| | | if(ctx != null && ctx.channel().isActive()) { |
| | | ctx.writeAndFlush(Unpooled.copiedBuffer((msg).getBytes())); |
| | | } |
| | | } |
| | | } |
| | | // super.userEventTriggered(ctx, evt); |
| | | } |
| | | |
| | | @Override |
| | | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { |
| | | ctx.close(); |
| | | } |
| | | |
| | | private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { |
| | | // Http解码失败,向服务器指定传输的协议为Upgrade:websocket |
| | | if(!req.getDecoderResult().isSuccess() || !("websocket").equals(req.headers().get("Upgrade"))){ |
| | | sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST)); |
| | | return; |
| | | } |
| | | // 握手相应处理,创建websocket握手的工厂类, |
| | | WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(WEB_SOCKET_URL, null, false); |
| | | // 根据工厂类和HTTP请求创建握手类 |
| | | handshaker = wsFactory.newHandshaker(req); |
| | | if (handshaker == null) { |
| | | // 不支持websocket |
| | | WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel()); |
| | | } else { |
| | | // 通过它构造握手响应消息返回给客户端 |
| | | handshaker.handshake(ctx.channel(), req); |
| | | } |
| | | } |
| | | |
| | | private void handleWebSocketRequest(ChannelHandlerContext ctx, WebSocketFrame req) throws Exception { |
| | | if (req instanceof CloseWebSocketFrame) { |
| | | // 关闭websocket连接 |
| | | handshaker.close(ctx.channel(), (CloseWebSocketFrame)req.retain()); |
| | | return; |
| | | } |
| | | if (req instanceof PingWebSocketFrame) { |
| | | ctx.channel().write(new PongWebSocketFrame(req.content().retain())); |
| | | return; |
| | | } |
| | | if (!(req instanceof TextWebSocketFrame)) { |
| | | throw new UnsupportedOperationException("当前只支持文本消息,不支持二进制消息"); |
| | | } |
| | | if (ctx == null || this.handshaker == null || ctx.isRemoved()) { |
| | | throw new Exception("尚未握手成功,无法向客户端发送WebSocket消息"); |
| | | } |
| | | String requestmsg = ((TextWebSocketFrame) req).text(); |
| | | |
| | | |
| | | //给连接的客户端返回数据 |
| | | //返回心跳 |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("code", 200); |
| | | jsonObject.put("method", Method.ok); |
| | | jsonObject.put("msg", "SUCCESS"); |
| | | jsonObject.put("data", new JSONObject()); |
| | | TextWebSocketFrame tws = new TextWebSocketFrame(jsonObject.toJSONString()); |
| | | // ctx.channel().writeAndFlush(tws); |
| | | |
| | | new NettyWebSocketController().JudgeOperation(ctx,requestmsg);//小程序心跳处理 |
| | | |
| | | // 群发服务端心跳响应 |
| | | Global.group.writeAndFlush(new TextWebSocketFrame((tws).text())); |
| | | } |
| | | |
| | | private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) { |
| | | // BAD_REQUEST(400) 客户端请求错误返回的应答消息 |
| | | if(res.getStatus().code() != 200){ |
| | | ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8); |
| | | res.content().writeBytes(buf); |
| | | buf.release(); |
| | | } |
| | | //服务端向客户端发送数据 |
| | | ChannelFuture f = ctx.channel().writeAndFlush(res); |
| | | // 非法连接直接关闭连接 |
| | | if(res.getStatus().code() != 200){ |
| | | f.addListener(ChannelFutureListener.CLOSE); |
| | | } |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void channelActive(ChannelHandlerContext ctx) throws Exception { |
| | | Global.group.add(ctx.channel()); |
| | | System.err.println("客户端与服务器端开启"); |
| | | } |
| | | |
| | | @Override |
| | | public void channelInactive(ChannelHandlerContext ctx) throws Exception { |
| | | Global.group.remove(ctx.channel()); |
| | | NettyChannelMap.remove(ctx); |
| | | System.err.println("客户端与服务器链接关闭"); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { |
| | | if (msg instanceof FullHttpRequest) { |
| | | // websocket连接请求 |
| | | handleHttpRequest(ctx, (FullHttpRequest)msg); |
| | | } else if (msg instanceof WebSocketFrame) { |
| | | // websocket业务处理 |
| | | handleWebSocketRequest(ctx, (WebSocketFrame)msg); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { |
| | | if (msg instanceof FullHttpRequest) { |
| | | // websocket连接请求 |
| | | handleHttpRequest(ctx, (FullHttpRequest)msg); |
| | | } else if (msg instanceof WebSocketFrame) { |
| | | // websocket业务处理 |
| | | handleWebSocketRequest(ctx, (WebSocketFrame)msg); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.applets; |
| | | |
| | | import javax.net.ssl.KeyManagerFactory; |
| | | import javax.net.ssl.SSLContext; |
| | | import java.io.FileInputStream; |
| | | import java.io.InputStream; |
| | | import java.security.KeyStore; |
| | | |
| | | public class createSSLContext { |
| | | |
| | | /** |
| | | * 获取SSLContext |
| | | * @param type |
| | | * @param path |
| | | * @param password |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static SSLContext createSSLContext(String type , String path , String password) throws Exception { |
| | | KeyStore ks = KeyStore.getInstance(type); /// "JKS" |
| | | InputStream ksInputStream = new FileInputStream(path); /// 证书存放地址 |
| | | ks.load(ksInputStream, password.toCharArray()); |
| | | //KeyManagerFactory充当基于密钥内容源的密钥管理器的工厂。 |
| | | KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());//getDefaultAlgorithm:获取默认的 KeyManagerFactory 算法名称。 |
| | | kmf.init(ks, password.toCharArray()); |
| | | //SSLContext的实例表示安全套接字协议的实现,它充当用于安全套接字工厂或 SSLEngine 的工厂。 |
| | | SSLContext sslContext = SSLContext.getInstance("TLS"); |
| | | sslContext.init(kmf.getKeyManagers(), null, null); |
| | | return sslContext; |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.echo; |
| | | |
| | | import io.netty.buffer.Unpooled; |
| | | import io.netty.channel.ChannelHandlerContext; |
| | | import io.netty.channel.ChannelPromise; |
| | | import io.netty.channel.SimpleChannelInboundHandler; |
| | | import io.netty.handler.timeout.IdleState; |
| | | import io.netty.handler.timeout.IdleStateEvent; |
| | | import io.netty.util.ReferenceCountUtil; |
| | | |
| | | import java.net.InetSocketAddress; |
| | | import java.util.HashMap; |
| | | |
| | | public class DiscardServerHandler extends SimpleChannelInboundHandler<String> { |
| | | |
| | | private NettyServerController nettyServerController = new NettyServerController(); |
| | | |
| | | public static boolean isdebug = true; |
| | | |
| | | @Override |
| | | public void channelRead(ChannelHandlerContext ctx, Object msg) { |
| | | InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); |
| | | if(isdebug) { |
| | | // System.err.println(insocket.getAddress() + ": 收到客户端数据......."); |
| | | } |
| | | try { |
| | | // 调用service |
| | | nettyServerController.JudgeOperation(ctx, msg); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | ReferenceCountUtil.release(msg); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { |
| | | InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); |
| | | if(isdebug) { |
| | | // System.err.println(insocket.getAddress() + ": 收到客户端数据......."); |
| | | } |
| | | try { |
| | | // 调用service |
| | | nettyServerController.JudgeOperation(ctx, msg); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | ReferenceCountUtil.release(msg); |
| | | } |
| | | } |
| | | |
| | | // @Override |
| | | // protected void messageReceived(ChannelHandlerContext channelHandlerContext, String s) throws Exception { |
| | | // |
| | | // } |
| | | |
| | | // @Override |
| | | // protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception { |
| | | // |
| | | // } |
| | | |
| | | // @Override |
| | | // protected void messageReceived(ChannelHandlerContext channelHandlerContext, String s) throws Exception { |
| | | // |
| | | // } |
| | | |
| | | /** 在连接被建立并且准备进行通信时被调用 */ |
| | | public void channelActive(final ChannelHandlerContext ctx) throws Exception { |
| | | InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); |
| | | if(isdebug) { |
| | | // System.err.println(insocket.getAddress() + ": Connect successful......"); |
| | | } |
| | | } |
| | | |
| | | /** 心跳 */ |
| | | @Override |
| | | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { |
| | | if (evt instanceof IdleStateEvent) { |
| | | IdleStateEvent event = (IdleStateEvent) evt; |
| | | if (event.state().equals(IdleState.READER_IDLE)) |
| | | { |
| | | // |
| | | } |
| | | else if (event.state().equals(IdleState.WRITER_IDLE)) |
| | | { |
| | | // |
| | | } |
| | | else if (event.state().equals(IdleState.ALL_IDLE)) |
| | | { |
| | | String msg = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); |
| | | if(ctx != null && ctx.channel().isActive()) { |
| | | ctx.writeAndFlush(Unpooled.copiedBuffer((msg).getBytes())); |
| | | // System.err.println(msg); |
| | | } |
| | | } |
| | | } |
| | | //super.userEventTriggered(ctx, evt); |
| | | } |
| | | |
| | | /** 连接处于不活跃时调用(连接关闭) **/ |
| | | public void channelInactive(ChannelHandlerContext ctx) throws Exception { |
| | | if(isdebug) { |
| | | InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); |
| | | // System.err.println(insocket.getAddress() + ": Disconnect connection......"); |
| | | } |
| | | NettyChannelMap.remove(ctx); |
| | | // System.err.println("清除通道" + ctx); |
| | | // super.channelInactive(ctx); |
| | | } |
| | | |
| | | public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { |
| | | ctx.flush(); |
| | | } |
| | | |
| | | /** 处理方法是当出现Throwable对象才会被调用 **/ |
| | | public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception { |
| | | ctx.close(); |
| | | } |
| | | |
| | | public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { |
| | | if(isdebug) { |
| | | InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); |
| | | // System.err.println("close......." + insocket.getAddress()); |
| | | } |
| | | ctx.close(promise); |
| | | } |
| | | |
| | | public void read(ChannelHandlerContext ctx) throws Exception { |
| | | ctx.read(); |
| | | } |
| | | |
| | | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { |
| | | ctx.write(msg, promise); |
| | | } |
| | | |
| | | // @Override |
| | | // protected void channelRead(ChannelHandlerContext ctx, String msg) throws Exception { |
| | | // // TODO Auto-generated method stub |
| | | // InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); |
| | | // if(isdebug) { |
| | | // System.out.println(insocket.getAddress() + ": 收到客户端数据......."); |
| | | // } |
| | | // try { |
| | | // // 调用service |
| | | // nettyServerController.JudgeOperation(ctx, msg); |
| | | // } catch (Exception e) { |
| | | // e.printStackTrace(); |
| | | // } finally { |
| | | // ReferenceCountUtil.release(msg); |
| | | // } |
| | | // } |
| | | |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.echo; |
| | | |
| | | /** |
| | | * 即时通讯【通讯类型类】 |
| | | * |
| | | * @author TaoNingBo |
| | | * @createDate 2016年6月14日 |
| | | * @version 1.0 |
| | | */ |
| | | public class Method { |
| | | |
| | | /** 心跳【推送】 */ |
| | | public static final String ok = "OK"; |
| | | |
| | | /** 心跳【接收】 */ |
| | | public final static String ping = "PING"; |
| | | |
| | | /** 心跳【响应】 */ |
| | | public final static String pong = "PONG"; |
| | | |
| | | /** 司机上传位置 */ |
| | | public static final String location = "LOCATION"; |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.echo; |
| | | |
| | | import io.netty.channel.ChannelHandlerContext; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | public class NettyChannelMap { |
| | | |
| | | protected static Map<String, ChannelHandlerContext> map = new ConcurrentHashMap<>(); |
| | | |
| | | public static Map<String, ChannelHandlerContext> ctxMap = new HashMap<>();//单点登录存储的通道 |
| | | |
| | | |
| | | private NettyChannelMap() { |
| | | // 放置外部实例化 |
| | | } |
| | | |
| | | /** |
| | | * Get data from source. |
| | | * |
| | | * @param key |
| | | * @return |
| | | */ |
| | | public static ChannelHandlerContext getData(String key) { |
| | | if(map==null){ |
| | | map = new HashMap<String, ChannelHandlerContext>(); |
| | | } |
| | | return map.get(key); |
| | | } |
| | | |
| | | |
| | | public static ChannelHandlerContext getData_(String key) { |
| | | if(ctxMap==null){ |
| | | ctxMap = new HashMap<String, ChannelHandlerContext>(); |
| | | } |
| | | return ctxMap.get(key); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Save data from source. |
| | | * |
| | | * @param key |
| | | * @param val |
| | | */ |
| | | public static synchronized void saveData(String key, ChannelHandlerContext val) { |
| | | map.put(key, val); |
| | | } |
| | | |
| | | /** |
| | | * Determine whether the cache key contains the key. |
| | | * |
| | | * @param key |
| | | * @return true|false |
| | | * @author TaoNingBo |
| | | */ |
| | | public static synchronized boolean containsKey(String key) { |
| | | return map.containsKey(key); |
| | | } |
| | | |
| | | /** |
| | | * Determine whether the cache value contains the value. |
| | | * |
| | | * @param val |
| | | * @return |
| | | */ |
| | | public static synchronized boolean containsVal(ChannelHandlerContext val) { |
| | | return map.containsValue(val); |
| | | } |
| | | |
| | | /** |
| | | * Remove the data resources. |
| | | * |
| | | * @param value |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public static synchronized void remove(ChannelHandlerContext value) { |
| | | Set<String> strings = map.keySet(); |
| | | for(String key : strings){ |
| | | ChannelHandlerContext channelHandlerContext = map.get(key); |
| | | String s = channelHandlerContext.channel().remoteAddress().toString(); |
| | | String s1 = value.channel().remoteAddress().toString(); |
| | | if(s.equals(s1)){ |
| | | channelHandlerContext.close();//关闭通道 |
| | | map.remove(key); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | public static synchronized void remove_(ChannelHandlerContext value) { |
| | | Set<String> strings = ctxMap.keySet(); |
| | | for(String key : strings){ |
| | | ChannelHandlerContext channelHandlerContext = ctxMap.get(key); |
| | | String s = channelHandlerContext.channel().remoteAddress().toString(); |
| | | String s1 = value.channel().remoteAddress().toString(); |
| | | if(s.equals(s1)){ |
| | | channelHandlerContext.close();//关闭通道 |
| | | ctxMap.remove(key); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Remove the data resources. |
| | | * |
| | | * @param key |
| | | * @author TaoNingBo |
| | | */ |
| | | public static synchronized void remove(String key) { |
| | | map.remove(key); |
| | | } |
| | | |
| | | /** |
| | | * Update the data resources. |
| | | * |
| | | * @param key |
| | | * @param value |
| | | */ |
| | | public static synchronized void update(String key, ChannelHandlerContext value) { |
| | | map.put(key, value); |
| | | } |
| | | |
| | | |
| | | |
| | | public static synchronized void update_(String key, ChannelHandlerContext value) { |
| | | ctxMap.put(key, value); |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.echo; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import io.netty.buffer.ByteBuf; |
| | | import io.netty.buffer.Unpooled; |
| | | import io.netty.channel.ChannelFuture; |
| | | import io.netty.channel.ChannelHandlerContext; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | |
| | | public class NettyMsg { |
| | | public static void main(String[] args) { |
| | | Map<String,Object> map = new HashMap<String, Object>(); |
| | | //用户信息 |
| | | map.put("imgUrl","1"); |
| | | map.put("nickName","1"); |
| | | map.put("licensePlate","1"); |
| | | map.put("phone",1); |
| | | map.put("driverId",1); |
| | | map.put("carColor","1"); |
| | | map.put("modelName","1"); |
| | | map.put("brandName","1"); |
| | | map.put("driverOrderNums",1); |
| | | map.put("score",1); |
| | | |
| | | |
| | | map.put("id",1); |
| | | map.put("orderNum", "123456"); |
| | | map.put("startAddress", "测试"); |
| | | map.put("endAddress", "测试1"); |
| | | map.put("departureTime", 1533608196000L); |
| | | map.put("type",1); |
| | | map.put("mileage",1); |
| | | map.put("mileageMoney",10); |
| | | map.put("duration",10); |
| | | map.put("durationMoney",10); |
| | | map.put("nightMoney",1); |
| | | map.put("serverMoney",1); |
| | | map.put("nightMileage",10); |
| | | map.put("longMileage",10); |
| | | map.put("longDurationMoney",10); |
| | | map.put("orderMoney",10); |
| | | map.put("payMoney",10); |
| | | map.put("couponsMoney",10); |
| | | System.out.println(setMsg(Method.ping, new HashMap<String, Object>())); |
| | | } |
| | | |
| | | /** |
| | | * 返回一个正确数据 |
| | | * |
| | | * @param method |
| | | * @param data |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static String setMsg(String method, Map<String, Object> data) { |
| | | StringBuffer json = new StringBuffer(); |
| | | json.append(getHeader(200, "SUCCESS", method)); |
| | | json.append(JSON.toJSONString(data)); |
| | | json.append("}"); |
| | | //return JSON.toJSONString(json); |
| | | return json.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 返回一个正确数据 |
| | | * |
| | | * @param method |
| | | * @param data |
| | | * @return |
| | | */ |
| | | public static String setMsg(String method, List<Map<String, Object>> data) { |
| | | StringBuffer json = new StringBuffer(); |
| | | json.append(getHeader(200, "SUCCESS", method)); |
| | | List<JSONObject> jsonList = new ArrayList<JSONObject>(); |
| | | for(Map<String, Object> map : data) { |
| | | JSONObject dataJson = new JSONObject(map); |
| | | jsonList.add(dataJson); |
| | | } |
| | | json.append(jsonList); |
| | | json.append("}"); |
| | | |
| | | // return JSON.toJSONString(json); |
| | | return json.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 返回一个错误数据 |
| | | * |
| | | * @param method |
| | | * @param data |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | public static String setErrMsg(String method, String data) { |
| | | StringBuffer json = new StringBuffer(); |
| | | json.append(getHeader(-1, "FAILURE", method)); |
| | | json.append("\"" + data + "\""); |
| | | json.append("}"); |
| | | // return JSON.toJSONString(json); |
| | | return json.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 生成一个返回JSON的头 |
| | | * |
| | | * @param code |
| | | * @param msg |
| | | * @param method |
| | | * @return |
| | | * @author TaoNingBo |
| | | */ |
| | | private static String getHeader(int code, String msg, String method) { |
| | | StringBuffer header = new StringBuffer(); |
| | | header.append("{"); |
| | | header.append("\"code\":\"" + code); |
| | | header.append("\",\"msg\":\"" + msg); |
| | | header.append("\",\"method\":\"" + method); |
| | | header.append("\",\"data\":"); |
| | | return header.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 发送消息给客户端 |
| | | * |
| | | * @param cacheType |
| | | * @param id |
| | | * @param method |
| | | * @param data |
| | | * @author TaoNingBo |
| | | */ |
| | | public static void sendMsg(String cacheType, Integer id, String method, Map<String, Object> data) { |
| | | //NettyServerController.sendMsgToClient(NettyChannelMap.getData(cacheType + id), setMsg(method, data)); |
| | | NettyServerController.sendMsgToClient(cacheType,id, setMsg(method, data)); |
| | | } |
| | | |
| | | |
| | | public static void resendMsg(String token){ |
| | | String msg = NettyServerController.table.get(token); |
| | | ChannelHandlerContext ctx = NettyChannelMap.getData(token); |
| | | if(null != msg && !"".equals(msg) && ctx != null && ctx.channel().isActive()){ |
| | | ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes()); |
| | | ChannelFuture sync; |
| | | try { |
| | | sync = ctx.writeAndFlush(buffer).sync(); |
| | | System.err.println("重发异常推送状态"+sync.isSuccess()+",位置:"+token+",消息内容:"+msg); |
| | | if(!sync.isSuccess()){ |
| | | resendMsg(token); |
| | | System.err.println("重发异常推送不成功,将继续推送"+msg); |
| | | } |
| | | NettyServerController.table.remove(token); |
| | | } catch (Exception e) { |
| | | resendMsg(token); |
| | | System.err.println("重发推送发生异常,记录:"+msg); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.echo; |
| | | |
| | | import io.netty.bootstrap.ServerBootstrap; |
| | | import io.netty.channel.ChannelFuture; |
| | | import io.netty.channel.ChannelOption; |
| | | import io.netty.channel.ChannelPipeline; |
| | | import io.netty.channel.EventLoopGroup; |
| | | import io.netty.channel.nio.NioEventLoopGroup; |
| | | import io.netty.channel.socket.SocketChannel; |
| | | import io.netty.channel.socket.nio.NioServerSocketChannel; |
| | | import io.netty.handler.codec.LengthFieldBasedFrameDecoder; |
| | | import io.netty.handler.codec.LengthFieldPrepender; |
| | | import io.netty.handler.timeout.IdleStateHandler; |
| | | |
| | | import java.util.Timer; |
| | | import java.util.TimerTask; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * 即时通讯服务启动类 |
| | | * |
| | | * @date 2016年6月25日 |
| | | * @version 1.0 |
| | | */ |
| | | public class NettyServer { |
| | | |
| | | |
| | | /** |
| | | * NettyServer启动方法. |
| | | */ |
| | | public void bind() { |
| | | final Thread thread = new Thread(new NettyRunnable()); |
| | | Timer timer = new Timer(); |
| | | timer.schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | thread.start(); |
| | | } |
| | | }, 10000); |
| | | } |
| | | |
| | | /** |
| | | * 即时通讯服务启动 |
| | | * |
| | | * @date 2016年6月24日 |
| | | * @version 1.0 |
| | | */ |
| | | public class NettyRunnable implements Runnable { |
| | | |
| | | /** |
| | | * 获取即时通讯启动端口 |
| | | */ |
| | | private Integer nettyPort = 8888; |
| | | @Override |
| | | public void run() { |
| | | EventLoopGroup bossGroup = new NioEventLoopGroup(); |
| | | EventLoopGroup workerGroup = new NioEventLoopGroup(); |
| | | try { |
| | | ServerBootstrap bootstrap = new ServerBootstrap(); |
| | | bootstrap.group(bossGroup, workerGroup); |
| | | bootstrap.channel(NioServerSocketChannel.class); |
| | | bootstrap.option(ChannelOption.SO_BACKLOG, 1024); |
| | | // 通过TCP_NODELAY禁用NAGLE,使消息立即发出去,不用等待到一定的数据量才发出去 |
| | | bootstrap.option(ChannelOption.TCP_NODELAY, true); |
| | | // 保持长连接状态 |
| | | bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); |
| | | bootstrap.childHandler(new ServerInit() { |
| | | @Override |
| | | protected void initChannel(SocketChannel socketChannel) throws Exception { |
| | | ChannelPipeline pipeline = socketChannel.pipeline(); |
| | | pipeline.addLast("ping", new IdleStateHandler(120, 60, 5, TimeUnit.SECONDS)); |
| | | pipeline.addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); |
| | | pipeline.addLast("encoder", new LengthFieldPrepender(4)); |
| | | //pipeline.addLast(new LineBasedFrameDecoder(1048576 * 10)); |
| | | //pipeline.addLast(new StringDecoder(Charset.forName("UTF-8"))); |
| | | //pipeline.addLast(new StringEncoder(Charset.forName("UTF-8"))); |
| | | pipeline.addLast(new DiscardServerHandler()); |
| | | } |
| | | }); |
| | | // 服务器绑定端口监听 |
| | | ChannelFuture f = bootstrap.bind(nettyPort).sync(); |
| | | if(f.isSuccess()) { |
| | | System.out.println("******************************Netty启动成功******************************"); |
| | | } |
| | | // 监听服务器关闭监听 |
| | | f.channel().closeFuture().sync(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | bossGroup.shutdownGracefully(); |
| | | workerGroup.shutdownGracefully(); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.echo; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.sinata.zuul.util.*; |
| | | import io.netty.buffer.ByteBuf; |
| | | import io.netty.buffer.Unpooled; |
| | | import io.netty.channel.ChannelFuture; |
| | | import io.netty.channel.ChannelHandlerContext; |
| | | import org.springframework.http.HttpEntity; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.util.LinkedMultiValueMap; |
| | | import org.springframework.util.MultiValueMap; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.util.*; |
| | | |
| | | |
| | | /** |
| | | * Netty业务逻辑层 |
| | | * @author sinata |
| | | * @createDate 2016年6月3日 |
| | | * @version 1.0 |
| | | */ |
| | | public class NettyServerController { |
| | | |
| | | public static Hashtable<String, Hashtable<ChannelHandlerContext, String>> map = new Hashtable<String, Hashtable<ChannelHandlerContext,String>>(); |
| | | |
| | | public static Hashtable<String,String> table; |
| | | |
| | | private RedisUtil redisUtil = SpringUtil.getObject(RedisUtil.class); |
| | | |
| | | private GDMapGeocodingUtil gdMapGeocodingUtil = SpringUtil.getObject(GDMapGeocodingUtil.class); |
| | | |
| | | private RestTemplate internalRestTemplate = SpringUtil.getObject(RestTemplate.class); |
| | | |
| | | |
| | | |
| | | |
| | | static{ |
| | | if(table == null){ |
| | | table = new Hashtable<>(); |
| | | } |
| | | } |
| | | |
| | | public static boolean isdebug = false; |
| | | public static int i = 0; |
| | | |
| | | |
| | | /** |
| | | * 判断客户端要执行什么操作 |
| | | * |
| | | * @param ctx |
| | | * @param msg |
| | | * @author TaoNingBo |
| | | */ |
| | | public void JudgeOperation(ChannelHandlerContext ctx, Object msg) { |
| | | try { |
| | | // ByteBuf转String |
| | | ByteBuf byteBuf = (ByteBuf) msg; |
| | | |
| | | byte[] req = new byte[byteBuf.readableBytes()]; |
| | | byteBuf.readBytes(req); |
| | | msg = new String(req, "UTF-8"); |
| | | // 验证即时通讯命令是否正确有效 |
| | | if(SinataUtil.isEmpty(msg)) { |
| | | return; |
| | | } |
| | | String msgStr = msg.toString(); |
| | | if(msgStr.indexOf("{") == -1 || msgStr.indexOf("}") == -1 || msgStr.indexOf("code") == -1 || msgStr.indexOf("msg") == -1 || msgStr.indexOf("data") == -1 || msgStr.indexOf("method") == -1) { |
| | | return; |
| | | } |
| | | if(isdebug) { |
| | | // System.out.println("<<<--receive-->>>" + msg); |
| | | } |
| | | |
| | | // 获取socket信息,保存相应的socket |
| | | JSONObject jsonMsg = JSONObject.parseObject(msg.toString()); |
| | | int code = jsonMsg.getInteger("code"); |
| | | String message = jsonMsg.getString("msg"); |
| | | String method = jsonMsg.getString("method"); |
| | | if(code != 200 || !message.equals("SUCCESS")) { |
| | | return; |
| | | } |
| | | JSONObject jsonCon = JSONObject.parseObject(jsonMsg.get("data").toString()); |
| | | |
| | | if(null != ctx && ctx.channel().isActive()){ |
| | | jsonMsg.put("method", Method.pong); |
| | | sendMsgToClient(ctx, jsonMsg.toJSONString()); |
| | | } |
| | | |
| | | //心跳 |
| | | if(method.equals(Method.ping)) { |
| | | Integer type = jsonCon.getInteger("type"); |
| | | String token = jsonCon.getString("token"); |
| | | String userId1 = jsonCon.getString("userId"); |
| | | String device = jsonCon.getString("device"); |
| | | String version = jsonCon.getString("version"); |
| | | if(StringUtil.isNotEmpty(userId1)){ |
| | | |
| | | //判断用户或者司机长连接 |
| | | if(type==1){ |
| | | //确保账号在单个设备上登录 |
| | | if(StringUtil.isNotEmpty(token)){ |
| | | String token_ = redisUtil.getValue("USER_APP_"+ userId1);//获取缓存中最新的数据 |
| | | if(StringUtil.isNotEmpty(token_) && !token.equals(token_)){//不在同一设备上登录,向其他设备发送数据 |
| | | ChannelHandlerContext data_ = NettyChannelMap.getData_(token_.substring(0, 23)); |
| | | |
| | | JSONObject msg_ = new JSONObject(); |
| | | msg_.put("code", 200); |
| | | msg_.put("msg", "SUCCESS"); |
| | | msg_.put("method", "OFFLINE"); |
| | | msg_.put("data", new Object()); |
| | | this.sendMsgToClient(data_, msg_.toJSONString());//给当前通道发送消息 |
| | | TimerTask timerTask = new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | NettyChannelMap.remove_(data_); |
| | | NettyChannelMap.remove(data_); |
| | | } |
| | | }; |
| | | Timer timer = new Timer(); |
| | | timer.schedule(timerTask, 3000); |
| | | timer.cancel(); |
| | | } |
| | | |
| | | NettyChannelMap.update_(token.substring(0, 23), ctx); |
| | | NettyChannelMap.update("USER" + userId1, ctx); |
| | | String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); |
| | | ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); |
| | | |
| | | if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况 |
| | | redisUtil.setStrValue("USER_APP_" + userId1, token); |
| | | } |
| | | } |
| | | |
| | | }else{ |
| | | //添加司机在线 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | // 以表单的方式提交 |
| | | headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); |
| | | //将请求头部和参数合成一个请求 |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("driverId", userId1); |
| | | params.add("device", (null != device && device.equals("carDevice")) ? "2" : "1"); |
| | | params.add("version", version); |
| | | HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); |
| | | String w = internalRestTemplate.postForObject("http://driver-server/base/driverOnline/addDriverOnline",requestEntity , String.class); |
| | | JSONObject jsonObject = JSON.parseObject(w, JSONObject.class); |
| | | if(jsonObject.getIntValue("code") != 200){ |
| | | System.err.println("调用driver-server添加司机在线数据出错了"); |
| | | } |
| | | |
| | | //TODO 存储最后一次上传的时间(用于保证车载端断电后1小时自动下班) |
| | | if(StringUtil.isNotEmpty(device) && device.equals("carDevice")){ |
| | | redisUtil.setStrValue("DEVICE_" + userId1, String.valueOf(System.currentTimeMillis())); |
| | | |
| | | String token_ = redisUtil.getValue("DRIVER_" + userId1);//缓存中拿最新数据 |
| | | if(StringUtil.isNotEmpty(token_) && !token_.equals(token)){ |
| | | ChannelHandlerContext data_ = NettyChannelMap.getData_(token_.substring(0, 23)); |
| | | |
| | | //如果是车载端登录,则将其它端都强迫下线 |
| | | JSONObject msg_ = new JSONObject(); |
| | | msg_.put("code", 200); |
| | | msg_.put("msg", "SUCCESS"); |
| | | msg_.put("method", "OFFLINE"); |
| | | msg_.put("data", new Object()); |
| | | this.sendMsgToClient(data_, msg_.toJSONString());//给当前通道发送消息 |
| | | TimerTask timerTask = new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | NettyChannelMap.remove_(data_); |
| | | NettyChannelMap.remove(data_); |
| | | } |
| | | }; |
| | | Timer timer = new Timer(); |
| | | timer.schedule(timerTask, 3000); |
| | | timer.cancel(); |
| | | } |
| | | |
| | | NettyChannelMap.update("DRIVER" + userId1, ctx); |
| | | NettyChannelMap.update_(token.substring(0, 23), ctx); |
| | | String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); |
| | | ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); |
| | | |
| | | if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况 |
| | | redisUtil.setStrValue("DRIVER_" + userId1, token); |
| | | } |
| | | } |
| | | |
| | | |
| | | //确保账号在单个设备上登录 |
| | | String value = redisUtil.getValue("DEVICE_" + userId1); |
| | | if(StringUtil.isNotEmpty(token) && StringUtil.isEmpty(device) && StringUtil.isEmpty(value)){//APP端登录的操作 |
| | | String token_ = redisUtil.getValue("DRIVER_" + userId1);//缓存中拿最新数据 |
| | | if(StringUtil.isNotEmpty(token_) && !token.equals(token_)){//不在同一设备上登录,向当前设备发送数据 |
| | | ChannelHandlerContext data_ = NettyChannelMap.getData_(token_.substring(0, 23)); |
| | | |
| | | JSONObject msg_ = new JSONObject(); |
| | | msg_.put("code", 200); |
| | | msg_.put("msg", "SUCCESS"); |
| | | msg_.put("method", "OFFLINE"); |
| | | msg_.put("data", new Object()); |
| | | this.sendMsgToClient(data_, msg_.toJSONString());//给当前通道发送消息 |
| | | TimerTask timerTask = new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | NettyChannelMap.remove_(data_); |
| | | NettyChannelMap.remove(data_); |
| | | } |
| | | }; |
| | | Timer timer = new Timer(); |
| | | timer.schedule(timerTask, 3000); |
| | | timer.cancel(); |
| | | } |
| | | NettyChannelMap.update("DRIVER" + userId1, ctx); |
| | | NettyChannelMap.update_(token.substring(0, 23), ctx); |
| | | String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); |
| | | ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); |
| | | |
| | | if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况 |
| | | redisUtil.setStrValue("DRIVER_" + userId1, token); |
| | | } |
| | | } |
| | | |
| | | |
| | | //存储通讯通道 |
| | | if(null != ctx && ctx.channel().isActive()){ |
| | | // System.err.println("开始存储司机通道" + userId1); |
| | | NettyChannelMap.update("DRIVER" + userId1, ctx); |
| | | String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); |
| | | ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //司机上传位置 |
| | | if(method.equals(Method.location)){ |
| | | Integer driverId = jsonCon.getInteger("driverId"); |
| | | Integer orderId = jsonCon.getInteger("orderId"); |
| | | Integer orderType = jsonCon.getInteger("orderType"); |
| | | Double lon = jsonCon.getDouble("lon"); |
| | | Double lat = jsonCon.getDouble("lat"); |
| | | Double computeAzimuth = jsonCon.getDouble("computeAzimuth"); |
| | | Double altitude = jsonCon.getDouble("altitude"); |
| | | if(SinataUtil.isNotEmpty(driverId)){ |
| | | if(null != lon && 0 != lon && null != lat && 0 != lat){ |
| | | if(null != orderId && 0 != driverId && null != orderType && 0 != orderType){//开始存入数据库 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | // 以表单的方式提交 |
| | | headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); |
| | | //将请求头部和参数合成一个请求 |
| | | MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); |
| | | params.add("orderType", String.valueOf(orderType)); |
| | | params.add("orderId", String.valueOf(orderId)); |
| | | params.add("driverId", String.valueOf(driverId)); |
| | | params.add("lon", String.valueOf(lon)); |
| | | params.add("lat", String.valueOf(lat)); |
| | | params.add("directionAngle", String.valueOf(computeAzimuth)); |
| | | params.add("altitude", String.valueOf(altitude)); |
| | | HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); |
| | | String s = internalRestTemplate.postForObject("http://driver-server/base/savePosition",requestEntity , String.class); |
| | | JSONObject jsonObject = JSON.parseObject(s, JSONObject.class); |
| | | if(jsonObject.getIntValue("code") != 200){ |
| | | System.err.println("调用driver-server存储位置数据出错了"); |
| | | } |
| | | } |
| | | redisUtil.setStrValue("DRIVER" + driverId, lon + "," + lat, 300);//实时位置存入redis中 |
| | | }else{ |
| | | NettyServerController.sendMsgToClient(ctx, "__error__" + msg.toString()); |
| | | } |
| | | }else{ |
| | | NettyServerController.sendMsgToClient(ctx, "__error__" + msg.toString()); |
| | | } |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | if(isdebug) { |
| | | NettyServerController.sendMsgToClient(ctx, "__error__" + msg.toString()); |
| | | } |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 向客户端发送消息 |
| | | * |
| | | * @param ctx |
| | | * @param msg |
| | | * @author TaoNingBo |
| | | */ |
| | | public static void sendMsgToClient(ChannelHandlerContext ctx, String msg) { |
| | | if (ctx != null && ctx.channel().isActive()) { |
| | | ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes()); |
| | | ChannelFuture sync; |
| | | try { |
| | | sync = ctx.writeAndFlush(buffer).sync(); |
| | | if(!sync.isSuccess()){//如果推送失败则继续推送10次 |
| | | boolean b = true; |
| | | for (int i = 0; i < 10; i++) { |
| | | ctx.wait(3000); |
| | | sync = ctx.writeAndFlush(buffer).sync(); |
| | | if(sync.isSuccess()){ |
| | | b = false; |
| | | break; |
| | | } |
| | | System.err.println("推送不成功,将继续推送"+msg); |
| | | } |
| | | if(b){ |
| | | NettyChannelMap.remove(ctx); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | System.err.println("推送发生异常,记录:"+msg); |
| | | NettyChannelMap.remove(ctx); |
| | | } |
| | | if(isdebug) { |
| | | System.err.println("<<<--send-->>>" + msg) ; |
| | | } |
| | | }else{ |
| | | System.err.println("推送失败,长连接不存在"); |
| | | NettyChannelMap.remove(ctx); |
| | | } |
| | | } |
| | | |
| | | // **链接断开 将推送消息记录 |
| | | public static void sendMsgToClient(String cacheType, Integer id,String msg) { |
| | | ChannelHandlerContext ctx = NettyChannelMap.getData(cacheType + id); |
| | | if (ctx != null) { |
| | | ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes()); |
| | | ChannelFuture sync; |
| | | try { |
| | | sync = ctx.writeAndFlush(buffer).sync(); |
| | | // System.out.println("推送状态"+sync.isSuccess()); |
| | | if(!sync.isSuccess()){ |
| | | for (int i = 0; i < 10; i++) { |
| | | sync = ctx.writeAndFlush(buffer).sync(); |
| | | if(!sync.isSuccess()){ |
| | | sync = ctx.writeAndFlush(buffer).sync(); |
| | | System.err.println("推送不成功,将继续推送"+msg); |
| | | if(i == 9){ |
| | | table.put(cacheType+id, msg); |
| | | |
| | | ctx.close(); |
| | | System.err.println("推送发生异常,记录:"+msg); |
| | | } |
| | | }else{ |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | table.put(cacheType+id, msg); |
| | | System.err.println("推送发生异常,记录:"+msg); |
| | | } |
| | | if(isdebug) { |
| | | // System.out.println("<<<--send-->>>" + msg); |
| | | } |
| | | }else{ |
| | | table.put(cacheType+id, msg); |
| | | System.err.println("链接断开,记录:id="+cacheType+id+",消息:"+msg); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 记录推送不成功消息,并在心跳连接续推 |
| | | * @param token |
| | | */ |
| | | public static void resendMsg(String token){ |
| | | String msg = table.get(token); |
| | | ChannelHandlerContext ctx = NettyChannelMap.getData(token); |
| | | if(SinataUtil.isNotEmpty(msg) && ctx != null && ctx.channel().isActive()){ |
| | | ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes()); |
| | | ChannelFuture sync; |
| | | try { |
| | | sync = ctx.writeAndFlush(buffer).sync(); |
| | | System.err.println("重发异常推送状态"+sync.isSuccess()+",位置:"+token+",消息内容:"+msg); |
| | | if(!sync.isSuccess()){ |
| | | i++; |
| | | if(i == 10){ |
| | | i =0; |
| | | ctx.close(); |
| | | return; |
| | | } |
| | | System.err.println("重发异常推送不成功,将继续推送"+msg); |
| | | resendMsg(token); |
| | | }else{ |
| | | i=0; |
| | | } |
| | | table.remove(token); |
| | | } catch (Exception e) { |
| | | resendMsg(token); |
| | | System.err.println("重发推送发生异常,记录:"+msg); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.sinata.zuul.util.echo; |
| | | |
| | | import io.netty.channel.ChannelInitializer; |
| | | import io.netty.channel.ChannelPipeline; |
| | | import io.netty.channel.socket.SocketChannel; |
| | | import io.netty.handler.codec.string.StringDecoder; |
| | | import io.netty.handler.codec.string.StringEncoder; |
| | | |
| | | import java.nio.charset.Charset; |
| | | |
| | | public class ServerInit extends ChannelInitializer<SocketChannel> { |
| | | |
| | | private DiscardServerHandler discardServerHandler = new DiscardServerHandler(); |
| | | |
| | | @Override |
| | | protected void initChannel(SocketChannel ch) throws Exception { |
| | | ChannelPipeline pipeline = ch.pipeline(); |
| | | pipeline.addLast(new StringDecoder(Charset.forName("utf-8"))); |
| | | pipeline.addLast(new StringEncoder(Charset.forName("utf-8"))); |
| | | // 心跳监测机制 |
| | | // pipeline.addLast(new IdleStateHandler(5,7,10, TimeUnit.SECONDS)); |
| | | pipeline.addLast(discardServerHandler); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | server: |
| | | port: 80 |
| | | |
| | | spring: |
| | | application: |
| | | name: zuul-gateway #服务名称 |
| | | |
| | | eureka: |
| | | client: |
| | | service-url: #注册中心地址 |
| | | defaultZone: http://sinata:sinata@127.0.0.1:8000/eureka #启用身份验证的方式连接 |
| | | register-with-eureka: true #在注册中心进行注册 |
| | | fetch-registry: true #从Eureka中获取注册信息。 |
| | | |
| | | zuul: |
| | | # prefix: /api #添加URL前缀 |
| | | sensitive-headers: #将默认过滤掉的敏感数据清除,不进行过滤("Cookie", "Set-Cookie", "Authorization") |
| | | routes: |
| | | user-server: #接口调用路由服务,名字任意取。(用户端服务) |
| | | path: /user/** #配置请求URL的请求规则 |
| | | url: http://127.0.0.1:8006 #真正的微服务地址,path匹配的请求都转发到这里 |
| | | service-id: user-server #指定Eureka注册中心的服务id |
| | | driver-server: #路由司机相关请求 |
| | | path: /driver/** #配置请求URL的请求规则 |
| | | url: http://127.0.0.1:8007 #真正的微服务地址,path匹配的请求都转发到这里 |
| | | service-id: driver-server #指定Eureka注册中心的服务id |
| | | dispatch-server: #路由调度相关请求 |
| | | path: /dispatch/** #配置请求URL的请求规则 |
| | | url: http://127.0.0.1:8008 #真正的微服务地址,path匹配的请求都转发到这里 |
| | | service-id: dispatch-server #指定Eureka注册中心的服务id |
| | | # 配置zuul超时时间 |
| | | host: |
| | | connect-timeout-millis: 150000 |
| | | socket-timeout-millis: 15000 |
| | | |
| | | # 配置ribbon超时时间 |
| | | ribbon: |
| | | ReadTimeout: 10000 |
| | | ConnectTimeout: 10000 |
New file |
| | |
| | | #redisÅäÖÿªÊ¼ |
| | | # RedisÊý¾Ý¿âË÷Òý£¨Ä¬ÈÏΪ0£© |
| | | spring.redis.database=0 |
| | | # Redis·þÎñÆ÷µØÖ· |
| | | spring.redis.host=127.0.0.1 |
| | | # Redis·þÎñÆ÷Á¬½Ó¶Ë¿Ú |
| | | #spring.redis.port=16379 |
| | | spring.redis.port=6379 |
| | | # Redis·þÎñÆ÷Á¬½ÓÃÜÂ루ĬÈÏΪ¿Õ£© |
| | | #spring.redis.password=mPMHThYzlT8DWgl8HLqwPEyPOiHDPPB5 |
| | | spring.redis.password=123456 |
| | | # Á¬½Ó³Ø×î´óÁ¬½ÓÊý£¨Ê¹ÓøºÖµ±íʾûÓÐÏÞÖÆ£© |
| | | spring.redis.jedis.pool.max-active=1024 |
| | | # Á¬½Ó³Ø×î´ó×èÈûµÈ´ýʱ¼ä£¨Ê¹ÓøºÖµ±íʾûÓÐÏÞÖÆ£© |
| | | spring.redis.jedis.pool.max-wait=10000 |
| | | # Á¬½Ó³ØÖеÄ×î´ó¿ÕÏÐÁ¬½Ó |
| | | spring.redis.jedis.pool.max-idle=200 |
| | | # Á¬½Ó³ØÖеÄ×îС¿ÕÏÐÁ¬½Ó |
| | | spring.redis.jedis.pool.min-idle=50 |
| | | # Á¬½Ó³¬Ê±Ê±¼ä£¨ºÁÃ룩 |
| | | spring.redis.timeout=10000 |
| | | #redisÅäÖýáÊø |
| | | spring.redis.block-when-exhausted=true |
New file |
| | |
| | | 0ef42640d32181b65822b974b89492d4 |