From de3fa815fa8f9fdf914972a98491e098c90f8441 Mon Sep 17 00:00:00 2001 From: xuhy <3313886187@qq.com> Date: 星期五, 11 八月 2023 14:11:00 +0800 Subject: [PATCH] 初始化日月出行,zuul,demo --- ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyMsg.java | 165 ++ ZuulOKTravel/src/main/java/com/sinata/zuul/config/RedisConfig.java | 54 EurekaOKTravel/src/main/java/com/sinata/eureka/config/WebSecurityConfig.java | 24 ZuulOKTravel/src/main/java/com/sinata/zuul/util/GDMapGeocodingUtil.java | 102 + ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/NettyWebSocketController.java | 215 ++ ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/ChildChannelHandler.java | 36 ZuulOKTravel/src/main/resources/application.yml | 39 ZuulOKTravel/mvnw | 310 +++ ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/CacheType.java | 86 + EurekaOKTravel/.mvn/wrapper/maven-wrapper.properties | 2 ZuulOKTravel/src/main/java/com/sinata/zuul/util/SinataUtil.java | 405 +++++ ZuulOKTravel/src/main/java/com/sinata/zuul/util/SpringUtil.java | 34 ZuulOKTravel/mvnw.cmd | 182 ++ EurekaOKTravel/src/main/java/com/sinata/eureka/EurekaApplication.java | 22 ZuulOKTravel/src/main/java/com/sinata/zuul/util/CrossOriginFilter.java | 54 EurekaOKTravel/.mvn/wrapper/MavenWrapperDownloader.java | 118 + ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyServerController.java | 400 +++++ ZuulOKTravel/pom.xml | 105 + EurekaOKTravel/.mvn/wrapper/maven-wrapper.jar | 0 ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/NettyServer0.java | 77 EurekaOKTravel/.gitignore | 31 ZuulOKTravel/src/main/java/com/sinata/zuul/util/StringUtil.java | 121 + ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/ClientPingMessage.java | 59 EurekaOKTravel/mvnw.cmd | 182 ++ ZuulOKTravel/.mvn/wrapper/maven-wrapper.jar | 0 ZuulOKTravel/src/main/java/com/sinata/zuul/util/RedisUtil.java | 124 + ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/createSSLContext.java | 31 ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyChannelMap.java | 133 + ZuulOKTravel/.mvn/wrapper/MavenWrapperDownloader.java | 118 + ZuulOKTravel/.mvn/wrapper/maven-wrapper.properties | 2 ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyServer.java | 95 + ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/ServerInit.java | 25 ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/Method.java | 26 ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/Global.java | 9 ZuulOKTravel/.gitignore | 31 ZuulOKTravel/src/main/java/com/sinata/zuul/controller/NettyController.java | 54 ZuulOKTravel/src/main/resources/static/tXQaRbVjpJ.txt | 1 EurekaOKTravel/pom.xml | 82 + ZuulOKTravel/src/main/java/com/sinata/zuul/util/NettyStartListener.java | 36 ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/WebSocketHandler.java | 180 ++ EurekaOKTravel/mvnw | 310 +++ EurekaOKTravel/src/main/resources/application.yml | 24 ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/DiscardServerHandler.java | 153 + ZuulOKTravel/src/main/java/com/sinata/zuul/ZuulApplication.java | 121 + ZuulOKTravel/src/main/java/com/sinata/zuul/controller/RedisController.java | 83 + ZuulOKTravel/src/main/resources/redis.properties | 23 ZuulOKTravel/src/main/java/com/sinata/zuul/util/ResultUtil.java | 188 ++ 47 files changed, 4,672 insertions(+), 0 deletions(-) diff --git a/EurekaOKTravel/.gitignore b/EurekaOKTravel/.gitignore new file mode 100644 index 0000000..a2a3040 --- /dev/null +++ b/EurekaOKTravel/.gitignore @@ -0,0 +1,31 @@ +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/ diff --git a/EurekaOKTravel/.mvn/wrapper/MavenWrapperDownloader.java b/EurekaOKTravel/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..a45eb6b --- /dev/null +++ b/EurekaOKTravel/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,118 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/EurekaOKTravel/.mvn/wrapper/maven-wrapper.jar b/EurekaOKTravel/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..2cc7d4a --- /dev/null +++ b/EurekaOKTravel/.mvn/wrapper/maven-wrapper.jar Binary files differ diff --git a/EurekaOKTravel/.mvn/wrapper/maven-wrapper.properties b/EurekaOKTravel/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..642d572 --- /dev/null +++ b/EurekaOKTravel/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +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 diff --git a/EurekaOKTravel/mvnw b/EurekaOKTravel/mvnw new file mode 100644 index 0000000..a16b543 --- /dev/null +++ b/EurekaOKTravel/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/EurekaOKTravel/mvnw.cmd b/EurekaOKTravel/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/EurekaOKTravel/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/EurekaOKTravel/pom.xml b/EurekaOKTravel/pom.xml new file mode 100644 index 0000000..bd79780 --- /dev/null +++ b/EurekaOKTravel/pom.xml @@ -0,0 +1,82 @@ +<?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> diff --git a/EurekaOKTravel/src/main/java/com/sinata/eureka/EurekaApplication.java b/EurekaOKTravel/src/main/java/com/sinata/eureka/EurekaApplication.java new file mode 100644 index 0000000..1e9c18d --- /dev/null +++ b/EurekaOKTravel/src/main/java/com/sinata/eureka/EurekaApplication.java @@ -0,0 +1,22 @@ +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); + } +} diff --git a/EurekaOKTravel/src/main/java/com/sinata/eureka/config/WebSecurityConfig.java b/EurekaOKTravel/src/main/java/com/sinata/eureka/config/WebSecurityConfig.java new file mode 100644 index 0000000..66bdadc --- /dev/null +++ b/EurekaOKTravel/src/main/java/com/sinata/eureka/config/WebSecurityConfig.java @@ -0,0 +1,24 @@ +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(); + } +} diff --git a/EurekaOKTravel/src/main/resources/application.yml b/EurekaOKTravel/src/main/resources/application.yml new file mode 100644 index 0000000..0241f86 --- /dev/null +++ b/EurekaOKTravel/src/main/resources/application.yml @@ -0,0 +1,24 @@ +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 diff --git a/ZuulOKTravel/.gitignore b/ZuulOKTravel/.gitignore new file mode 100644 index 0000000..a2a3040 --- /dev/null +++ b/ZuulOKTravel/.gitignore @@ -0,0 +1,31 @@ +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/ diff --git a/ZuulOKTravel/.mvn/wrapper/MavenWrapperDownloader.java b/ZuulOKTravel/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..a45eb6b --- /dev/null +++ b/ZuulOKTravel/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,118 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/ZuulOKTravel/.mvn/wrapper/maven-wrapper.jar b/ZuulOKTravel/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..2cc7d4a --- /dev/null +++ b/ZuulOKTravel/.mvn/wrapper/maven-wrapper.jar Binary files differ diff --git a/ZuulOKTravel/.mvn/wrapper/maven-wrapper.properties b/ZuulOKTravel/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..642d572 --- /dev/null +++ b/ZuulOKTravel/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +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 diff --git a/ZuulOKTravel/mvnw b/ZuulOKTravel/mvnw new file mode 100644 index 0000000..a16b543 --- /dev/null +++ b/ZuulOKTravel/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/ZuulOKTravel/mvnw.cmd b/ZuulOKTravel/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/ZuulOKTravel/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/ZuulOKTravel/pom.xml b/ZuulOKTravel/pom.xml new file mode 100644 index 0000000..c2048fe --- /dev/null +++ b/ZuulOKTravel/pom.xml @@ -0,0 +1,105 @@ +<?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> diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/ZuulApplication.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/ZuulApplication.java new file mode 100644 index 0000000..bb80363 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/ZuulApplication.java @@ -0,0 +1,121 @@ +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); +// } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/config/RedisConfig.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/config/RedisConfig.java new file mode 100644 index 0000000..895ffce --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/config/RedisConfig.java @@ -0,0 +1,54 @@ +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; + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/controller/NettyController.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/controller/NettyController.java new file mode 100644 index 0000000..b34e425 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/controller/NettyController.java @@ -0,0 +1,54 @@ +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("推送失败")); + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/controller/RedisController.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/controller/RedisController.java new file mode 100644 index 0000000..4866ef5 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/controller/RedisController.java @@ -0,0 +1,83 @@ +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()); + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/CrossOriginFilter.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/CrossOriginFilter.java new file mode 100644 index 0000000..2e0e635 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/CrossOriginFilter.java @@ -0,0 +1,54 @@ +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() { + + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/GDMapGeocodingUtil.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/GDMapGeocodingUtil.java new file mode 100644 index 0000000..99e0a5c --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/GDMapGeocodingUtil.java @@ -0,0 +1,102 @@ +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; + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/NettyStartListener.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/NettyStartListener.java new file mode 100644 index 0000000..1d8670a --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/NettyStartListener.java @@ -0,0 +1,36 @@ +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) { + + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/RedisUtil.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/RedisUtil.java new file mode 100644 index 0000000..3abe256 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/RedisUtil.java @@ -0,0 +1,124 @@ +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(); + } + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/ResultUtil.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/ResultUtil.java new file mode 100644 index 0000000..5a4f428 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/ResultUtil.java @@ -0,0 +1,188 @@ +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); + } + +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/SinataUtil.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/SinataUtil.java new file mode 100644 index 0000000..287d4ad --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/SinataUtil.java @@ -0,0 +1,405 @@ +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; +} +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/SpringUtil.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/SpringUtil.java new file mode 100644 index 0000000..838138a --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/SpringUtil.java @@ -0,0 +1,34 @@ +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); + } +} \ No newline at end of file diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/StringUtil.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/StringUtil.java new file mode 100644 index 0000000..3f6641f --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/StringUtil.java @@ -0,0 +1,121 @@ +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); + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/CacheType.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/CacheType.java new file mode 100644 index 0000000..65621d6 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/CacheType.java @@ -0,0 +1,86 @@ +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_"; +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/ChildChannelHandler.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/ChildChannelHandler.java new file mode 100644 index 0000000..a256061 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/ChildChannelHandler.java @@ -0,0 +1,36 @@ +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()); + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/ClientPingMessage.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/ClientPingMessage.java new file mode 100644 index 0000000..93a8497 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/ClientPingMessage.java @@ -0,0 +1,59 @@ +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; + } + +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/Global.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/Global.java new file mode 100644 index 0000000..1f3fa95 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/Global.java @@ -0,0 +1,9 @@ +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); +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/NettyServer0.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/NettyServer0.java new file mode 100644 index 0000000..aafe1b3 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/NettyServer0.java @@ -0,0 +1,77 @@ +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(); + } + } + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/NettyWebSocketController.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/NettyWebSocketController.java new file mode 100644 index 0000000..b525762 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/NettyWebSocketController.java @@ -0,0 +1,215 @@ +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); + } + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/WebSocketHandler.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/WebSocketHandler.java new file mode 100644 index 0000000..bbb3ba2 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/WebSocketHandler.java @@ -0,0 +1,180 @@ +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); + } + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/createSSLContext.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/createSSLContext.java new file mode 100644 index 0000000..8487513 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/applets/createSSLContext.java @@ -0,0 +1,31 @@ +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; + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/DiscardServerHandler.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/DiscardServerHandler.java new file mode 100644 index 0000000..6edaf44 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/DiscardServerHandler.java @@ -0,0 +1,153 @@ +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); +// } +// } + +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/Method.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/Method.java new file mode 100644 index 0000000..aa3f100 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/Method.java @@ -0,0 +1,26 @@ +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"; + + + +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyChannelMap.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyChannelMap.java new file mode 100644 index 0000000..b27fd8f --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyChannelMap.java @@ -0,0 +1,133 @@ +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); + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyMsg.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyMsg.java new file mode 100644 index 0000000..2f49fc0 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyMsg.java @@ -0,0 +1,165 @@ +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); + } + } + } + + +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyServer.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyServer.java new file mode 100644 index 0000000..82cce36 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyServer.java @@ -0,0 +1,95 @@ +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(); + } + } + } +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyServerController.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyServerController.java new file mode 100644 index 0000000..09ee9a6 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/NettyServerController.java @@ -0,0 +1,400 @@ +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); + } + } + } + + +} diff --git a/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/ServerInit.java b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/ServerInit.java new file mode 100644 index 0000000..3a50298 --- /dev/null +++ b/ZuulOKTravel/src/main/java/com/sinata/zuul/util/echo/ServerInit.java @@ -0,0 +1,25 @@ +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); + } + +} diff --git a/ZuulOKTravel/src/main/resources/application.yml b/ZuulOKTravel/src/main/resources/application.yml new file mode 100644 index 0000000..d08f4ca --- /dev/null +++ b/ZuulOKTravel/src/main/resources/application.yml @@ -0,0 +1,39 @@ +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 \ No newline at end of file diff --git a/ZuulOKTravel/src/main/resources/redis.properties b/ZuulOKTravel/src/main/resources/redis.properties new file mode 100644 index 0000000..7cb4d29 --- /dev/null +++ b/ZuulOKTravel/src/main/resources/redis.properties @@ -0,0 +1,23 @@ +#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 \ No newline at end of file diff --git a/ZuulOKTravel/src/main/resources/static/tXQaRbVjpJ.txt b/ZuulOKTravel/src/main/resources/static/tXQaRbVjpJ.txt new file mode 100644 index 0000000..9059363 --- /dev/null +++ b/ZuulOKTravel/src/main/resources/static/tXQaRbVjpJ.txt @@ -0,0 +1 @@ +0ef42640d32181b65822b974b89492d4 \ No newline at end of file -- Gitblit v1.7.1