├── .gitignore ├── LICENSE ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── top │ │ └── itning │ │ └── yunshunotesr │ │ ├── YunshuNotesRApplication.java │ │ ├── config │ │ └── CorsConfig.java │ │ ├── controller │ │ ├── NoteBookController.java │ │ ├── NoteController.java │ │ └── UserController.java │ │ ├── dao │ │ ├── HbaseRepository.java │ │ ├── NoteBookDao.java │ │ └── UserDao.java │ │ ├── entity │ │ ├── Note.java │ │ ├── NoteBook.java │ │ ├── ServerResponse.java │ │ └── User.java │ │ ├── exception │ │ ├── ExceptionResolver.java │ │ ├── IncorrectParameterException.java │ │ ├── NoSuchIdException.java │ │ ├── UserAlreadyExistsException.java │ │ └── UserDoesNotExistException.java │ │ ├── securtiy │ │ ├── SecurityFilter.java │ │ ├── SecurityUtils.java │ │ └── SessionListener.java │ │ ├── service │ │ ├── NoteBookService.java │ │ ├── NoteService.java │ │ ├── UserService.java │ │ └── impl │ │ │ ├── HbaseNoteServiceImpl.java │ │ │ ├── NoteBookServiceImpl.java │ │ │ └── UserServiceImpl.java │ │ └── util │ │ └── EmailUtils.java └── resources │ └── application.yml └── test └── java └── top └── itning └── yunshunotesr ├── YunshuNotesRApplicationTests.java ├── dao ├── NoteBookDaoTest.java └── UserDaoTest.java └── service └── NoteBookServiceTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 云舒云笔记 2 | 3 | > 基于HBASE的大数据存储分布式云计算笔记 4 | > 5 | > 云笔记使用大数据成熟的分布式存储解决方案,解决了传统笔记数据日益膨胀,数据丢失等问题。云笔记通过数据分析、用户画像等技术实现,能够通过精准推送其他人公开分享的云笔记来达到扩充用户知识行囊的目的,并且通过独立的账户安全体系来达到笔记安全私有化,保证用户独立的空间。且分布式存储可以达到用户笔记空间无限大,笔记平台响应式,满足用户不同平台办公的需求。 6 | 7 | [前端项目地址:https://github.com/itning/yunshu-notes](https://github.com/itning/yunshu-notes) 8 | 9 | [![GitHub stars](https://img.shields.io/github/stars/itning/yunshu-notes-r.svg?style=social&label=Stars)](https://github.com/itning/yunshu-notes-r/stargazers) 10 | [![GitHub forks](https://img.shields.io/github/forks/itning/yunshu-notes-r.svg?style=social&label=Fork)](https://github.com/itning/yunshu-notes-r/network/members) 11 | [![GitHub watchers](https://img.shields.io/github/watchers/itning/yunshu-notes-r.svg?style=social&label=Watch)](https://github.com/itning/yunshu-notes-r/watchers) 12 | [![GitHub followers](https://img.shields.io/github/followers/itning.svg?style=social&label=Follow)](https://github.com/itning?tab=followers) 13 | 14 | [![GitHub issues](https://img.shields.io/github/issues/itning/yunshu-notes-r.svg)](https://github.com/itning/yunshu-notes-r/issues) 15 | [![GitHub license](https://img.shields.io/github/license/itning/yunshu-notes-r.svg)](https://github.com/itning/yunshu-notes-r/blob/master/LICENSE) 16 | [![GitHub last commit](https://img.shields.io/github/last-commit/itning/yunshu-notes-r.svg)](https://github.com/itning/yunshu-notes-r/commits) 17 | [![GitHub release](https://img.shields.io/github/release/itning/yunshu-notes-r.svg)](https://github.com/itning/yunshu-notes-r/releases) 18 | [![GitHub repo size in bytes](https://img.shields.io/github/repo-size/itning/yunshu-notes-r.svg)](https://github.com/itning/yunshu-notes-r) 19 | [![HitCount](http://hits.dwyl.io/itning/yunshu-notes-r.svg)](http://hits.dwyl.io/itning/yunshu-notes-r) 20 | [![language](https://img.shields.io/badge/language-JAVA-green.svg)](https://github.com/itning/yunshu-notes-r) 21 | 22 | ## 接口 23 | ### 笔记本 24 | | 方法 | 接口 | 参数 | 说明 | 25 | | ---- | ----------- | ---- |---- | 26 | | get | /note_books | | 获取所有笔记本信息集合 | 27 | | post | /note_book | name:笔记本名称 | 新建笔记本 | 28 | | patch | /note_book/{id}/{name} | id:笔记本ID;name:新笔记本名 | 修改笔记本 | 29 | | delete | /note_book/{id} | id:笔记本ID | 删除笔记本 | 30 | ### 笔记 31 | | 方法 | 接口 | 参数 | 说明 | 32 | | ---- | ----------- | ---- |---- | 33 | | get | /note/{id} | id:笔记ID | 获取笔记 | 34 | | post | /note | noteBookId:笔记本ID;title:笔记标题;content:笔记内容 | 新建笔记 | 35 | | patch | /note/{id}/{title}/{content} | id:笔记ID;title:笔记名;content:笔记内容 | 修改笔记 | 36 | | delete | /note/{id} | id:笔记ID | 删除笔记 | 37 | ### 用户 38 | | 方法 | 接口 | 参数 | 说明 | 39 | | ---- | ----------- | ---- |---- | 40 | | post | /login | username:用户名;password:密码 | 登陆 | 41 | | get | /logout | | 注销 | 42 | | get | /getLoginUser | | 获取登录用户信息 | 43 | | post | /registered | name:昵称;username:用户名;password:密码;code:验证码 | 删除笔记 | 44 | | get | /get_code | email:邮箱 | 获取验证码 | 45 | | get | /forget_get_code | email:邮箱 | 获取忘记密码邮箱验证码 | 46 | | post | /forget_password | code:验证码;vCode:密钥;password:密码 | 忘记密码 | 47 | | post | /change_user_profile | id:用户ID;name:新用户名:password:新密码 | 更改用户信息 | 48 | 49 | ## 关于跨域 50 | 51 | [CorsConfig.java](https://github.com/itning/yunshu-notes-r/blob/master/src/main/java/top/itning/yunshunotesr/config/CorsConfig.java#L16) 52 | 53 | [SecurityFilter.java](https://github.com/itning/yunshu-notes-r/blob/master/src/main/java/top/itning/yunshunotesr/securtiy/SecurityFilter.java#L53) 54 | 55 | 修改这两个位置,可能下个版本会单独提到配置文件中 56 | 57 | ## 项目技术栈 58 | 59 | [spring boot](https://github.com/spring-projects/spring-boot) 60 | [apache hbase](https://github.com/apache/hbase) 61 | 62 | 63 | 64 | ## 开源协议 65 | 66 | MIT 67 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | top.itning 7 | yunshu-notes-r 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | yunshu-notes-r 12 | HBASE-based big data storage distributed cloud computing notes 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.3.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | mysql 38 | mysql-connector-java 39 | 40 | 41 | 42 | org.apache.hbase 43 | hbase-client 44 | 2.0.1 45 | 46 | 47 | commons-logging 48 | commons-logging 49 | 50 | 51 | log4j 52 | log4j 53 | 54 | 55 | jcodings 56 | org.jruby.jcodings 57 | 58 | 59 | jackson-mapper-asl 60 | org.codehaus.jackson 61 | 62 | 63 | jackson-core-asl 64 | org.codehaus.jackson 65 | 66 | 67 | 68 | 69 | 70 | javax.mail 71 | mail 72 | 1.4.7 73 | 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-starter-test 78 | test 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | org.springframework.boot 87 | spring-boot-maven-plugin 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/YunshuNotesRApplication.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.ServletComponentScan; 6 | 7 | 8 | /** 9 | * Spring Boot 启动类 10 | * 11 | * @author itning 12 | */ 13 | @SpringBootApplication 14 | @ServletComponentScan 15 | public class YunshuNotesRApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(YunshuNotesRApplication.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | /** 8 | * CORS跨域配置 9 | * 10 | * @author itning 11 | */ 12 | @Configuration 13 | public class CorsConfig implements WebMvcConfigurer { 14 | @Override 15 | public void addCorsMappings(CorsRegistry registry) { 16 | registry.addMapping("/**") 17 | .allowedOrigins("*") 18 | .allowCredentials(true) 19 | .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH") 20 | .maxAge(3600); 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/controller/NoteBookController.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.controller; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | import top.itning.yunshunotesr.entity.ServerResponse; 8 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 9 | import top.itning.yunshunotesr.exception.NoSuchIdException; 10 | import top.itning.yunshunotesr.service.NoteBookService; 11 | 12 | import javax.servlet.http.HttpServletResponse; 13 | import java.util.ArrayList; 14 | 15 | /** 16 | * 笔记本控制层 17 | * 18 | * @author itning 19 | */ 20 | @RestController 21 | public class NoteBookController { 22 | private static final Logger logger = LoggerFactory.getLogger(NoteBookController.class); 23 | 24 | private final NoteBookService noteBookService; 25 | 26 | @Autowired 27 | public NoteBookController(NoteBookService noteBookService) { 28 | this.noteBookService = noteBookService; 29 | } 30 | 31 | /** 32 | * 获取所有笔记本信息集合 33 | * 34 | * @return 笔记本集合 35 | */ 36 | @GetMapping("/note_books") 37 | public ServerResponse getAllNoteBooks() { 38 | return new ServerResponse(noteBookService.getAllNoteBook().orElse(new ArrayList<>())); 39 | } 40 | 41 | /** 42 | * 新建笔记本 43 | * 44 | * @param name 笔记本名 45 | * @param response {@link HttpServletResponse} 46 | */ 47 | @PostMapping("/note_book") 48 | public void newNoteBook(String name, HttpServletResponse response) { 49 | try { 50 | noteBookService.addNoteBook(name); 51 | response.setStatus(201); 52 | } catch (IncorrectParameterException e) { 53 | logger.info("new note book exception " + e); 54 | response.setStatus(400); 55 | } 56 | } 57 | 58 | /** 59 | * 修改笔记本 60 | * 61 | * @param id 笔记本ID 62 | * @param name 新笔记本名 63 | * @param response {@link HttpServletResponse} 64 | */ 65 | @PatchMapping("/note_book/{id}/{name}") 66 | public void upNoteBook(@PathVariable("id") String id, @PathVariable("name") String name, HttpServletResponse response) { 67 | try { 68 | noteBookService.modifyNoteBookName(id, name); 69 | response.setStatus(204); 70 | } catch (NoSuchIdException e) { 71 | logger.info("modify note book exception " + e); 72 | response.setStatus(404); 73 | } catch (IncorrectParameterException e) { 74 | logger.info("modify note book exception " + e); 75 | response.setStatus(400); 76 | } 77 | } 78 | 79 | /** 80 | * 删除笔记本 81 | * 82 | * @param id 笔记本ID 83 | * @param response {@link HttpServletResponse} 84 | */ 85 | @DeleteMapping("/note_book/{id}") 86 | public void delNoteBook(@PathVariable("id") String id, HttpServletResponse response) { 87 | try { 88 | noteBookService.deleteNoteBookById(id); 89 | response.setStatus(204); 90 | } catch (NoSuchIdException e) { 91 | logger.info("delete note book exception " + e); 92 | response.setStatus(400); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/controller/NoteController.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.controller; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | import top.itning.yunshunotesr.entity.Note; 8 | import top.itning.yunshunotesr.entity.ServerResponse; 9 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 10 | import top.itning.yunshunotesr.exception.NoSuchIdException; 11 | import top.itning.yunshunotesr.service.NoteService; 12 | 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.Optional; 17 | 18 | /** 19 | * 笔记控制层 20 | * 21 | * @author itning 22 | */ 23 | @RestController 24 | public class NoteController { 25 | private static final Logger logger = LoggerFactory.getLogger(NoteController.class); 26 | 27 | private final NoteService noteService; 28 | 29 | @Autowired 30 | public NoteController(NoteService noteService) { 31 | this.noteService = noteService; 32 | } 33 | 34 | /** 35 | * 获取某笔记本下的所有笔记 36 | * 37 | * @param id 笔记本ID 38 | * @return 笔记集合 39 | */ 40 | @GetMapping("/notes/{id}") 41 | public ServerResponse getAllNotes(@PathVariable("id") String id) { 42 | logger.debug("get all notes by note book id is " + id); 43 | ServerResponse serverResponse = new ServerResponse(); 44 | Optional> optionalNoteList = noteService.getAllNotes(id); 45 | if (optionalNoteList.isPresent()) { 46 | serverResponse.setDataList(optionalNoteList.get()); 47 | } else { 48 | serverResponse.setStatus(404); 49 | serverResponse.setMsg("未找到"); 50 | } 51 | return serverResponse; 52 | } 53 | 54 | /** 55 | * 获取笔记 56 | * 57 | * @param id 笔记Id 58 | * @return 笔记信息 59 | */ 60 | @GetMapping("/note/{id}") 61 | public ServerResponse getNote(@PathVariable("id") String id) { 62 | logger.debug("get note id is " + id); 63 | ServerResponse serverResponse = new ServerResponse(); 64 | Optional noteOptional = noteService.getNoteByNoteId(id); 65 | if (noteOptional.isPresent()) { 66 | serverResponse.setData(noteOptional.get()); 67 | } else { 68 | serverResponse.setStatus(404); 69 | serverResponse.setMsg("未找到"); 70 | } 71 | return serverResponse; 72 | } 73 | 74 | /** 75 | * 删除笔记 76 | * 77 | * @param id 笔记ID 78 | */ 79 | @DeleteMapping("/note/{id}") 80 | public void deleteNote(@PathVariable("id") String id) { 81 | logger.debug("delete note id is " + id); 82 | noteService.deleteByNoteBookId(id); 83 | } 84 | 85 | /** 86 | * 添加笔记 87 | * 88 | * @param noteBookId 笔记本ID 89 | * @param title 标题 90 | * @param content 内容 91 | * @param response {@link HttpServletResponse} 92 | */ 93 | @PostMapping("/note") 94 | public void addNote(String noteBookId, String title, String content, HttpServletResponse response) { 95 | try { 96 | if (noteService.addNote(noteBookId, title, content) == null) { 97 | logger.info("add note id error add result null"); 98 | response.setStatus(500); 99 | } 100 | } catch (IncorrectParameterException e) { 101 | logger.info("add note id error ", e); 102 | response.setStatus(400); 103 | } catch (NoSuchIdException e) { 104 | logger.info("add note id error ", e); 105 | response.setStatus(404); 106 | } 107 | } 108 | 109 | /** 110 | * 修改笔记 111 | * 112 | * @param id 笔记ID 113 | * @param note 笔记Map 114 | * @param response {@link HttpServletResponse} 115 | */ 116 | @PatchMapping("/note/{id}") 117 | public void upNote(@PathVariable("id") String id, @RequestBody Map note, HttpServletResponse response) { 118 | try { 119 | if (noteService.modifyNote(id, note.get("title"), note.get("content")) == null) { 120 | logger.info("up note error result is null"); 121 | response.setStatus(500); 122 | } 123 | } catch (IncorrectParameterException e) { 124 | logger.info("up note error ", e); 125 | response.setStatus(400); 126 | } catch (NoSuchIdException e) { 127 | logger.info("up note error ", e); 128 | response.setStatus(404); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.controller; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | import top.itning.yunshunotesr.entity.ServerResponse; 10 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 11 | import top.itning.yunshunotesr.exception.NoSuchIdException; 12 | import top.itning.yunshunotesr.exception.UserAlreadyExistsException; 13 | import top.itning.yunshunotesr.exception.UserDoesNotExistException; 14 | import top.itning.yunshunotesr.securtiy.SecurityUtils; 15 | import top.itning.yunshunotesr.service.UserService; 16 | 17 | import javax.mail.MessagingException; 18 | import javax.servlet.http.HttpServletResponse; 19 | 20 | /** 21 | * 用户控制层 22 | * 23 | * @author itning 24 | */ 25 | @RestController 26 | public class UserController { 27 | private static final Logger logger = LoggerFactory.getLogger(UserController.class); 28 | 29 | private final UserService userService; 30 | 31 | @Autowired 32 | public UserController(UserService userService) { 33 | this.userService = userService; 34 | } 35 | 36 | /** 37 | * 获取登录用户信息 38 | * 39 | * @return 用户信息 40 | */ 41 | @GetMapping("/getLoginUser") 42 | public ServerResponse getLoginUser() { 43 | return new ServerResponse(SecurityUtils.getUser()); 44 | } 45 | 46 | /** 47 | * 注册 48 | * 49 | * @return 注册消息 50 | */ 51 | @PostMapping("/registered") 52 | public ServerResponse registered(String name, String username, String password, String code) { 53 | ServerResponse serverResponse = new ServerResponse(); 54 | if (userService.registeredUser(name, username, password, code) == null) { 55 | serverResponse.setMsg("验证码不正确"); 56 | serverResponse.setStatus(400); 57 | } 58 | return serverResponse; 59 | } 60 | 61 | /** 62 | * 获取验证码 63 | * 64 | * @param response {@link HttpServletResponse} 65 | * @param email 邮箱 66 | */ 67 | @GetMapping("/get_code") 68 | public void getCode(HttpServletResponse response, String email) { 69 | try { 70 | userService.getCode(email); 71 | response.setStatus(202); 72 | } catch (MessagingException e) { 73 | logger.info("get code error ", e); 74 | response.setStatus(500); 75 | } catch (UserAlreadyExistsException e) { 76 | logger.info("get code error ", e); 77 | response.setStatus(406); 78 | } 79 | } 80 | 81 | /** 82 | * 获取忘记密码邮箱验证码 83 | * 84 | * @param email 邮箱 85 | * @param response {@link HttpServletResponse} 86 | * @return 密钥 87 | */ 88 | @GetMapping("/forget_get_code") 89 | public Integer forgetPasswordGetCode(String email, HttpServletResponse response) { 90 | try { 91 | return userService.forgetPasswordGetCode(email); 92 | } catch (MessagingException e) { 93 | logger.info("get code error ", e); 94 | response.setStatus(500); 95 | } catch (UserDoesNotExistException e) { 96 | logger.info("get code error ", e); 97 | response.setStatus(404); 98 | } 99 | return -1; 100 | } 101 | 102 | /** 103 | * 忘记密码 104 | * 105 | * @param code 验证码 106 | * @param vCode 密钥 107 | * @param password 密码 108 | * @return 被重置的用户 109 | */ 110 | @PostMapping("/forget_password") 111 | public ServerResponse forgetPassword(String code, String vCode, String password) { 112 | ServerResponse serverResponse = new ServerResponse(); 113 | try { 114 | serverResponse.setData(userService.forgetPassword(code, vCode, password)); 115 | } catch (IncorrectParameterException | UserDoesNotExistException e) { 116 | serverResponse.setStatus(404); 117 | serverResponse.setMsg(e.getMessage()); 118 | } 119 | return serverResponse; 120 | } 121 | 122 | /** 123 | * 更改用户信息 124 | * 125 | * @param id ID 126 | * @param name 昵称 127 | * @param password 密码 128 | * @return 被修改的用户信息 129 | */ 130 | @PostMapping("/change_user_profile") 131 | public ServerResponse changeUserProfile(String id, String name, String password) { 132 | ServerResponse serverResponse = new ServerResponse(); 133 | try { 134 | serverResponse.setData(userService.changeUserProfile(id, name, password)); 135 | } catch (NoSuchIdException e) { 136 | serverResponse.setMsg(e.getMessage()); 137 | serverResponse.setStatus(404); 138 | } 139 | return serverResponse; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/dao/HbaseRepository.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.dao; 2 | 3 | import org.apache.hadoop.conf.Configuration; 4 | import org.apache.hadoop.hbase.CompareOperator; 5 | import org.apache.hadoop.hbase.HBaseConfiguration; 6 | import org.apache.hadoop.hbase.TableName; 7 | import org.apache.hadoop.hbase.client.*; 8 | import org.apache.hadoop.hbase.filter.RegexStringComparator; 9 | import org.apache.hadoop.hbase.filter.RowFilter; 10 | import org.apache.hadoop.hbase.util.Bytes; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.stereotype.Repository; 14 | import top.itning.yunshunotesr.entity.Note; 15 | import top.itning.yunshunotesr.entity.NoteBook; 16 | 17 | import java.io.IOException; 18 | import java.util.ArrayList; 19 | import java.util.Date; 20 | import java.util.List; 21 | import java.util.Optional; 22 | import java.util.stream.Collectors; 23 | 24 | /** 25 | * 对Hbase的CRUD操作 26 | * 27 | * @author itning 28 | */ 29 | @Repository 30 | public class HbaseRepository { 31 | private static final Logger logger = LoggerFactory.getLogger(HbaseRepository.class); 32 | 33 | /** 34 | * Hbase 表对象 35 | */ 36 | private static Table table; 37 | /** 38 | * 表名 39 | */ 40 | private static final String TABLE_NAME = "note"; 41 | /** 42 | * 列族名 43 | */ 44 | private static final String FAMILY_NAME = "shu"; 45 | 46 | static { 47 | System.setProperty("hadoop.home.dir", "G:\\winutils\\hadoop-2.8.3"); 48 | Configuration config = HBaseConfiguration.create(); 49 | config.set("hbase.zookeeper.quorum", "node3:2181"); 50 | try { 51 | logger.info("start build connection..."); 52 | Connection connection = ConnectionFactory.createConnection(config); 53 | Admin admin = connection.getAdmin(); 54 | //检查表存在 55 | if (admin.tableExists(TableName.valueOf(TABLE_NAME))) { 56 | logger.info("the table of name " + TABLE_NAME + " already exists"); 57 | table = connection.getTable(TableName.valueOf(TABLE_NAME.getBytes())); 58 | } else { 59 | logger.info("create table..."); 60 | TableDescriptor descriptor = TableDescriptorBuilder.newBuilder(TableName.valueOf(TABLE_NAME)) 61 | .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(FAMILY_NAME.getBytes()).build()) 62 | .build(); 63 | admin.createTable(descriptor); 64 | table = connection.getTable(TableName.valueOf(TABLE_NAME.getBytes())); 65 | } 66 | } catch (IOException e) { 67 | logger.error("init hbase connection error ", e); 68 | } 69 | } 70 | 71 | /** 72 | * 根据rowKey查找笔记 73 | * 74 | * @param rowKey 行键 75 | * @return 查找到的笔记实体 76 | * @throws IOException IOException 77 | */ 78 | public Optional findOne(String rowKey) throws IOException { 79 | Result result = table.get(new Get(rowKey.getBytes())); 80 | if (result.size() == 0) { 81 | logger.debug("the rowkey " + rowKey + " does not exist"); 82 | return Optional.empty(); 83 | } 84 | Note note = new Note(); 85 | note.setId(rowKey); 86 | note.setGmtCreate(new Date(Bytes.toLong(result.getValue(FAMILY_NAME.getBytes(), "gmt_create".getBytes())))); 87 | note.setGmtModified(new Date(Bytes.toLong(result.getValue(FAMILY_NAME.getBytes(), "gmt_modified".getBytes())))); 88 | note.setTrash(Bytes.toBoolean(result.getValue(FAMILY_NAME.getBytes(), "trash".getBytes()))); 89 | note.setTitle(Bytes.toString(result.getValue(FAMILY_NAME.getBytes(), "title".getBytes()))); 90 | note.setContent(Bytes.toString(result.getValue(FAMILY_NAME.getBytes(), "content".getBytes()))); 91 | return Optional.of(note); 92 | } 93 | 94 | /** 95 | * 根据笔记本ID,查找所有以该ID开头的笔记 96 | * 97 | * @param noteBookId 笔记本ID 98 | * @return 笔记集合 99 | * @throws IOException IOException 100 | */ 101 | public Optional> findAll(String noteBookId) throws IOException { 102 | RowFilter filter = new RowFilter(CompareOperator.EQUAL, new RegexStringComparator("^" + noteBookId)); 103 | Scan scan = new Scan(); 104 | scan.setFilter(filter); 105 | ResultScanner scanner = table.getScanner(scan); 106 | List noteList = new ArrayList<>(); 107 | logger.debug("the note list size is " + noteList.size()); 108 | scanner.forEach(result -> { 109 | Note note = new Note(); 110 | note.setId(Bytes.toString(result.getRow())); 111 | note.setGmtCreate(new Date(Bytes.toLong(result.getValue(FAMILY_NAME.getBytes(), "gmt_create".getBytes())))); 112 | note.setGmtModified(new Date(Bytes.toLong(result.getValue(FAMILY_NAME.getBytes(), "gmt_modified".getBytes())))); 113 | note.setTrash(Bytes.toBoolean(result.getValue(FAMILY_NAME.getBytes(), "trash".getBytes()))); 114 | note.setTitle(Bytes.toString(result.getValue(FAMILY_NAME.getBytes(), "title".getBytes()))); 115 | note.setContent(Bytes.toString(result.getValue(FAMILY_NAME.getBytes(), "content".getBytes()))); 116 | noteList.add(note); 117 | }); 118 | return Optional.of(noteList); 119 | } 120 | 121 | /** 122 | * 保存或覆盖笔记 123 | * 124 | * @param note 笔记实体 125 | * @throws IOException IOException 126 | */ 127 | public Note save(Note note) throws IOException { 128 | Put put = new Put(note.getId().getBytes()); 129 | put.addColumn(FAMILY_NAME.getBytes(), "gmt_create".getBytes(), Bytes.toBytes(note.getGmtCreate().getTime())); 130 | put.addColumn(FAMILY_NAME.getBytes(), "gmt_modified".getBytes(), Bytes.toBytes(note.getGmtModified().getTime())); 131 | put.addColumn(FAMILY_NAME.getBytes(), "trash".getBytes(), Bytes.toBytes(note.isTrash())); 132 | put.addColumn(FAMILY_NAME.getBytes(), "title".getBytes(), Bytes.toBytes(note.getTitle())); 133 | put.addColumn(FAMILY_NAME.getBytes(), "content".getBytes(), Bytes.toBytes(note.getContent())); 134 | table.put(put); 135 | return note; 136 | } 137 | 138 | /** 139 | * 删除笔记 140 | * 141 | * @param rowKey 行键 142 | * @throws IOException IOException 143 | */ 144 | public void delete(String rowKey) throws IOException { 145 | Delete delete = new Delete(rowKey.getBytes()); 146 | table.delete(delete); 147 | } 148 | 149 | /** 150 | * 批量删除笔记(删除笔记本时) 151 | * 152 | * @param noteBookId 笔记本ID 153 | */ 154 | public void batchDelete(String noteBookId) throws IOException { 155 | RowFilter filter = new RowFilter(CompareOperator.EQUAL, new RegexStringComparator("^" + noteBookId)); 156 | Scan scan = new Scan(); 157 | scan.setFilter(filter); 158 | ResultScanner scanner = table.getScanner(scan); 159 | List noteRowKey = new ArrayList<>(); 160 | scanner.forEach(result -> noteRowKey.add(result.getRow())); 161 | table.delete(noteRowKey.stream().map(Delete::new).collect(Collectors.toList())); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/dao/NoteBookDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.yunshunotesr.entity.Note; 5 | import top.itning.yunshunotesr.entity.NoteBook; 6 | import top.itning.yunshunotesr.entity.User; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * NoteBook Dao interface 12 | * 13 | * @author itning 14 | */ 15 | public interface NoteBookDao extends JpaRepository { 16 | /** 17 | * 查找用户的所有笔记本 18 | * 19 | * @param user 用户 20 | * @return 笔记本集合 21 | */ 22 | List findAllByUser(User user); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.dao; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import top.itning.yunshunotesr.entity.User; 5 | 6 | /** 7 | * User Dao interface 8 | * 9 | * @author itning 10 | */ 11 | public interface UserDao extends JpaRepository { 12 | /** 13 | * 根据用户名查找用户 14 | * 15 | * @param username 用户名 16 | * @return 用户实体 17 | */ 18 | User findByUsername(String username); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/entity/Note.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * 笔记实体 8 | * 9 | * @author itning 10 | */ 11 | public class Note implements Serializable { 12 | /** 13 | * 笔记唯一标识ID 14 | */ 15 | private String id; 16 | /** 17 | * 创建时间 18 | */ 19 | private Date gmtCreate; 20 | /** 21 | * 修改时间 22 | */ 23 | private Date gmtModified; 24 | /** 25 | * 是否为废纸篓中的笔记 26 | */ 27 | private boolean trash; 28 | /** 29 | * 标题 30 | */ 31 | private String title; 32 | /** 33 | * 内容 34 | */ 35 | private String content; 36 | 37 | public String getId() { 38 | return id; 39 | } 40 | 41 | public void setId(String id) { 42 | this.id = id; 43 | } 44 | 45 | public Date getGmtCreate() { 46 | return gmtCreate; 47 | } 48 | 49 | public void setGmtCreate(Date gmtCreate) { 50 | this.gmtCreate = gmtCreate; 51 | } 52 | 53 | public Date getGmtModified() { 54 | return gmtModified; 55 | } 56 | 57 | public void setGmtModified(Date gmtModified) { 58 | this.gmtModified = gmtModified; 59 | } 60 | 61 | public boolean isTrash() { 62 | return trash; 63 | } 64 | 65 | public void setTrash(boolean trash) { 66 | this.trash = trash; 67 | } 68 | 69 | public String getTitle() { 70 | return title; 71 | } 72 | 73 | public void setTitle(String title) { 74 | this.title = title; 75 | } 76 | 77 | public String getContent() { 78 | return content; 79 | } 80 | 81 | public void setContent(String content) { 82 | this.content = content; 83 | } 84 | 85 | @Override 86 | public String toString() { 87 | return "Note{" + 88 | "id='" + id + '\'' + 89 | ", gmtCreate=" + gmtCreate + 90 | ", gmtModified=" + gmtModified + 91 | ", trash=" + trash + 92 | ", title='" + title + '\'' + 93 | ", content='" + content + '\'' + 94 | '}'; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/entity/NoteBook.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.entity; 2 | 3 | import org.hibernate.annotations.GenericGenerator; 4 | 5 | import javax.persistence.*; 6 | import java.io.Serializable; 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | /** 11 | * 笔记本实体 12 | * 13 | * @author itning 14 | */ 15 | @Entity(name = "note_book") 16 | public class NoteBook implements Serializable { 17 | /** 18 | * 笔记本标识ID 19 | */ 20 | @Id 21 | @Column(name = "b_id", length = 36) 22 | @GeneratedValue(generator = "noteBookIdGenerator") 23 | @GenericGenerator(name = "noteBookIdGenerator", strategy = "org.hibernate.id.UUIDGenerator") 24 | private String id; 25 | /** 26 | * 创建时间 27 | */ 28 | @Column(name = "gmt_create", nullable = false) 29 | private Date gmtCreate; 30 | /** 31 | * 修改时间 32 | */ 33 | @Column(name = "gmt_modified", nullable = false) 34 | private Date gmtModified; 35 | /** 36 | * 笔记本名称 37 | */ 38 | @Column(name = "b_name", nullable = false) 39 | private String name; 40 | /** 41 | * 该笔记本所属用户 42 | */ 43 | @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) 44 | @JoinColumn(name = "u_id", referencedColumnName = "u_id", nullable = false) 45 | private User user; 46 | 47 | public String getId() { 48 | return id; 49 | } 50 | 51 | public void setId(String id) { 52 | this.id = id; 53 | } 54 | 55 | public Date getGmtCreate() { 56 | return gmtCreate; 57 | } 58 | 59 | public void setGmtCreate(Date gmtCreate) { 60 | this.gmtCreate = gmtCreate; 61 | } 62 | 63 | public Date getGmtModified() { 64 | return gmtModified; 65 | } 66 | 67 | public void setGmtModified(Date gmtModified) { 68 | this.gmtModified = gmtModified; 69 | } 70 | 71 | public String getName() { 72 | return name; 73 | } 74 | 75 | public void setName(String name) { 76 | this.name = name; 77 | } 78 | 79 | public User getUser() { 80 | return user; 81 | } 82 | 83 | public void setUser(User user) { 84 | this.user = user; 85 | } 86 | 87 | @Override 88 | public String toString() { 89 | return "NoteBook{" + 90 | "id='" + id + '\'' + 91 | ", gmtCreate=" + gmtCreate + 92 | ", gmtModified=" + gmtModified + 93 | ", name='" + name + '\'' + 94 | ", user=" + user + 95 | '}'; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/entity/ServerResponse.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * 服务器响应 9 | * 10 | * @author itning 11 | */ 12 | public class ServerResponse implements Serializable { 13 | /** 14 | * 状态码 15 | */ 16 | private int status; 17 | /** 18 | * 消息 19 | */ 20 | private String msg; 21 | /** 22 | * 数据集合 23 | */ 24 | private List dataList; 25 | /** 26 | * 数据 27 | */ 28 | private Object data; 29 | 30 | public ServerResponse() { 31 | this.status = 200; 32 | this.msg = "OK"; 33 | this.data = ""; 34 | this.dataList = new ArrayList<>(); 35 | } 36 | 37 | public ServerResponse(int status, String msg) { 38 | this.status = status; 39 | this.msg = msg; 40 | this.data = ""; 41 | this.dataList = new ArrayList<>(); 42 | } 43 | 44 | public ServerResponse(Object data) { 45 | this.status = 200; 46 | this.msg = "OK"; 47 | this.dataList = new ArrayList<>(); 48 | this.data = data; 49 | } 50 | 51 | public ServerResponse(List dataList) { 52 | this.status = 200; 53 | this.msg = "OK"; 54 | this.data = ""; 55 | this.dataList = dataList; 56 | } 57 | 58 | public ServerResponse(int status, String msg, Object data) { 59 | this.status = status; 60 | this.msg = msg; 61 | this.data = data; 62 | this.dataList = new ArrayList<>(); 63 | } 64 | 65 | public ServerResponse(int status, String msg, List dataList) { 66 | this.status = status; 67 | this.msg = msg; 68 | this.data = ""; 69 | this.dataList = dataList; 70 | } 71 | 72 | public ServerResponse(int status, String msg, List dataList, Object data) { 73 | this.status = status; 74 | this.msg = msg; 75 | this.dataList = dataList; 76 | this.data = data; 77 | } 78 | 79 | public int getStatus() { 80 | return status; 81 | } 82 | 83 | public void setStatus(int status) { 84 | this.status = status; 85 | } 86 | 87 | public String getMsg() { 88 | return msg; 89 | } 90 | 91 | public void setMsg(String msg) { 92 | this.msg = msg; 93 | } 94 | 95 | public List getDataList() { 96 | return dataList; 97 | } 98 | 99 | public void setDataList(List dataList) { 100 | this.dataList = dataList; 101 | } 102 | 103 | public Object getData() { 104 | return data; 105 | } 106 | 107 | public void setData(Object data) { 108 | this.data = data; 109 | } 110 | 111 | @Override 112 | public String toString() { 113 | return "ServerResponse{" + 114 | "status=" + status + 115 | ", msg='" + msg + '\'' + 116 | ", dataList=" + dataList + 117 | ", data=" + data + 118 | '}'; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/entity/User.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.entity; 2 | 3 | 4 | import org.hibernate.annotations.GenericGenerator; 5 | 6 | import javax.persistence.*; 7 | import java.io.Serializable; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | /** 12 | * 用户实体 13 | * 14 | * @author itning 15 | */ 16 | @Entity(name = "user") 17 | public class User implements Serializable { 18 | /** 19 | * 用户唯一标识ID 20 | */ 21 | @Id 22 | @Column(name = "u_id", length = 36) 23 | @GeneratedValue(generator = "userIdGenerator") 24 | @GenericGenerator(name = "userIdGenerator", strategy = "org.hibernate.id.UUIDGenerator") 25 | private String id; 26 | /** 27 | * 创建时间 28 | */ 29 | @Column(name = "gmt_create", nullable = false) 30 | private Date gmtCreate; 31 | /** 32 | * 修改时间 33 | */ 34 | @Column(name = "gmt_modified", nullable = false) 35 | private Date gmtModified; 36 | /** 37 | * 用户名 38 | */ 39 | @Column(name = "username", nullable = false) 40 | private String username; 41 | /** 42 | * 密码 43 | */ 44 | @Column(name = "password", nullable = false) 45 | private String password; 46 | /** 47 | * 昵称 48 | */ 49 | @Column(name = "u_name", nullable = false) 50 | private String name; 51 | 52 | public String getId() { 53 | return id; 54 | } 55 | 56 | public void setId(String id) { 57 | this.id = id; 58 | } 59 | 60 | public Date getGmtCreate() { 61 | return gmtCreate; 62 | } 63 | 64 | public void setGmtCreate(Date gmtCreate) { 65 | this.gmtCreate = gmtCreate; 66 | } 67 | 68 | public Date getGmtModified() { 69 | return gmtModified; 70 | } 71 | 72 | public void setGmtModified(Date gmtModified) { 73 | this.gmtModified = gmtModified; 74 | } 75 | 76 | public String getUsername() { 77 | return username; 78 | } 79 | 80 | public void setUsername(String username) { 81 | this.username = username; 82 | } 83 | 84 | public String getPassword() { 85 | return password; 86 | } 87 | 88 | public void setPassword(String password) { 89 | this.password = password; 90 | } 91 | 92 | public String getName() { 93 | return name; 94 | } 95 | 96 | public void setName(String name) { 97 | this.name = name; 98 | } 99 | 100 | @Override 101 | public String toString() { 102 | return "User{" + 103 | "id='" + id + '\'' + 104 | ", gmtCreate=" + gmtCreate + 105 | ", gmtModified=" + gmtModified + 106 | ", username='" + username + '\'' + 107 | ", password='" + password + '\'' + 108 | ", name='" + name + '\'' + 109 | '}'; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/exception/ExceptionResolver.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.exception; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.web.bind.annotation.ControllerAdvice; 8 | import org.springframework.web.bind.annotation.ExceptionHandler; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import org.springframework.web.bind.annotation.ResponseStatus; 11 | import org.springframework.web.servlet.DispatcherServlet; 12 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 13 | import top.itning.yunshunotesr.entity.ServerResponse; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | 17 | /** 18 | * @author itning 19 | */ 20 | @EnableWebMvc 21 | @ControllerAdvice 22 | public class ExceptionResolver { 23 | private static final Logger logger = LoggerFactory.getLogger(ExceptionResolver.class); 24 | 25 | @Bean 26 | DispatcherServlet dispatcherServlet() { 27 | DispatcherServlet ds = new DispatcherServlet(); 28 | ds.setThrowExceptionIfNoHandlerFound(true); 29 | return ds; 30 | } 31 | 32 | @ExceptionHandler 33 | @ResponseStatus(value = HttpStatus.NOT_FOUND) 34 | @ResponseBody 35 | public ServerResponse defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { 36 | return new ServerResponse(404, e.getMessage()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/exception/IncorrectParameterException.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.exception; 2 | 3 | /** 4 | * 参数不正确 5 | * 6 | * @author itning 7 | */ 8 | public class IncorrectParameterException extends Exception { 9 | public IncorrectParameterException(String msg) { 10 | super(msg); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/exception/NoSuchIdException.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.exception; 2 | 3 | /** 4 | * ID不存在 5 | * 6 | * @author itning 7 | */ 8 | public class NoSuchIdException extends Exception { 9 | public NoSuchIdException(String msg) { 10 | super(msg); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/exception/UserAlreadyExistsException.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.exception; 2 | 3 | /** 4 | * 用户已经存在 5 | * 6 | * @author itning 7 | */ 8 | public class UserAlreadyExistsException extends Exception { 9 | public UserAlreadyExistsException(String message) { 10 | super(message); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/exception/UserDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.exception; 2 | 3 | /** 4 | * 用户不存在 5 | * 6 | * @author itning 7 | */ 8 | public class UserDoesNotExistException extends Exception { 9 | public UserDoesNotExistException(String message) { 10 | super(message); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/securtiy/SecurityFilter.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.securtiy; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.core.annotation.Order; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.stereotype.Component; 7 | import top.itning.yunshunotesr.dao.UserDao; 8 | import top.itning.yunshunotesr.entity.User; 9 | 10 | import javax.servlet.*; 11 | import javax.servlet.annotation.WebFilter; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import javax.servlet.http.HttpSession; 15 | import java.io.IOException; 16 | import java.util.Optional; 17 | 18 | /** 19 | * 安全过滤器 20 | * 21 | * @author itning 22 | */ 23 | @Component 24 | @Order(1) 25 | @WebFilter(filterName = "SecurityFilter", urlPatterns = "/*") 26 | public class SecurityFilter implements Filter { 27 | private static final String LOGIN_URL = "/login"; 28 | private static final String LOGOUT_URL = "/logout"; 29 | private static final String USERNAME_PARAMETER = "username"; 30 | private static final String PASSWORD_PARAMETER = "password"; 31 | private static final String LOGIN_METHOD = "POST"; 32 | private static final String USER_SESSION_KEY = "user"; 33 | private static final String[] RELEASE_ARRAY = {"/registered", "/get_code", "/forget_get_code", "/forget_password"}; 34 | 35 | private final UserDao userDao; 36 | 37 | @Autowired 38 | public SecurityFilter(UserDao userDao) { 39 | this.userDao = userDao; 40 | } 41 | 42 | @Override 43 | public void init(FilterConfig filterConfig) { 44 | 45 | } 46 | 47 | @Override 48 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 49 | HttpServletResponse resp = (HttpServletResponse) response; 50 | HttpServletRequest req = (HttpServletRequest) request; 51 | if ("OPTIONS".equals(req.getMethod())) { 52 | resp.setHeader("Access-Control-Allow-Credentials", "true"); 53 | resp.setHeader("Access-Control-Allow-Origin", "http://localhost:8081"); 54 | resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT,PATCH"); 55 | resp.setHeader("Access-Control-Allow-Headers", req.getHeader("Access-Control-Request-Headers")); 56 | return; 57 | } 58 | for (String release : RELEASE_ARRAY) { 59 | if (release.equals(req.getServletPath())) { 60 | chain.doFilter(request, response); 61 | return; 62 | } 63 | } 64 | if (LOGIN_URL.equals(req.getServletPath())) { 65 | if (!LOGIN_METHOD.equals(req.getMethod())) { 66 | SecurityUtils.setResponseMsg("不支持该方法", HttpStatus.METHOD_NOT_ALLOWED.value(), 405, resp); 67 | return; 68 | } 69 | String username = req.getParameter(USERNAME_PARAMETER); 70 | String password = req.getParameter(PASSWORD_PARAMETER); 71 | Optional user = this.loadUserByUserName(username); 72 | if (!user.isPresent()) { 73 | SecurityUtils.setResponseMsg("用户不存在", HttpStatus.OK.value(), 404, resp); 74 | } else { 75 | User dbUser = user.get(); 76 | if (dbUser.getPassword().equals(password)) { 77 | HttpSession session = req.getSession(); 78 | session.setAttribute(USER_SESSION_KEY, dbUser); 79 | SecurityUtils.setUser(session.getId(), dbUser); 80 | SecurityUtils.setResponseMsg("登陆成功", dbUser, HttpStatus.OK.value(), 200, resp); 81 | } else { 82 | SecurityUtils.setResponseMsg("密码错误", HttpStatus.OK.value(), 404, resp); 83 | } 84 | } 85 | } else if (LOGOUT_URL.equals(req.getServletPath())) { 86 | HttpSession session = req.getSession(); 87 | SecurityUtils.deleteUser(session.getId()); 88 | session.invalidate(); 89 | SecurityUtils.setResponseMsg("注销成功", HttpStatus.OK.value(), 200, resp); 90 | } else { 91 | //检查Session是否存在 92 | if (req.getSession().getAttribute(USER_SESSION_KEY) != null) { 93 | chain.doFilter(request, response); 94 | } else { 95 | SecurityUtils.setResponseMsg("请先登陆", HttpStatus.UNAUTHORIZED.value(), 401, resp); 96 | } 97 | } 98 | } 99 | 100 | @Override 101 | public void destroy() { 102 | 103 | } 104 | 105 | private Optional loadUserByUserName(String username) { 106 | return Optional.ofNullable(userDao.findByUsername(username)); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/securtiy/SecurityUtils.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.securtiy; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.web.context.request.RequestContextHolder; 5 | import top.itning.yunshunotesr.entity.ServerResponse; 6 | import top.itning.yunshunotesr.entity.User; 7 | 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | import java.util.Objects; 13 | 14 | /** 15 | * 安全工具 16 | * 17 | * @author itning 18 | */ 19 | public class SecurityUtils { 20 | /** 21 | * ObjectMapper 22 | */ 23 | private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 24 | /** 25 | * 用于存储登陆用户 26 | */ 27 | private static final Map USER_MAP = new HashMap<>(16); 28 | 29 | private SecurityUtils() { 30 | } 31 | 32 | /** 33 | * 设置响应消息 34 | * 35 | * @param msg 消息 36 | * @param code 状态码 37 | * @param resp {@link HttpServletResponse} 38 | * @throws IOException IOException 39 | */ 40 | static void setResponseMsg(String msg, int code, int status, HttpServletResponse resp) throws IOException { 41 | resp.setHeader("Access-Control-Allow-Credentials", "true"); 42 | resp.setHeader("Access-Control-Allow-Origin", "http://localhost:8081"); 43 | resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT,PATCH"); 44 | resp.setHeader("Access-Control-Allow-Headers", "*"); 45 | resp.setStatus(code); 46 | resp.setCharacterEncoding("utf-8"); 47 | resp.setContentType("application/json; charset=utf-8"); 48 | ServerResponse serverResponse = new ServerResponse(status, msg); 49 | String s = OBJECT_MAPPER.writeValueAsString(serverResponse); 50 | resp.getWriter().write(s); 51 | } 52 | 53 | static void setResponseMsg(String msg, Object data, int code, int status, HttpServletResponse resp) throws IOException { 54 | resp.setHeader("Access-Control-Allow-Credentials", "true"); 55 | resp.setHeader("Access-Control-Allow-Origin", "http://localhost:8081"); 56 | resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT"); 57 | resp.setHeader("Access-Control-Allow-Headers", "*"); 58 | resp.setStatus(code); 59 | resp.setCharacterEncoding("utf-8"); 60 | resp.setContentType("application/json; charset=utf-8"); 61 | ServerResponse serverResponse = new ServerResponse(status, msg, data); 62 | String s = OBJECT_MAPPER.writeValueAsString(serverResponse); 63 | resp.getWriter().write(s); 64 | } 65 | 66 | /** 67 | * 将登陆用户实体存入MAP 68 | * 69 | * @param sessionId session id 70 | * @param user 用户实体 71 | */ 72 | static void setUser(String sessionId, User user) { 73 | USER_MAP.put(sessionId, user); 74 | } 75 | 76 | /** 77 | * 在MAP中删除用户 78 | * 79 | * @param sessionId session id 80 | */ 81 | static void deleteUser(String sessionId) { 82 | USER_MAP.remove(sessionId); 83 | } 84 | 85 | /** 86 | * 获取当前登录用户 87 | * 88 | * @return 用户实体 89 | */ 90 | public static User getUser() { 91 | return USER_MAP.get(Objects.requireNonNull(RequestContextHolder.getRequestAttributes()).getSessionId()); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/securtiy/SessionListener.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.securtiy; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import javax.servlet.annotation.WebListener; 7 | import javax.servlet.http.HttpSessionEvent; 8 | import javax.servlet.http.HttpSessionListener; 9 | 10 | 11 | /** 12 | * Session事件监听 13 | * 14 | * @author itning 15 | */ 16 | @WebListener 17 | public class SessionListener implements HttpSessionListener { 18 | private static final Logger logger = LoggerFactory.getLogger(SessionListener.class); 19 | 20 | @Override 21 | public void sessionCreated(HttpSessionEvent se) { 22 | logger.info("sessionCreated...."); 23 | } 24 | 25 | @Override 26 | public void sessionDestroyed(HttpSessionEvent se) { 27 | logger.info("sessionDestroyed...."); 28 | SecurityUtils.deleteUser(se.getSession().getId()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/service/NoteBookService.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.service; 2 | 3 | import top.itning.yunshunotesr.entity.NoteBook; 4 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 5 | import top.itning.yunshunotesr.exception.NoSuchIdException; 6 | 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | /** 11 | * 笔记本服务层接口 12 | * 13 | * @author itning 14 | */ 15 | public interface NoteBookService { 16 | /** 17 | * 获取登陆用户的所有笔记本集合 18 | * 19 | * @return 笔记本集合 20 | */ 21 | Optional> getAllNoteBook(); 22 | 23 | /** 24 | * 根据笔记本ID删除指定笔记本 25 | * 26 | * @param id 笔记本ID 27 | * @throws NoSuchIdException 当指定的ID不存在时 28 | */ 29 | void deleteNoteBookById(String id) throws NoSuchIdException; 30 | 31 | /** 32 | * 根据笔记本ID修改笔记本名称 33 | * 34 | * @param id 笔记本ID 35 | * @param name 新的笔记本名称 36 | * @return 被修改的实体 37 | * @throws NoSuchIdException 当指定的ID不存在时 38 | * @throws IncorrectParameterException 笔记本名称为null或空字符串时 39 | */ 40 | NoteBook modifyNoteBookName(String id, String name) throws NoSuchIdException, IncorrectParameterException; 41 | 42 | /** 43 | * 新建笔记本 44 | * 45 | * @param name 笔记本名称 46 | * @return 被保存的实体 47 | * @throws IncorrectParameterException 笔记本名称为null或空字符串时 48 | */ 49 | NoteBook addNoteBook(String name) throws IncorrectParameterException; 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/service/NoteService.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.service; 2 | 3 | import top.itning.yunshunotesr.entity.Note; 4 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 5 | import top.itning.yunshunotesr.exception.NoSuchIdException; 6 | 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | /** 11 | * 笔记服务层接口 12 | * 13 | * @author itning 14 | */ 15 | public interface NoteService { 16 | /** 17 | * 获取某笔记本下的所有笔记 18 | * 19 | * @param noteBookId 笔记本Id 20 | * @return 笔记集合 21 | */ 22 | Optional> getAllNotes(String noteBookId); 23 | 24 | /** 25 | * 根基笔记Id获取笔记 26 | * 27 | * @param noteId 笔记Id 28 | * @return 笔记实体 29 | */ 30 | Optional getNoteByNoteId(String noteId); 31 | 32 | /** 33 | * 添加笔记 34 | * 35 | * @param noteBookId 笔记本ID 36 | * @param title 笔记标题 37 | * @param content 笔记内容 38 | * @return 被添加的笔记实体 39 | * @throws IncorrectParameterException 参数不正确 40 | * @throws NoSuchIdException 笔记本ID不存在 41 | */ 42 | Note addNote(String noteBookId, String title, String content) throws IncorrectParameterException, NoSuchIdException; 43 | 44 | /** 45 | * 修改笔记 46 | * 47 | * @param id 笔记ID 48 | * @param title 笔记标题 49 | * @param content 笔记内容 50 | * @return 被修改的笔记实体 51 | * @throws IncorrectParameterException 参数不正确 52 | * @throws NoSuchIdException 笔记ID不存在 53 | */ 54 | Note modifyNote(String id, String title, String content) throws IncorrectParameterException, NoSuchIdException; 55 | 56 | /** 57 | * 根据笔记Id删除笔记 58 | * 59 | * @param id 笔记Id 60 | */ 61 | void deleteByNoteId(String id); 62 | 63 | /** 64 | * 删除笔记本下的所有笔记 65 | * 66 | * @param noteBookId 笔记本Id 67 | */ 68 | void deleteByNoteBookId(String noteBookId); 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/service/UserService.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.service; 2 | 3 | import top.itning.yunshunotesr.entity.User; 4 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 5 | import top.itning.yunshunotesr.exception.NoSuchIdException; 6 | import top.itning.yunshunotesr.exception.UserAlreadyExistsException; 7 | import top.itning.yunshunotesr.exception.UserDoesNotExistException; 8 | 9 | import javax.mail.MessagingException; 10 | 11 | /** 12 | * 用户服务接口 13 | * 14 | * @author itning 15 | */ 16 | public interface UserService { 17 | /** 18 | * 注册用户 19 | * 20 | * @param name 昵称 21 | * @param username 用户名 22 | * @param password 密码 23 | * @param code 验证码 24 | * @return 注册用户信息 25 | */ 26 | User registeredUser(String name, String username, String password, String code); 27 | 28 | /** 29 | * 获取验证码 30 | * 31 | * @param email 邮箱 32 | * @throws MessagingException MessagingException 33 | * @throws UserAlreadyExistsException 用户已经存在 34 | */ 35 | void getCode(String email) throws MessagingException, UserAlreadyExistsException; 36 | 37 | /** 38 | * 获取重置密码验证码 39 | * 40 | * @param email 邮箱 41 | * @return 重置密钥 42 | * @throws MessagingException MessagingException 43 | * @throws UserDoesNotExistException 用户不存在 44 | */ 45 | Integer forgetPasswordGetCode(String email) throws MessagingException, UserDoesNotExistException; 46 | 47 | /** 48 | * 忘记密码 49 | * 50 | * @param code 验证码 51 | * @param vCode 密钥 52 | * @param password 新密码 53 | * @return 被重置密码的用户 54 | * @throws IncorrectParameterException 参数不正确 55 | * @throws UserDoesNotExistException 用户不存在 56 | */ 57 | User forgetPassword(String code, String vCode, String password) throws IncorrectParameterException, UserDoesNotExistException; 58 | 59 | /** 60 | * 更改用户信息 61 | * 62 | * @param id 用户ID 63 | * @param name 用户名 64 | * @param password 密码 65 | * @return 被更改的用户实体 66 | * @throws NoSuchIdException ID不存在 67 | */ 68 | User changeUserProfile(String id, String name, String password) throws NoSuchIdException; 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/service/impl/HbaseNoteServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.service.impl; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import top.itning.yunshunotesr.dao.HbaseRepository; 9 | import top.itning.yunshunotesr.dao.NoteBookDao; 10 | import top.itning.yunshunotesr.entity.Note; 11 | import top.itning.yunshunotesr.entity.NoteBook; 12 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 13 | import top.itning.yunshunotesr.exception.NoSuchIdException; 14 | import top.itning.yunshunotesr.service.NoteService; 15 | 16 | import javax.transaction.Transactional; 17 | import java.io.IOException; 18 | import java.util.Date; 19 | import java.util.List; 20 | import java.util.Optional; 21 | import java.util.UUID; 22 | 23 | /** 24 | * 笔记服务层实现类(HBASE) 25 | * 26 | * @author itning 27 | */ 28 | @Service 29 | @Transactional(rollbackOn = Exception.class) 30 | public class HbaseNoteServiceImpl implements NoteService { 31 | private static final Logger logger = LoggerFactory.getLogger(NoteBookServiceImpl.class); 32 | 33 | private final HbaseRepository hbaseRepository; 34 | 35 | private final NoteBookDao noteBookDao; 36 | 37 | @Autowired 38 | public HbaseNoteServiceImpl(HbaseRepository hbaseRepository, NoteBookDao noteBookDao) { 39 | this.hbaseRepository = hbaseRepository; 40 | this.noteBookDao = noteBookDao; 41 | } 42 | 43 | @Override 44 | public Optional> getAllNotes(String noteBookId) { 45 | try { 46 | return hbaseRepository.findAll(noteBookId); 47 | } catch (IOException e) { 48 | logger.info("get all notes error ", e); 49 | return Optional.empty(); 50 | } 51 | } 52 | 53 | @Override 54 | public Optional getNoteByNoteId(String noteId) { 55 | try { 56 | return hbaseRepository.findOne(noteId); 57 | } catch (IOException e) { 58 | logger.info("get note error ", e); 59 | return Optional.empty(); 60 | } 61 | 62 | } 63 | 64 | @Override 65 | public Note addNote(String noteBookId, String title, String content) throws IncorrectParameterException, NoSuchIdException { 66 | if (StringUtils.isAnyBlank(noteBookId, title, content)) { 67 | logger.info("add note parameter exception"); 68 | throw new IncorrectParameterException("参数不正确"); 69 | } 70 | Note note = new Note(); 71 | NoteBook noteBook = noteBookDao.findById(noteBookId).orElseThrow(() -> new NoSuchIdException("Id不存在")); 72 | //ID组成: 笔记本ID+笔记ID 73 | note.setId(noteBook.getId() + UUID.randomUUID().toString()); 74 | note.setTitle(title); 75 | note.setContent(content); 76 | note.setGmtCreate(new Date()); 77 | note.setGmtModified(new Date()); 78 | note.setTrash(false); 79 | try { 80 | return hbaseRepository.save(note); 81 | } catch (IOException e) { 82 | logger.info("save note error ", e); 83 | return null; 84 | } 85 | } 86 | 87 | @Override 88 | public Note modifyNote(String id, String title, String content) throws IncorrectParameterException, NoSuchIdException { 89 | if (StringUtils.isAnyBlank(id, title, content)) { 90 | logger.info("add note parameter exception"); 91 | throw new IncorrectParameterException("参数不正确"); 92 | } 93 | try { 94 | Optional noteOptional = hbaseRepository.findOne(id); 95 | Note note = noteOptional.orElseThrow(() -> new NoSuchIdException("ID不存在")); 96 | note.setTitle(title); 97 | note.setContent(content); 98 | note.setGmtModified(new Date()); 99 | return hbaseRepository.save(note); 100 | } catch (IOException e) { 101 | logger.info("modify note error ", e); 102 | throw new IncorrectParameterException("参数不正确"); 103 | } 104 | } 105 | 106 | @Override 107 | public void deleteByNoteId(String id) { 108 | try { 109 | hbaseRepository.delete(id); 110 | } catch (IOException e) { 111 | logger.info("delete note error ", e); 112 | } 113 | } 114 | 115 | @Override 116 | public void deleteByNoteBookId(String noteBookId) { 117 | try { 118 | hbaseRepository.batchDelete(noteBookId); 119 | } catch (IOException e) { 120 | logger.info("batch delete notes error ", e); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/service/impl/NoteBookServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.service.impl; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import top.itning.yunshunotesr.dao.NoteBookDao; 9 | import top.itning.yunshunotesr.entity.NoteBook; 10 | import top.itning.yunshunotesr.entity.User; 11 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 12 | import top.itning.yunshunotesr.exception.NoSuchIdException; 13 | import top.itning.yunshunotesr.dao.HbaseRepository; 14 | import top.itning.yunshunotesr.securtiy.SecurityUtils; 15 | import top.itning.yunshunotesr.service.NoteBookService; 16 | import top.itning.yunshunotesr.service.NoteService; 17 | 18 | import javax.transaction.Transactional; 19 | import java.io.IOException; 20 | import java.util.Date; 21 | import java.util.List; 22 | import java.util.Optional; 23 | 24 | /** 25 | * 笔记本服务层实现类 26 | * 27 | * @author itning 28 | */ 29 | @Service 30 | @Transactional(rollbackOn = Exception.class) 31 | public class NoteBookServiceImpl implements NoteBookService { 32 | private static final Logger logger = LoggerFactory.getLogger(NoteBookServiceImpl.class); 33 | 34 | private final NoteBookDao noteBookDao; 35 | 36 | private final NoteService noteService; 37 | 38 | @Autowired 39 | public NoteBookServiceImpl(NoteBookDao noteBookDao, NoteService noteService) { 40 | this.noteBookDao = noteBookDao; 41 | this.noteService = noteService; 42 | } 43 | 44 | @Override 45 | public Optional> getAllNoteBook() { 46 | return Optional.of(noteBookDao.findAllByUser(SecurityUtils.getUser())); 47 | } 48 | 49 | @Override 50 | public void deleteNoteBookById(String id) throws NoSuchIdException { 51 | if (!noteBookDao.existsById(id)) { 52 | logger.info("the note book id " + id + " does not exist"); 53 | throw new NoSuchIdException("笔记本Id:" + id + " 不存在"); 54 | } 55 | noteService.deleteByNoteBookId(id); 56 | noteBookDao.deleteById(id); 57 | } 58 | 59 | @Override 60 | public NoteBook modifyNoteBookName(String id, String name) throws NoSuchIdException, IncorrectParameterException { 61 | if (StringUtils.isBlank(name)) { 62 | throw new IncorrectParameterException("参数不正确:" + name); 63 | } 64 | NoteBook noteBook = noteBookDao.findById(id).orElseThrow(() -> new NoSuchIdException("笔记本Id:" + id + " 不存在")); 65 | noteBook.setName(name); 66 | return noteBookDao.save(noteBook); 67 | } 68 | 69 | @Override 70 | public NoteBook addNoteBook(String name) throws IncorrectParameterException { 71 | if (StringUtils.isBlank(name)) { 72 | throw new IncorrectParameterException("参数不正确:" + name); 73 | } 74 | User user = SecurityUtils.getUser(); 75 | NoteBook noteBook = new NoteBook(); 76 | noteBook.setGmtCreate(new Date()); 77 | noteBook.setGmtModified(new Date()); 78 | noteBook.setName(name); 79 | noteBook.setUser(user); 80 | return noteBookDao.save(noteBook); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.service.impl; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.web.context.request.RequestContextHolder; 9 | import org.springframework.web.context.request.ServletRequestAttributes; 10 | import top.itning.yunshunotesr.dao.UserDao; 11 | import top.itning.yunshunotesr.entity.User; 12 | import top.itning.yunshunotesr.exception.IncorrectParameterException; 13 | import top.itning.yunshunotesr.exception.NoSuchIdException; 14 | import top.itning.yunshunotesr.exception.UserAlreadyExistsException; 15 | import top.itning.yunshunotesr.exception.UserDoesNotExistException; 16 | import top.itning.yunshunotesr.service.UserService; 17 | import top.itning.yunshunotesr.util.EmailUtils; 18 | 19 | import javax.mail.MessagingException; 20 | import javax.transaction.Transactional; 21 | import java.util.*; 22 | 23 | /** 24 | * 用户服务层实现类 25 | * 26 | * @author itning 27 | */ 28 | @Service 29 | @Transactional(rollbackOn = Exception.class) 30 | public class UserServiceImpl implements UserService { 31 | private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); 32 | 33 | private static final String REG_SESSION_ATTRIBUTE = "code"; 34 | 35 | private static final String FORGET_SESSION_ATTRIBUTE = "forgetCode"; 36 | 37 | private static final String FORGET_SESSION_ATTRIBUTE_MAP_CODE = "code"; 38 | 39 | private static final String FORGET_SESSION_ATTRIBUTE_MAP_VCODE = "vCode"; 40 | 41 | private static final String FORGET_SESSION_ATTRIBUTE_MAP_USERNAME = "username"; 42 | 43 | private final UserDao userDao; 44 | 45 | @Autowired 46 | public UserServiceImpl(UserDao userDao) { 47 | this.userDao = userDao; 48 | } 49 | 50 | @Override 51 | public User registeredUser(String name, String username, String password, String code) { 52 | if ((int) ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest().getSession().getAttribute(REG_SESSION_ATTRIBUTE) == Integer.parseInt(code)) { 53 | User user = new User(); 54 | user.setId(UUID.randomUUID().toString()); 55 | user.setGmtCreate(new Date()); 56 | user.setGmtModified(new Date()); 57 | user.setUsername(username); 58 | user.setPassword(password); 59 | user.setName(name); 60 | return userDao.save(user); 61 | } else { 62 | return null; 63 | } 64 | } 65 | 66 | @Override 67 | public void getCode(String email) throws MessagingException, UserAlreadyExistsException { 68 | if (userDao.findByUsername(email) != null) { 69 | logger.info("user " + email + " already exists"); 70 | throw new UserAlreadyExistsException("用户已经存在,重复注册"); 71 | } else { 72 | int code = (int) ((Math.random() * 9 + 1) * 1000); 73 | ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest().getSession().setAttribute(REG_SESSION_ATTRIBUTE, code); 74 | EmailUtils.sendEmail(email, "云舒云笔记验证码邮件", "您的验证码是:" + code); 75 | } 76 | } 77 | 78 | @Override 79 | public Integer forgetPasswordGetCode(String email) throws MessagingException, UserDoesNotExistException { 80 | if (userDao.findByUsername(email) == null) { 81 | throw new UserDoesNotExistException("用户不存在"); 82 | } else { 83 | int code = (int) ((Math.random() * 9 + 1) * 1000); 84 | int vCode = (int) ((Math.random() * 9 + 1) * 1000); 85 | Map map = new HashMap<>(3); 86 | map.put(FORGET_SESSION_ATTRIBUTE_MAP_CODE, code); 87 | map.put(FORGET_SESSION_ATTRIBUTE_MAP_VCODE, vCode); 88 | map.put(FORGET_SESSION_ATTRIBUTE_MAP_USERNAME, email); 89 | ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest().getSession().setAttribute(FORGET_SESSION_ATTRIBUTE, map); 90 | EmailUtils.sendEmail(email, "云舒云笔记重置密码验证码邮件", "您的验证码是:" + code); 91 | return vCode; 92 | } 93 | } 94 | 95 | @Override 96 | public User forgetPassword(String code, String vCode, String password) throws IncorrectParameterException, UserDoesNotExistException { 97 | @SuppressWarnings("unchecked") 98 | Map map = (Map) ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest().getSession().getAttribute(FORGET_SESSION_ATTRIBUTE); 99 | if (!map.get(FORGET_SESSION_ATTRIBUTE_MAP_CODE).toString().equals(code) || !map.get(FORGET_SESSION_ATTRIBUTE_MAP_VCODE).toString().equals(vCode)) { 100 | logger.info("Verification code or key error"); 101 | throw new IncorrectParameterException("验证码或密钥错误"); 102 | } else { 103 | String username = (String) map.get(FORGET_SESSION_ATTRIBUTE_MAP_USERNAME); 104 | User user = userDao.findByUsername(username); 105 | if (user == null) { 106 | throw new UserDoesNotExistException("用户不存在"); 107 | } 108 | user.setPassword(password); 109 | return userDao.save(user); 110 | } 111 | } 112 | 113 | @Override 114 | public User changeUserProfile(String id, String name, String password) throws NoSuchIdException { 115 | User user = userDao.findById(id).orElseThrow(() -> new NoSuchIdException("id不存在")); 116 | boolean change = false; 117 | if (StringUtils.isNoneBlank(name)) { 118 | user.setName(name); 119 | change = true; 120 | } 121 | if (StringUtils.isNoneBlank(password)) { 122 | user.setPassword(password); 123 | change = true; 124 | } 125 | if (change) { 126 | user.setGmtModified(new Date()); 127 | return userDao.save(user); 128 | } 129 | return null; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/top/itning/yunshunotesr/util/EmailUtils.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.util; 2 | 3 | import javax.mail.*; 4 | import javax.mail.internet.InternetAddress; 5 | import javax.mail.internet.MimeMessage; 6 | import java.util.Properties; 7 | 8 | /** 9 | * 邮件工具类 10 | * 11 | * @author wangn 12 | */ 13 | public class EmailUtils { 14 | private EmailUtils() { 15 | } 16 | 17 | /** 18 | * 邮件发送者账户 19 | */ 20 | private static final String EMAIL_SENDER_USER = "itning@itning.top"; 21 | /** 22 | * 邮件发送者密码 23 | */ 24 | private static final String EMAIL_SENDER_PWD = ""; 25 | 26 | private static final String CHECK_EMAIL_STR = "@"; 27 | 28 | /** 29 | * 1、创建连接对象 30 | * 设置邮件发送的协议 31 | * 设置发送邮件的服务器 32 | * 填写自己的密钥 33 | * 2、创建邮件对象 34 | * 设置发件人 35 | * 设置收件人 36 | * 设置抄送者 37 | * 设置邮件主题 38 | * 设置邮件内容 39 | * 3、发送邮件 40 | * 41 | * @param to 邮件接收者邮箱 42 | * @param subject 主题 43 | * @param content 内容 44 | */ 45 | public static void sendEmail(String to, String subject, String content) throws MessagingException { 46 | if (!to.contains(CHECK_EMAIL_STR)) { 47 | throw new IllegalArgumentException("接收者邮箱非法,请检查!"); 48 | } 49 | //1、创建连接对象 50 | Properties props = new Properties(); 51 | //1.1设置邮件发送的协议 52 | props.put("mail.transport.protocol", "smtp"); 53 | //1.2设置发送邮件的服务器 54 | props.put("mail.smtp.host", "smtp.mxhichina.com"); 55 | //1.3需要经过授权,也就是有户名和密码的校验,这样才能通过验证(一定要有这一条) 56 | props.put("mail.smtp.auth", "true"); 57 | //1.4下面一串是发送邮件用465端口,如果不写就是以25端口发送,阿里云已经关闭了25端口 58 | props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 59 | props.setProperty("mail.smtp.socketFactory.fallback", "false"); 60 | props.setProperty("mail.smtp.port", "465"); 61 | props.setProperty("mail.smtp.socketFactory.port", "465"); 62 | //1.5认证信息 63 | Session session = Session.getInstance(props, new Authenticator() { 64 | @Override 65 | protected PasswordAuthentication getPasswordAuthentication() { 66 | return new PasswordAuthentication(EMAIL_SENDER_USER, EMAIL_SENDER_PWD); 67 | } 68 | }); 69 | //2、创建邮件对象 70 | Message message = new MimeMessage(session); 71 | //2.1设置发件人 72 | message.setFrom(new InternetAddress(EMAIL_SENDER_USER)); 73 | //2.2设置收件人 74 | message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to)); 75 | //2.3设置抄送者(PS:没有这一条网易会认为这是一条垃圾短信,而发不出去) 76 | message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(EMAIL_SENDER_USER)); 77 | //2.4设置邮件的主题 78 | message.setSubject(subject); 79 | //2.5设置邮件的内容 80 | message.setContent("" + content + "", "text/html;charset=utf-8"); 81 | // 3、发送邮件 82 | Transport.send(message); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | debug: false 2 | server: 3 | port: 8080 4 | spring: 5 | datasource: 6 | url: jdbc:mysql://localhost:3306/yunshu?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&connectTimeout=0&serverTimezone=UTC 7 | username: root 8 | password: kingston 9 | jpa: 10 | open-in-view: true 11 | database-platform: org.hibernate.dialect.MySQL5InnoDBDialect 12 | hibernate: 13 | ddl-auto: update 14 | show-sql: true 15 | logging: 16 | level.top: debug -------------------------------------------------------------------------------- /src/test/java/top/itning/yunshunotesr/YunshuNotesRApplicationTests.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class YunshuNotesRApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/top/itning/yunshunotesr/dao/NoteBookDaoTest.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.dao; 2 | 3 | import com.google.common.collect.Lists; 4 | import org.junit.After; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.test.context.junit4.SpringRunner; 13 | import top.itning.yunshunotesr.entity.NoteBook; 14 | import top.itning.yunshunotesr.entity.User; 15 | 16 | import java.util.Date; 17 | import java.util.Optional; 18 | 19 | import static org.junit.Assert.assertNotNull; 20 | import static org.junit.Assert.assertSame; 21 | import static org.junit.Assert.assertTrue; 22 | 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest 25 | public class NoteBookDaoTest { 26 | private static final Logger logger = LoggerFactory.getLogger(NoteBookDaoTest.class); 27 | 28 | @Autowired 29 | private NoteBookDao noteBookDao; 30 | 31 | @Autowired 32 | private UserDao userDao; 33 | 34 | @Before 35 | public void setUp() throws Exception { 36 | logger.info("setUp method invoke"); 37 | User user = new User(); 38 | user.setGmtCreate(new Date()); 39 | user.setGmtModified(new Date()); 40 | user.setUsername("test"); 41 | user.setPassword("test"); 42 | user.setName("test"); 43 | userDao.saveAndFlush(user); 44 | if (noteBookDao.findAll().stream().noneMatch(noteBook -> noteBook.getName().equals("测试笔记本1"))) { 45 | NoteBook noteBook = new NoteBook(); 46 | noteBook.setGmtCreate(new Date()); 47 | noteBook.setGmtModified(new Date()); 48 | noteBook.setName("测试笔记本1"); 49 | userDao.findAll().forEach(noteBook::setUser); 50 | noteBookDao.save(noteBook); 51 | } 52 | } 53 | 54 | @After 55 | public void tearDown() throws Exception { 56 | logger.info("tearDown method invoke"); 57 | if (noteBookDao.findAll().stream().anyMatch(noteBook -> noteBook.getName().equals("测试笔记本1"))) { 58 | noteBookDao.findAll().stream().filter(noteBook -> noteBook.getName().equals("测试笔记本1")).forEach(noteBookDao::delete); 59 | } 60 | if (userDao.findAll().stream().anyMatch(user -> user.getName().equals("test"))) { 61 | userDao.findAll().stream().filter(user -> user.getName().equals("test")).forEach(userDao::delete); 62 | } 63 | } 64 | 65 | @Test 66 | public void testSave() { 67 | logger.info("testSave method invoke"); 68 | NoteBook noteBook = new NoteBook(); 69 | noteBook.setGmtCreate(new Date()); 70 | noteBook.setGmtModified(new Date()); 71 | noteBook.setName("测试笔记本1"); 72 | userDao.findAll().forEach(noteBook::setUser); 73 | assertNotNull(noteBookDao.save(noteBook)); 74 | } 75 | 76 | @Test 77 | public void testModify() { 78 | logger.info("testModify method invoke"); 79 | Optional bookOptional = noteBookDao.findAll().stream().filter(noteBook -> noteBook.getName().equals("测试笔记本1")).findFirst(); 80 | assertTrue(bookOptional.isPresent()); 81 | NoteBook noteBook = bookOptional.get(); 82 | Date date = new Date(); 83 | noteBook.setGmtModified(date); 84 | assertNotNull(noteBookDao.save(noteBook)); 85 | } 86 | 87 | @Test 88 | public void testDelete() { 89 | logger.info("testDelete method invoke"); 90 | noteBookDao.findAll().stream().filter(noteBook -> noteBook.getName().equals("测试笔记本1")).forEach(noteBookDao::delete); 91 | assertSame(0L, noteBookDao.findAll().stream().filter(noteBook -> noteBook.getName().equals("测试笔记本1")).count()); 92 | } 93 | } -------------------------------------------------------------------------------- /src/test/java/top/itning/yunshunotesr/dao/UserDaoTest.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.dao; 2 | 3 | import com.google.common.collect.Lists; 4 | 5 | import java.util.Date; 6 | import java.util.Optional; 7 | 8 | import org.junit.After; 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.boot.test.context.SpringBootTest; 16 | import org.springframework.test.context.junit4.SpringRunner; 17 | import top.itning.yunshunotesr.entity.User; 18 | 19 | import static org.junit.Assert.*; 20 | 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | public class UserDaoTest { 24 | private static final Logger logger = LoggerFactory.getLogger(UserDaoTest.class); 25 | 26 | @Autowired 27 | private UserDao userDao; 28 | 29 | @Before 30 | public void setUp() throws Exception { 31 | logger.info("setUp method invoke"); 32 | User user = new User(); 33 | user.setGmtCreate(new Date()); 34 | user.setGmtModified(new Date()); 35 | user.setUsername("test1"); 36 | user.setPassword("test"); 37 | user.setName("test"); 38 | userDao.saveAndFlush(user); 39 | } 40 | 41 | @After 42 | public void tearDown() throws Exception { 43 | if (userDao.findAll().stream().anyMatch(user1 -> user1.getName().equals("test"))) { 44 | userDao.findAll().stream().filter(user2 -> user2.getName().equals("test")).forEach(userDao::delete); 45 | } 46 | if (userDao.findAll().stream().anyMatch(user1 -> user1.getName().equals("test1"))) { 47 | userDao.findAll().stream().filter(user2 -> user2.getName().equals("test1")).forEach(userDao::delete); 48 | } 49 | } 50 | 51 | @Test 52 | public void testSave() { 53 | User user = new User(); 54 | user.setGmtCreate(new Date()); 55 | user.setGmtModified(new Date()); 56 | user.setUsername("test"); 57 | user.setPassword("test"); 58 | user.setName("test1"); 59 | assertNotNull(userDao.save(user)); 60 | assertTrue(userDao.findAll().stream().anyMatch(user1 -> user1.getName().equals("test1"))); 61 | } 62 | 63 | @Test 64 | public void testModify() { 65 | Optional userOptional = userDao.findAll().stream().filter(user -> user.getName().equals("test")).findFirst(); 66 | assertTrue(userOptional.isPresent()); 67 | User user = userOptional.get(); 68 | user.setPassword("test1"); 69 | assertNotNull(userDao.save(user)); 70 | } 71 | 72 | @Test 73 | public void testDelete() { 74 | userDao.findAll().stream().filter(user -> user.getName().equals("test")).forEach(userDao::delete); 75 | assertSame(0L, userDao.findAll().stream().filter(user -> user.getName().equals("test")).count()); 76 | } 77 | } -------------------------------------------------------------------------------- /src/test/java/top/itning/yunshunotesr/service/NoteBookServiceTest.java: -------------------------------------------------------------------------------- 1 | package top.itning.yunshunotesr.service; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.boot.web.servlet.ServletComponentScan; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest 16 | public class NoteBookServiceTest { 17 | 18 | @Before 19 | public void setUp() throws Exception { 20 | 21 | } 22 | 23 | @After 24 | public void tearDown() throws Exception { 25 | } 26 | 27 | @Test 28 | public void getAllNoteBook() { 29 | 30 | } 31 | 32 | @Test 33 | public void deleteNoteBookById() { 34 | } 35 | 36 | @Test 37 | public void modifyNoteBookName() { 38 | } 39 | 40 | @Test 41 | public void addNoteBook() { 42 | } 43 | } --------------------------------------------------------------------------------