├── .gitignore
├── 01.framework-introductions
├── jpa-in-10-steps
│ ├── .gitignore
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── code-21July2017.zip
│ ├── jpa-in-10-steps-all-code.md
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── notes.txt
│ ├── pom.xml
│ ├── readme.md
│ ├── src
│ │ ├── main
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── in28minutes
│ │ │ │ │ └── learning
│ │ │ │ │ └── jpa
│ │ │ │ │ └── jpain10steps
│ │ │ │ │ ├── JpaIn10StepsApplication.java
│ │ │ │ │ ├── UserDaoServiceCommandLineRunner.java
│ │ │ │ │ ├── UserRepositoryCommandLineRunner.java
│ │ │ │ │ ├── entity
│ │ │ │ │ └── User.java
│ │ │ │ │ └── service
│ │ │ │ │ ├── UserDAOService.java
│ │ │ │ │ └── UserRepository.java
│ │ │ └── resources
│ │ │ │ └── application.properties
│ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── in28minutes
│ │ │ └── learning
│ │ │ └── jpa
│ │ │ └── jpain10steps
│ │ │ └── JpaIn10StepsApplicationTests.java
│ ├── step-completed.sh
│ ├── step21.md
│ ├── step21.zip
│ ├── step22.md
│ ├── step22.zip
│ ├── step23.md
│ ├── step23.zip
│ └── take-step-backup.sh
└── springboot-in-10-steps
│ ├── .gitignore
│ ├── 1.md
│ ├── 2.md
│ ├── HELP.md
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── learnspringboot
│ │ │ ├── LearnSpringBootApplication.java
│ │ │ └── courses
│ │ │ ├── bean
│ │ │ └── Course.java
│ │ │ ├── controller
│ │ │ └── CourseController.java
│ │ │ └── repository
│ │ │ └── CourseRepository.java
│ └── resources
│ │ ├── application.properties
│ │ └── data.sql
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── learnspringboot
│ └── LearnSpringBootApplicationTests.java
├── 02.restful-web-services
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── 2.3.1.RELEASE-upgrade.md
├── 2.3.1.RELEASE-upgrade.zip
├── 2.5.0-UPGRADE.md
├── backup01-after-creating-project.md
├── backup01-after-creating-project.zip
├── backup02-after-hello-world-path-param.md
├── backup02-after-hello-world-path-param.zip
├── backup03-after-two-retrieve-user-services.md
├── backup03-after-two-retrieve-user-services.zip
├── backup04-basic-create-service.md
├── backup04-basic-create-service.zip
├── backup05-after-creating-delete-method-on-user-resource.md
├── backup05-after-creating-delete-method-on-user-resource.zip
├── backup06-after-implementing-validation.md
├── backup06-after-implementing-validation.zip
├── backup06-z-content-negotiation.md
├── backup07-improving-documentation-with-swagger.md
├── backup07-improving-documentation-with-swagger.zip
├── backup08-completed-filtering.md
├── backup08-completed-filtering.zip
├── backup09-completed-versioning.md
├── backup09-completed-versioning.zip
├── backup09-z-completed-security.md
├── backup09-z-completed-security.zip
├── backup10-configure-jpa-and-repository.md
├── backup10-configure-jpa-and-repository.zip
├── backup11-added-create-post-resource.md
├── backup11-added-create-post-resource.zip
├── backup12-migrated-to-jpa.md
├── backup12-migrated-to-jpa.zip
├── code-21July2017.zip
├── mvnw
├── mvnw.cmd
├── notes.md
├── pom.xml
├── readme.md
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── in28minutes
│ │ │ └── rest
│ │ │ └── webservices
│ │ │ └── restfulwebservices
│ │ │ ├── RestfulWebServicesApplication.java
│ │ │ ├── exception
│ │ │ ├── CustomizedResponseEntityExceptionHandler.java
│ │ │ └── ExceptionResponse.java
│ │ │ ├── filtering
│ │ │ ├── FilteringController.java
│ │ │ └── SomeBean.java
│ │ │ ├── helloworld
│ │ │ ├── HelloWorldBean.java
│ │ │ └── HelloWorldController.java
│ │ │ ├── user
│ │ │ ├── Post.java
│ │ │ ├── PostRepository.java
│ │ │ ├── User.java
│ │ │ ├── UserDaoService.java
│ │ │ ├── UserJPAResource.java
│ │ │ ├── UserNotFoundException.java
│ │ │ ├── UserRepository.java
│ │ │ └── UserResource.java
│ │ │ └── versioning
│ │ │ ├── Name.java
│ │ │ ├── PersonV1.java
│ │ │ ├── PersonV2.java
│ │ │ └── PersonVersioningController.java
│ └── resources
│ │ ├── application.properties
│ │ ├── data.sql
│ │ ├── messages.properties
│ │ ├── messages_fr.properties
│ │ └── messages_nl.properties
│ └── test
│ └── java
│ └── com
│ └── in28minutes
│ └── rest
│ └── webservices
│ └── restfulwebservices
│ └── RestfulWebServicesApplicationTests.java
├── 03.microservices
├── 2.3.1.RELEASE-upgrade.md
├── 2.3.1.RELEASE-upgrade.zip
├── currency-conversion-service
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── in28minutes
│ │ │ │ └── microservices
│ │ │ │ └── currencyconversionservice
│ │ │ │ ├── CurrencyConversionBean.java
│ │ │ │ ├── CurrencyConversionController.java
│ │ │ │ ├── CurrencyConversionServiceApplication.java
│ │ │ │ └── CurrencyExchangeServiceProxy.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── in28minutes
│ │ └── microservices
│ │ └── currencyconversionservice
│ │ └── CurrencyConversionServiceApplicationTests.java
├── currency-exchange-service
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── in28minutes
│ │ │ │ └── microservices
│ │ │ │ └── currencyexchangeservice
│ │ │ │ ├── CurrencyExchangeController.java
│ │ │ │ ├── CurrencyExchangeServiceApplication.java
│ │ │ │ ├── ExchangeValue.java
│ │ │ │ └── ExchangeValueRepository.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── data.sql
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── in28minutes
│ │ └── microservices
│ │ └── currencyexchangeservice
│ │ └── CurrencyExchangeServiceApplicationTests.java
├── limits-service
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── in28minutes
│ │ │ │ └── microservices
│ │ │ │ └── limitsservice
│ │ │ │ ├── Configuration.java
│ │ │ │ ├── LimitsConfigurationController.java
│ │ │ │ ├── LimitsServiceApplication.java
│ │ │ │ └── bean
│ │ │ │ └── LimitConfiguration.java
│ │ └── resources
│ │ │ └── bootstrap.properties
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── in28minutes
│ │ └── microservices
│ │ └── limitsservice
│ │ └── LimitsServiceApplicationTests.java
├── netflix-eureka-naming-server
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── in28minutes
│ │ │ │ └── microservices
│ │ │ │ └── netflixeurekanamingserver
│ │ │ │ └── NetflixEurekaNamingServerApplication.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── in28minutes
│ │ └── microservices
│ │ └── netflixeurekanamingserver
│ │ └── NetflixEurekaNamingServerApplicationTests.java
├── netflix-zuul-api-gateway-server
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── in28minutes
│ │ │ │ └── microservices
│ │ │ │ └── netflixzuulapigatewayserver
│ │ │ │ ├── NetflixZuulApiGatewayServerApplication.java
│ │ │ │ └── ZuulLoggingFilter.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── in28minutes
│ │ └── microservices
│ │ └── netflixzuulapigatewayserver
│ │ └── NetflixZuulApiGatewayServerApplicationTests.java
├── readme.md
├── spring-cloud-config-server
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── in28minutes
│ │ │ │ └── microservices
│ │ │ │ └── springcloudconfigserver
│ │ │ │ └── SpringCloudConfigServerApplication.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── in28minutes
│ │ └── microservices
│ │ └── springcloudconfigserver
│ │ └── SpringCloudConfigServerApplicationTests.java
├── step01.md
├── step01.zip
├── step03.md
├── step03.zip
├── step08.md
├── step08.zip
├── step09.md
├── step09.zip
├── step11.md
├── step11.zip
├── step17.md
├── step17.zip
├── step20.md
├── step20.zip
├── step23.md
├── step23.zip
├── step25.md
├── step25.zip
├── step29.md
├── step29.zip
├── step34.md
├── step34.zip
├── step41.md
├── step41.zip
├── step42.md
├── step42.zip
├── step43.md
├── step43.zip
├── step44.md
└── step44.zip
├── 2.5.0-upgrade-faq.md
├── LICENSE
├── README.md
├── notes.md
├── spring-boot-2-0-0-Upgrade-notes.md
├── spring-boot-2-0-0-Upgrade-notes.pdf
├── spring-microservices-presentation.pdf
└── zipkin-server-2.12.9-exec.jar
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 | *.cmd
21 | *.classpath
22 | *.settings
23 | *.project
24 | *.mvn
25 | mvnw
26 | target
27 | *.DS_Store
28 |
29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
30 | hs_err_pid*
31 | bin
32 |
33 | # Ignore Mac system file
34 | .DS_Store
35 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/.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 |
12 | ### IntelliJ IDEA ###
13 | .idea
14 | *.iws
15 | *.iml
16 | *.ipr
17 |
18 | ### NetBeans ###
19 | nbproject/private/
20 | build/
21 | nbbuild/
22 | dist/
23 | nbdist/
24 | .nb-gradle/
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/01.framework-introductions/jpa-in-10-steps/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
2 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/code-21July2017.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/01.framework-introductions/jpa-in-10-steps/code-21July2017.zip
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/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 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/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 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/notes.txt:
--------------------------------------------------------------------------------
1 | Questions
2 | - Where is the database created?
3 | - What schema is used to create the tables?
4 | - Where are the tables created?
5 | - Can I see the data in the database?
6 | - Where is Hibernate coming in from?
7 | - How is a datasource created?
8 |
9 | Magic of Spring Boot and in Memory Database
10 | - Zero project setup or infrastructure
11 | - Zero Configuration
12 | - Zero Maintainance
13 | - Easy to use for Learning and Unit Tests
14 | - Simple Configuration to switch to a real database
15 |
16 | # Restrictions of using in-memory database
17 | - Data is not persisted between restarts
18 |
19 | Spring Boot chooses a default value for you based on whether it thinks your database is embedded (default create-drop) or not (default none).
20 |
21 | HibernateJpaAutoConfiguration matched:
22 | - @ConditionalOnClass found required classes 'org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean', 'javax.persistence.EntityManager'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
23 | - HibernateEntityManager found class 'org.hibernate.ejb.HibernateEntityManager' (HibernateJpaAutoConfiguration.HibernateEntityManagerCondition)
24 |
25 | DataSourceAutoConfiguration matched:
26 | - @ConditionalOnClass found required classes 'javax.sql.DataSource', 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
27 |
28 | JpaBaseConfiguration#entityManagerFactory matched:
29 | - @ConditionalOnMissingBean (types: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,javax.persistence.EntityManagerFactory; SearchStrategy: all) did not find any beans (OnBeanCondition)
30 |
31 | JpaBaseConfiguration#transactionManager matched:
32 | - @ConditionalOnMissingBean (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) did not find any beans (OnBeanCondition)
33 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.in28minutes.learning.jpa
7 | jpa-in-10-steps
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | jpa-in-10-steps
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.0.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 9
25 |
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-data-jpa
32 |
33 |
34 |
35 |
36 | javax.transaction
37 | javax.transaction-api
38 |
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-web
43 |
44 |
45 |
46 | com.h2database
47 | h2
48 | runtime
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-test
54 | test
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 | org.apache.maven.plugins
66 | maven-surefire-plugin
67 |
68 | --add-modules java.base
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | spring-snapshots
77 | Spring Snapshots
78 | https://repo.spring.io/snapshot
79 |
80 | true
81 |
82 |
83 |
84 | spring-milestones
85 | Spring Milestones
86 | https://repo.spring.io/milestone
87 |
88 | false
89 |
90 |
91 |
92 |
93 |
94 |
95 | spring-snapshots
96 | Spring Snapshots
97 | https://repo.spring.io/snapshot
98 |
99 | true
100 |
101 |
102 |
103 | spring-milestones
104 | Spring Milestones
105 | https://repo.spring.io/milestone
106 |
107 | false
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/JpaIn10StepsApplication.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learning.jpa.jpain10steps;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class JpaIn10StepsApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(JpaIn10StepsApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/UserDaoServiceCommandLineRunner.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learning.jpa.jpain10steps;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.CommandLineRunner;
7 | import org.springframework.stereotype.Component;
8 |
9 | import com.in28minutes.learning.jpa.jpain10steps.entity.User;
10 | import com.in28minutes.learning.jpa.jpain10steps.service.UserDAOService;
11 |
12 | @Component
13 | public class UserDaoServiceCommandLineRunner implements CommandLineRunner{
14 |
15 | private static final Logger log =
16 | LoggerFactory.getLogger(UserDaoServiceCommandLineRunner.class);
17 |
18 | @Autowired
19 | private UserDAOService userDaoService;
20 |
21 | @Override
22 | public void run(String... arg0) throws Exception {
23 | User user = new User("Jack", "Admin");
24 | //New User is created : User [id=1, name=Jack, role=Admin]
25 | long insert = userDaoService.insert(user);
26 | log.info("New User is created : " + user);
27 | }
28 | }
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/UserRepositoryCommandLineRunner.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learning.jpa.jpain10steps;
2 |
3 | import java.util.List;
4 | import java.util.Optional;
5 |
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.boot.CommandLineRunner;
10 | import org.springframework.stereotype.Component;
11 |
12 | import com.in28minutes.learning.jpa.jpain10steps.entity.User;
13 | import com.in28minutes.learning.jpa.jpain10steps.service.UserRepository;
14 |
15 | @Component
16 | public class UserRepositoryCommandLineRunner implements CommandLineRunner{
17 |
18 | private static final Logger log =
19 | LoggerFactory.getLogger(UserRepositoryCommandLineRunner.class);
20 |
21 | @Autowired
22 | private UserRepository userRepository;
23 |
24 | @Override
25 | public void run(String... arg0) throws Exception {
26 | User user = new User("Jill", "Admin");
27 | userRepository.save(user);
28 | log.info("New User is created : " + user);
29 |
30 | Optional userWithIdOne = userRepository.findById(1L);
31 | log.info("User is retrived : " + userWithIdOne);
32 |
33 | List users = userRepository.findAll();
34 | log.info("All Users : " + users);
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/entity/User.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learning.jpa.jpain10steps.entity;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.Id;
6 |
7 | //Table - User
8 | @Entity
9 | public class User {
10 |
11 | @Id
12 | @GeneratedValue
13 | private long id;
14 |
15 | private String name;
16 |
17 | private String role;
18 |
19 | protected User() {
20 |
21 | }
22 |
23 | public User(String name, String role) {
24 | super();
25 | this.name = name;
26 | this.role = role;
27 | }
28 |
29 | public long getId() {
30 | return id;
31 | }
32 |
33 | public String getName() {
34 | return name;
35 | }
36 |
37 | public String getRole() {
38 | return role;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return String.format("User [id=%s, name=%s, role=%s]", id, name, role);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/service/UserDAOService.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learning.jpa.jpain10steps.service;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 | import javax.transaction.Transactional;
6 |
7 | import org.springframework.stereotype.Repository;
8 |
9 | import com.in28minutes.learning.jpa.jpain10steps.entity.User;
10 |
11 | @Repository
12 | @Transactional
13 | public class UserDAOService {
14 |
15 | @PersistenceContext
16 | private EntityManager entityManager;
17 |
18 | public long insert(User user){
19 | entityManager.persist(user);
20 | return user.getId();
21 | }
22 | }
23 |
24 | /*
25 | * Spring Data JPA
26 | *
27 | *
28 | *
29 | */
30 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/src/main/java/com/in28minutes/learning/jpa/jpain10steps/service/UserRepository.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learning.jpa.jpain10steps.service;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | import com.in28minutes.learning.jpa.jpain10steps.entity.User;
6 |
7 | public interface UserRepository extends JpaRepository{
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.show-sql=true
2 | spring.h2.console.enabled=true
3 | logging.level.org.springframework=debug
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/src/test/java/com/in28minutes/learning/jpa/jpain10steps/JpaIn10StepsApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learning.jpa.jpain10steps;
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 JpaIn10StepsApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/step-completed.sh:
--------------------------------------------------------------------------------
1 | java -cp /ProgrammingExcellence/Workspaces/Rithus.com/ListDirectoryContentInGitFormat/bin test.ListDirectoryContentInGitFormat $PWD >> $1.md
2 | zip -r $1.zip . -x "target/*" -x ".*/*" -x ".*" -x "*.md" -x "mvn*" -x "*.zip"
3 | git add *; git commit -m "$1"; git push;
4 |
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/step21.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/01.framework-introductions/jpa-in-10-steps/step21.zip
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/step22.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/01.framework-introductions/jpa-in-10-steps/step22.zip
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/step23.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/01.framework-introductions/jpa-in-10-steps/step23.zip
--------------------------------------------------------------------------------
/01.framework-introductions/jpa-in-10-steps/take-step-backup.sh:
--------------------------------------------------------------------------------
1 | java -cp /ProgrammingExcellence/Workspaces/Rithus.com/ListDirectoryContentInGitFormat/bin test.ListDirectoryContentInGitFormat $PWD >> $1.md
2 | zip -r $1.zip . -x "target/*" -x ".*/*" -x ".*" -x "*.md" -x "mvn*" -x "*.zip"
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/.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 |
12 | ### IntelliJ IDEA ###
13 | .idea
14 | *.iws
15 | *.iml
16 | *.ipr
17 |
18 | ### NetBeans ###
19 | nbproject/private/
20 | build/
21 | nbbuild/
22 | dist/
23 | nbdist/
24 | .nb-gradle/
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/1.md:
--------------------------------------------------------------------------------
1 |
4 |
5 | ## Complete Code Example
6 |
7 |
8 | ### /pom.xml
9 |
10 | ```xml
11 |
12 |
14 | 4.0.0
15 |
16 | org.springframework.boot
17 | spring-boot-starter-parent
18 | 2.4.4
19 |
20 |
21 | com.in28minutes
22 | learn-spring-boot
23 | 0.0.1-SNAPSHOT
24 | learn-spring-boot
25 | Demo project for Spring Boot
26 |
27 | 11
28 |
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-web
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-data-jpa
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 | runtime
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-starter-actuator
50 |
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-devtools
55 | runtime
56 |
57 |
58 |
59 |
60 | org.springframework.boot
61 | spring-boot-starter-test
62 | test
63 |
64 |
65 |
66 |
67 |
68 |
69 | org.springframework.boot
70 | spring-boot-maven-plugin
71 |
72 |
73 |
74 |
75 |
76 | ```
77 | ---
78 |
79 | ### /src/test/java/com/in28minutes/learnspringboot/LearnSpringBootApplicationTests.java
80 |
81 | ```java
82 | package com.in28minutes.learnspringboot;
83 |
84 | import org.junit.jupiter.api.Test;
85 | import org.springframework.boot.test.context.SpringBootTest;
86 |
87 | @SpringBootTest
88 | class LearnSpringBootApplicationTests {
89 |
90 | @Test
91 | void contextLoads() {
92 | }
93 |
94 | }
95 | ```
96 | ---
97 |
98 | ### /src/main/resources/data.sql
99 |
100 | ```
101 | insert into COURSE (ID, AUTHOR, NAME)
102 | values (100001, 'in28minutes', 'Learn Microservices');
103 | insert into COURSE (ID, AUTHOR, NAME)
104 | values (100002, 'in28minutes', 'Learn FullStack with React and Angular');
105 | insert into COURSE (ID, AUTHOR, NAME)
106 | values (100003, 'in28minutes', 'Learn AWS, GCP and Azure');
107 | ```
108 | ---
109 |
110 | ### /src/main/resources/application.properties
111 |
112 | ```properties
113 | #logging.level.org.springframework=DEBUG
114 | #management.endpoints.web.exposure.include=*
115 | management.endpoints.web.exposure.include=health,metrics
116 | spring.datasource.url=jdbc:h2:mem:testdb
117 | ```
118 | ---
119 |
120 | ### /src/main/java/com/in28minutes/learnspringboot/LearnSpringBootApplication.java
121 |
122 | ```java
123 | package com.in28minutes.learnspringboot;
124 |
125 | import org.springframework.boot.SpringApplication;
126 | import org.springframework.boot.autoconfigure.SpringBootApplication;
127 |
128 | @SpringBootApplication
129 | //@SpringBootConfiguration
130 | //@EnableAutoConfiguration
131 | //@ComponentScan
132 | public class LearnSpringBootApplication {
133 |
134 | public static void main(String[] args) {
135 | SpringApplication.run(LearnSpringBootApplication.class, args);
136 | }
137 |
138 | }
139 | ```
140 | ---
141 |
142 | ### /src/main/java/com/in28minutes/learnspringboot/courses/repository/CourseRepository.java
143 |
144 | ```java
145 | package com.in28minutes.learnspringboot.courses.repository;
146 |
147 | import org.springframework.data.jpa.repository.JpaRepository;
148 |
149 | import com.in28minutes.learnspringboot.courses.bean.Course;
150 |
151 | public interface CourseRepository extends JpaRepository {
152 |
153 | }
154 | ```
155 | ---
156 |
157 | ### /src/main/java/com/in28minutes/learnspringboot/courses/bean/Course.java
158 |
159 | ```java
160 | package com.in28minutes.learnspringboot.courses.bean;
161 |
162 | import javax.persistence.Column;
163 | import javax.persistence.Entity;
164 | import javax.persistence.GeneratedValue;
165 | import javax.persistence.Id;
166 |
167 | @Entity
168 | public class Course {
169 |
170 | @Id
171 | @GeneratedValue
172 | private long id;
173 |
174 | //@Column(name="course_name")
175 | private String name;
176 |
177 | private String author;
178 |
179 | public Course() {
180 | }
181 |
182 | public Course(long id, String name, String author) {
183 | super();
184 | this.id = id;
185 | this.name = name;
186 | this.author = author;
187 | }
188 |
189 | public long getId() {
190 | return id;
191 | }
192 |
193 | public String getName() {
194 | return name;
195 | }
196 |
197 | public String getAuthor() {
198 | return author;
199 | }
200 |
201 | @Override
202 | public String toString() {
203 | return "Course [id=" + id + ", name=" + name + ", author=" + author + "]";
204 | }
205 |
206 | }
207 | ```
208 | ---
209 |
210 | ### /src/main/java/com/in28minutes/learnspringboot/courses/controller/CourseController.java
211 |
212 | ```java
213 | package com.in28minutes.learnspringboot.courses.controller;
214 |
215 | import java.util.List;
216 | import java.util.Optional;
217 |
218 | import org.springframework.beans.factory.annotation.Autowired;
219 | import org.springframework.web.bind.annotation.DeleteMapping;
220 | import org.springframework.web.bind.annotation.GetMapping;
221 | import org.springframework.web.bind.annotation.PathVariable;
222 | import org.springframework.web.bind.annotation.PostMapping;
223 | import org.springframework.web.bind.annotation.PutMapping;
224 | import org.springframework.web.bind.annotation.RequestBody;
225 | import org.springframework.web.bind.annotation.RestController;
226 |
227 | import com.in28minutes.learnspringboot.courses.bean.Course;
228 | import com.in28minutes.learnspringboot.courses.repository.CourseRepository;
229 |
230 | @RestController
231 | public class CourseController {
232 |
233 | @Autowired
234 | private CourseRepository repository;
235 |
236 | // http://localhost:8080/courses
237 | @GetMapping("/courses")
238 | public List getAllCourses() {
239 | return repository.findAll();
240 | }
241 |
242 | //// http://localhost:8080/courses/1
243 | @GetMapping("/courses/{id}")
244 | public Course getCourseDetails(@PathVariable long id) {
245 |
246 | Optional course = repository.findById(id);
247 |
248 | if(course.isEmpty()) {
249 | throw new RuntimeException("Course not found with id " + id);
250 | }
251 |
252 | return course.get();
253 | }
254 |
255 | /*
256 | POST http://localhost:8080/courses
257 | {
258 | "name": "Learn DevOps",
259 | "author": "in28minutes"
260 | }*/
261 |
262 | //POST - Create a new resource (/courses)
263 | @PostMapping("/courses")
264 | public void createCourse(@RequestBody Course course){
265 | repository.save(course);
266 | }
267 |
268 | /*
269 | PUT - http://localhost:8080/courses/100001
270 | {
271 | "id": 100001,
272 | "name": "Learn Microservices 2",
273 | "author": "in28minutes"
274 | }
275 | */
276 |
277 | //PUT - Update/Replace a resource (/courses/1)
278 | @PutMapping("/courses/{id}")
279 | public void updateCourse(@PathVariable long id, @RequestBody Course course){
280 | repository.save(course);
281 | }
282 |
283 |
284 | //DELETE - Delete a resource (/courses/1)
285 | @DeleteMapping("/courses/{id}")
286 | public void deleteCourse(@PathVariable long id){
287 | repository.deleteById(id);
288 | }
289 |
290 |
291 | // docker run --detach
292 | // --env MYSQL_ROOT_PASSWORD=dummypassword
293 | // --env MYSQL_USER=courses-user
294 | // --env MYSQL_PASSWORD=dummycourses
295 | // --env MYSQL_DATABASE=courses
296 | // --name mysql
297 | // --publish 3306:3306 mysql:5.7
298 | }
299 | ```
300 | ---
301 |
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/2.md:
--------------------------------------------------------------------------------
1 |
4 |
5 | ## Complete Code Example
6 |
7 |
8 | ### /pom.xml
9 |
10 | ```xml
11 |
12 |
14 | 4.0.0
15 |
16 | org.springframework.boot
17 | spring-boot-starter-parent
18 | 2.4.4
19 |
20 |
21 | com.in28minutes
22 | learn-spring-boot
23 | 0.0.1-SNAPSHOT
24 | learn-spring-boot
25 | Demo project for Spring Boot
26 |
27 | 11
28 |
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-web
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-data-jpa
39 |
40 |
41 |
47 |
48 |
49 | mysql
50 | mysql-connector-java
51 |
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-starter-actuator
56 |
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-devtools
61 | runtime
62 |
63 |
64 |
65 |
66 | org.springframework.boot
67 | spring-boot-starter-test
68 | test
69 |
70 |
71 |
72 |
73 |
74 |
75 | org.springframework.boot
76 | spring-boot-maven-plugin
77 |
78 |
79 |
80 |
81 |
82 | ```
83 | ---
84 |
85 | ### /src/test/java/com/in28minutes/learnspringboot/LearnSpringBootApplicationTests.java
86 |
87 | ```java
88 | package com.in28minutes.learnspringboot;
89 |
90 | import org.junit.jupiter.api.Test;
91 | import org.springframework.boot.test.context.SpringBootTest;
92 |
93 | @SpringBootTest
94 | class LearnSpringBootApplicationTests {
95 |
96 | @Test
97 | void contextLoads() {
98 | }
99 |
100 | }
101 | ```
102 | ---
103 |
104 | ### /src/main/resources/data.sql
105 |
106 | ```
107 | insert into COURSE (ID, AUTHOR, NAME)
108 | values (100001, 'in28minutes', 'Learn Microservices');
109 | insert into COURSE (ID, AUTHOR, NAME)
110 | values (100002, 'in28minutes', 'Learn FullStack with React and Angular');
111 | insert into COURSE (ID, AUTHOR, NAME)
112 | values (100003, 'in28minutes', 'Learn AWS, GCP and Azure');
113 | ```
114 | ---
115 |
116 | ### /src/main/resources/application.properties
117 |
118 | ```properties
119 | #logging.level.org.springframework=DEBUG
120 | #management.endpoints.web.exposure.include=*
121 | management.endpoints.web.exposure.include=health,metrics
122 | #spring.datasource.url=jdbc:h2:mem:testdb
123 |
124 | spring.jpa.hibernate.ddl-auto=update
125 | spring.datasource.url=jdbc:mysql://localhost:3306/courses
126 | spring.datasource.username=courses-user
127 | spring.datasource.password=dummycourses
128 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
129 |
130 | #courses-user@localhost:3306
131 | ```
132 | ---
133 |
134 | ### /src/main/java/com/in28minutes/learnspringboot/LearnSpringBootApplication.java
135 |
136 | ```java
137 | package com.in28minutes.learnspringboot;
138 |
139 | import org.springframework.boot.SpringApplication;
140 | import org.springframework.boot.autoconfigure.SpringBootApplication;
141 |
142 | @SpringBootApplication
143 | //@SpringBootConfiguration
144 | //@EnableAutoConfiguration
145 | //@ComponentScan
146 | public class LearnSpringBootApplication {
147 |
148 | public static void main(String[] args) {
149 | SpringApplication.run(LearnSpringBootApplication.class, args);
150 | }
151 |
152 | }
153 | ```
154 | ---
155 |
156 | ### /src/main/java/com/in28minutes/learnspringboot/courses/repository/CourseRepository.java
157 |
158 | ```java
159 | package com.in28minutes.learnspringboot.courses.repository;
160 |
161 | import org.springframework.data.jpa.repository.JpaRepository;
162 |
163 | import com.in28minutes.learnspringboot.courses.bean.Course;
164 |
165 | public interface CourseRepository extends JpaRepository {
166 |
167 | }
168 | ```
169 | ---
170 |
171 | ### /src/main/java/com/in28minutes/learnspringboot/courses/bean/Course.java
172 |
173 | ```java
174 | package com.in28minutes.learnspringboot.courses.bean;
175 |
176 | import javax.persistence.Column;
177 | import javax.persistence.Entity;
178 | import javax.persistence.GeneratedValue;
179 | import javax.persistence.Id;
180 |
181 | @Entity
182 | public class Course {
183 |
184 | @Id
185 | @GeneratedValue
186 | private long id;
187 |
188 | //@Column(name="course_name")
189 | private String name;
190 |
191 | private String author;
192 |
193 | public Course() {
194 | }
195 |
196 | public Course(long id, String name, String author) {
197 | super();
198 | this.id = id;
199 | this.name = name;
200 | this.author = author;
201 | }
202 |
203 | public long getId() {
204 | return id;
205 | }
206 |
207 | public String getName() {
208 | return name;
209 | }
210 |
211 | public String getAuthor() {
212 | return author;
213 | }
214 |
215 | @Override
216 | public String toString() {
217 | return "Course [id=" + id + ", name=" + name + ", author=" + author + "]";
218 | }
219 |
220 | }
221 | ```
222 | ---
223 |
224 | ### /src/main/java/com/in28minutes/learnspringboot/courses/controller/CourseController.java
225 |
226 | ```java
227 | package com.in28minutes.learnspringboot.courses.controller;
228 |
229 | import java.util.List;
230 | import java.util.Optional;
231 |
232 | import org.springframework.beans.factory.annotation.Autowired;
233 | import org.springframework.web.bind.annotation.DeleteMapping;
234 | import org.springframework.web.bind.annotation.GetMapping;
235 | import org.springframework.web.bind.annotation.PathVariable;
236 | import org.springframework.web.bind.annotation.PostMapping;
237 | import org.springframework.web.bind.annotation.PutMapping;
238 | import org.springframework.web.bind.annotation.RequestBody;
239 | import org.springframework.web.bind.annotation.RestController;
240 |
241 | import com.in28minutes.learnspringboot.courses.bean.Course;
242 | import com.in28minutes.learnspringboot.courses.repository.CourseRepository;
243 |
244 | @RestController
245 | public class CourseController {
246 |
247 | @Autowired
248 | private CourseRepository repository;
249 |
250 | // http://localhost:8080/courses
251 | @GetMapping("/courses")
252 | public List getAllCourses() {
253 | return repository.findAll();
254 | }
255 |
256 | //// http://localhost:8080/courses/1
257 | @GetMapping("/courses/{id}")
258 | public Course getCourseDetails(@PathVariable long id) {
259 |
260 | Optional course = repository.findById(id);
261 |
262 | if(course.isEmpty()) {
263 | throw new RuntimeException("Course not found with id " + id);
264 | }
265 |
266 | return course.get();
267 | }
268 |
269 | /*
270 | POST http://localhost:8080/courses
271 | {
272 | "name": "Learn DevOps",
273 | "author": "in28minutes"
274 | }*/
275 |
276 | //POST - Create a new resource (/courses)
277 | @PostMapping("/courses")
278 | public void createCourse(@RequestBody Course course){
279 | repository.save(course);
280 | }
281 |
282 | /*
283 | PUT - http://localhost:8080/courses/100001
284 | {
285 | "id": 100001,
286 | "name": "Learn Microservices 2",
287 | "author": "in28minutes"
288 | }
289 | */
290 |
291 | //PUT - Update/Replace a resource (/courses/1)
292 | @PutMapping("/courses/{id}")
293 | public void updateCourse(@PathVariable long id, @RequestBody Course course){
294 | repository.save(course);
295 | }
296 |
297 |
298 | //DELETE - Delete a resource (/courses/1)
299 | @DeleteMapping("/courses/{id}")
300 | public void deleteCourse(@PathVariable long id){
301 | repository.deleteById(id);
302 | }
303 |
304 |
305 | // docker run --detach
306 | // --env MYSQL_ROOT_PASSWORD=dummypassword
307 | // --env MYSQL_USER=courses-user
308 | // --env MYSQL_PASSWORD=dummycourses
309 | // --env MYSQL_DATABASE=courses
310 | // --name mysql
311 | // --publish 3306:3306 mysql:5.7
312 | }
313 | ```
314 | ---
315 |
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/HELP.md:
--------------------------------------------------------------------------------
1 | # Read Me First
2 | The following was discovered as part of building this project:
3 |
4 | * The original package name 'com.in28minutes.learn-spring-boot' is invalid and this project uses 'com.in28minutes.learnspringboot' instead.
5 |
6 | # Getting Started
7 |
8 | ### Reference Documentation
9 | For further reference, please consider the following sections:
10 |
11 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
12 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.4.4/maven-plugin/reference/html/)
13 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.4.4/maven-plugin/reference/html/#build-image)
14 | * [Spring Web](https://docs.spring.io/spring-boot/docs/2.4.4/reference/htmlsingle/#boot-features-developing-web-applications)
15 |
16 | ### Guides
17 | The following guides illustrate how to use some features concretely:
18 |
19 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
20 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
21 | * [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/)
22 |
23 |
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.4.4
9 |
10 |
11 | com.in28minutes
12 | learn-spring-boot
13 | 0.0.1-SNAPSHOT
14 | learn-spring-boot
15 | Demo project for Spring Boot
16 |
17 | 11
18 |
19 |
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-web
24 |
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-data-jpa
29 |
30 |
31 |
37 |
38 |
39 | mysql
40 | mysql-connector-java
41 |
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter-actuator
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-devtools
51 | runtime
52 |
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-starter-test
58 | test
59 |
60 |
61 |
62 |
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-maven-plugin
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/src/main/java/com/in28minutes/learnspringboot/LearnSpringBootApplication.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | //@SpringBootConfiguration
8 | //@EnableAutoConfiguration
9 | //@ComponentScan
10 | public class LearnSpringBootApplication {
11 |
12 | public static void main(String[] args) {
13 | SpringApplication.run(LearnSpringBootApplication.class, args);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/src/main/java/com/in28minutes/learnspringboot/courses/bean/Course.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot.courses.bean;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.Entity;
5 | import javax.persistence.GeneratedValue;
6 | import javax.persistence.Id;
7 |
8 | @Entity
9 | public class Course {
10 |
11 | @Id
12 | @GeneratedValue
13 | private long id;
14 |
15 | //@Column(name="course_name")
16 | private String name;
17 |
18 | private String author;
19 |
20 | public Course() {
21 | }
22 |
23 | public Course(long id, String name, String author) {
24 | super();
25 | this.id = id;
26 | this.name = name;
27 | this.author = author;
28 | }
29 |
30 | public long getId() {
31 | return id;
32 | }
33 |
34 | public String getName() {
35 | return name;
36 | }
37 |
38 | public String getAuthor() {
39 | return author;
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return "Course [id=" + id + ", name=" + name + ", author=" + author + "]";
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/src/main/java/com/in28minutes/learnspringboot/courses/controller/CourseController.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot.courses.controller;
2 |
3 | import java.util.List;
4 | import java.util.Optional;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.web.bind.annotation.DeleteMapping;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.PathVariable;
10 | import org.springframework.web.bind.annotation.PostMapping;
11 | import org.springframework.web.bind.annotation.PutMapping;
12 | import org.springframework.web.bind.annotation.RequestBody;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import com.in28minutes.learnspringboot.courses.bean.Course;
16 | import com.in28minutes.learnspringboot.courses.repository.CourseRepository;
17 |
18 | @RestController
19 | public class CourseController {
20 |
21 | @Autowired
22 | private CourseRepository repository;
23 |
24 | // http://localhost:8080/courses
25 | @GetMapping("/courses")
26 | public List getAllCourses() {
27 | return repository.findAll();
28 | }
29 |
30 | //// http://localhost:8080/courses/1
31 | @GetMapping("/courses/{id}")
32 | public Course getCourseDetails(@PathVariable long id) {
33 |
34 | Optional course = repository.findById(id);
35 |
36 | if(course.isEmpty()) {
37 | throw new RuntimeException("Course not found with id " + id);
38 | }
39 |
40 | return course.get();
41 | }
42 |
43 | /*
44 | POST http://localhost:8080/courses
45 | {
46 | "name": "Learn DevOps",
47 | "author": "in28minutes"
48 | }*/
49 |
50 | //POST - Create a new resource (/courses)
51 | @PostMapping("/courses")
52 | public void createCourse(@RequestBody Course course){
53 | repository.save(course);
54 | }
55 |
56 | /*
57 | PUT - http://localhost:8080/courses/100001
58 | {
59 | "id": 100001,
60 | "name": "Learn Microservices 2",
61 | "author": "in28minutes"
62 | }
63 | */
64 |
65 | //PUT - Update/Replace a resource (/courses/1)
66 | @PutMapping("/courses/{id}")
67 | public void updateCourse(@PathVariable long id, @RequestBody Course course){
68 | repository.save(course);
69 | }
70 |
71 |
72 | //DELETE - Delete a resource (/courses/1)
73 | @DeleteMapping("/courses/{id}")
74 | public void deleteCourse(@PathVariable long id){
75 | repository.deleteById(id);
76 | }
77 |
78 |
79 | // docker run --detach
80 | // --env MYSQL_ROOT_PASSWORD=dummypassword
81 | // --env MYSQL_USER=courses-user
82 | // --env MYSQL_PASSWORD=dummycourses
83 | // --env MYSQL_DATABASE=courses
84 | // --name mysql
85 | // --publish 3306:3306 mysql:5.7
86 | }
87 |
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/src/main/java/com/in28minutes/learnspringboot/courses/repository/CourseRepository.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot.courses.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | import com.in28minutes.learnspringboot.courses.bean.Course;
6 |
7 | public interface CourseRepository extends JpaRepository {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | #logging.level.org.springframework=DEBUG
2 | #management.endpoints.web.exposure.include=*
3 | management.endpoints.web.exposure.include=health,metrics
4 | #spring.datasource.url=jdbc:h2:mem:testdb
5 |
6 | spring.jpa.hibernate.ddl-auto=update
7 | spring.datasource.url=jdbc:mysql://localhost:3306/courses
8 | spring.datasource.username=courses-user
9 | spring.datasource.password=dummycourses
10 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
11 |
12 | #courses-user@localhost:3306
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/src/main/resources/data.sql:
--------------------------------------------------------------------------------
1 | insert into COURSE (ID, AUTHOR, NAME)
2 | values (100001, 'in28minutes', 'Learn Microservices');
3 | insert into COURSE (ID, AUTHOR, NAME)
4 | values (100002, 'in28minutes', 'Learn FullStack with React and Angular');
5 | insert into COURSE (ID, AUTHOR, NAME)
6 | values (100003, 'in28minutes', 'Learn AWS, GCP and Azure');
--------------------------------------------------------------------------------
/01.framework-introductions/springboot-in-10-steps/src/test/java/com/in28minutes/learnspringboot/LearnSpringBootApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.learnspringboot;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class LearnSpringBootApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/02.restful-web-services/.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 |
12 | ### IntelliJ IDEA ###
13 | .idea
14 | *.iws
15 | *.iml
16 | *.ipr
17 |
18 | ### NetBeans ###
19 | nbproject/private/
20 | build/
21 | nbbuild/
22 | dist/
23 | nbdist/
24 | .nb-gradle/
--------------------------------------------------------------------------------
/02.restful-web-services/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/02.restful-web-services/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
2 |
--------------------------------------------------------------------------------
/02.restful-web-services/2.3.1.RELEASE-upgrade.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/2.3.1.RELEASE-upgrade.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup01-after-creating-project.md:
--------------------------------------------------------------------------------
1 |
2 | ## Complete Code Example
3 |
4 |
5 | ### /pom.xml
6 |
7 | ```xml
8 |
9 |
11 | 4.0.0
12 |
13 | com.in28minutes.rest.webservices
14 | restful-web-services
15 | 0.0.1-SNAPSHOT
16 | jar
17 |
18 | restful-web-services
19 | Demo project for Spring Boot
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-parent
24 | 2.0.0.RELEASE
25 |
26 |
27 |
28 |
29 | UTF-8
30 | UTF-8
31 | 1.8
32 |
33 |
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-data-jpa
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-starter-web
42 |
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-devtools
47 | runtime
48 |
49 |
50 | com.h2database
51 | h2
52 | runtime
53 |
54 |
55 | org.springframework.boot
56 | spring-boot-starter-test
57 | test
58 |
59 |
60 |
61 |
62 |
63 |
64 | org.springframework.boot
65 | spring-boot-maven-plugin
66 |
67 |
68 |
69 |
70 |
71 |
72 | spring-snapshots
73 | Spring Snapshots
74 | https://repo.spring.io/snapshot
75 |
76 | true
77 |
78 |
79 |
80 | spring-milestones
81 | Spring Milestones
82 | https://repo.spring.io/milestone
83 |
84 | false
85 |
86 |
87 |
88 |
89 |
90 |
91 | spring-snapshots
92 | Spring Snapshots
93 | https://repo.spring.io/snapshot
94 |
95 | true
96 |
97 |
98 |
99 | spring-milestones
100 | Spring Milestones
101 | https://repo.spring.io/milestone
102 |
103 | false
104 |
105 |
106 |
107 |
108 |
109 |
110 | ```
111 | ---
112 |
113 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java
114 |
115 | ```java
116 | package com.in28minutes.rest.webservices.restfulwebservices;
117 |
118 | import org.springframework.boot.SpringApplication;
119 | import org.springframework.boot.autoconfigure.SpringBootApplication;
120 |
121 | @SpringBootApplication
122 | public class RestfulWebServicesApplication {
123 |
124 | public static void main(String[] args) {
125 | SpringApplication.run(RestfulWebServicesApplication.class, args);
126 | }
127 | }
128 | ```
129 | ---
130 |
131 | ### /src/main/resources/application.properties
132 |
133 | ```properties
134 | ```
135 | ---
136 |
137 | ### /src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java
138 |
139 | ```java
140 | package com.in28minutes.rest.webservices.restfulwebservices;
141 |
142 | import org.junit.Test;
143 | import org.junit.runner.RunWith;
144 | import org.springframework.boot.test.context.SpringBootTest;
145 | import org.springframework.test.context.junit4.SpringRunner;
146 |
147 | @RunWith(SpringRunner.class)
148 | @SpringBootTest
149 | public class RestfulWebServicesApplicationTests {
150 |
151 | @Test
152 | public void contextLoads() {
153 | }
154 |
155 | }
156 | ```
157 | ---
158 |
--------------------------------------------------------------------------------
/02.restful-web-services/backup01-after-creating-project.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup01-after-creating-project.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup02-after-hello-world-path-param.md:
--------------------------------------------------------------------------------
1 |
2 | ## Complete Code Example
3 |
4 |
5 | ### /pom.xml
6 |
7 | ```xml
8 |
9 |
11 | 4.0.0
12 |
13 | com.in28minutes.rest.webservices
14 | restful-web-services
15 | 0.0.1-SNAPSHOT
16 | jar
17 |
18 | restful-web-services
19 | Demo project for Spring Boot
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-parent
24 | 2.0.0.RELEASE
25 |
26 |
27 |
28 |
29 | UTF-8
30 | UTF-8
31 | 1.8
32 |
33 |
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-data-jpa
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-web
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-devtools
49 | runtime
50 |
51 |
52 |
53 | com.h2database
54 | h2
55 | runtime
56 |
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-starter-test
61 | test
62 |
63 |
64 |
65 |
66 |
67 |
68 | org.springframework.boot
69 | spring-boot-maven-plugin
70 |
71 |
72 |
73 |
74 |
75 |
76 | spring-snapshots
77 | Spring Snapshots
78 | https://repo.spring.io/snapshot
79 |
80 | true
81 |
82 |
83 |
84 | spring-milestones
85 | Spring Milestones
86 | https://repo.spring.io/milestone
87 |
88 | false
89 |
90 |
91 |
92 |
93 |
94 |
95 | spring-snapshots
96 | Spring Snapshots
97 | https://repo.spring.io/snapshot
98 |
99 | true
100 |
101 |
102 |
103 | spring-milestones
104 | Spring Milestones
105 | https://repo.spring.io/milestone
106 |
107 | false
108 |
109 |
110 |
111 |
112 |
113 |
114 | ```
115 | ---
116 |
117 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/HelloWorldBean.java
118 |
119 | ```java
120 | package com.in28minutes.rest.webservices.restfulwebservices;
121 |
122 | public class HelloWorldBean {
123 |
124 | private String message;
125 |
126 | public HelloWorldBean(String message) {
127 | this.message = message;
128 | }
129 |
130 | public String getMessage() {
131 | return message;
132 | }
133 |
134 | public void setMessage(String message) {
135 | this.message = message;
136 | }
137 |
138 | @Override
139 | public String toString() {
140 | return String.format("HelloWorldBean [message=%s]", message);
141 | }
142 |
143 | }
144 | ```
145 | ---
146 |
147 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/HelloWorldController.java
148 |
149 | ```java
150 | package com.in28minutes.rest.webservices.restfulwebservices;
151 |
152 | import org.springframework.web.bind.annotation.GetMapping;
153 | import org.springframework.web.bind.annotation.PathVariable;
154 | import org.springframework.web.bind.annotation.RestController;
155 |
156 | //Controller
157 | @RestController
158 | public class HelloWorldController {
159 |
160 | @GetMapping(path = "/hello-world")
161 | public String helloWorld() {
162 | return "Hello World";
163 | }
164 |
165 | @GetMapping(path = "/hello-world-bean")
166 | public HelloWorldBean helloWorldBean() {
167 | return new HelloWorldBean("Hello World");
168 | }
169 |
170 | ///hello-world/path-variable/in28minutes
171 | @GetMapping(path = "/hello-world/path-variable/{name}")
172 | public HelloWorldBean helloWorldPathVariable(@PathVariable String name) {
173 | return new HelloWorldBean(String.format("Hello World, %s", name));
174 | }
175 |
176 | }
177 | ```
178 | ---
179 |
180 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java
181 |
182 | ```java
183 | package com.in28minutes.rest.webservices.restfulwebservices;
184 |
185 | import org.springframework.boot.SpringApplication;
186 | import org.springframework.boot.autoconfigure.SpringBootApplication;
187 |
188 | @SpringBootApplication
189 | public class RestfulWebServicesApplication {
190 |
191 | public static void main(String[] args) {
192 | SpringApplication.run(RestfulWebServicesApplication.class, args);
193 | }
194 | }
195 | ```
196 | ---
197 |
198 | ### /src/main/resources/application.properties
199 |
200 | ```properties
201 | logging.level.org.springframework = info
202 | ```
203 | ---
204 |
205 | ### /src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java
206 |
207 | ```java
208 | package com.in28minutes.rest.webservices.restfulwebservices;
209 |
210 | import org.junit.Test;
211 | import org.junit.runner.RunWith;
212 | import org.springframework.boot.test.context.SpringBootTest;
213 | import org.springframework.test.context.junit4.SpringRunner;
214 |
215 | @RunWith(SpringRunner.class)
216 | @SpringBootTest
217 | public class RestfulWebServicesApplicationTests {
218 |
219 | @Test
220 | public void contextLoads() {
221 | }
222 |
223 | }
224 | ```
225 | ---
226 |
--------------------------------------------------------------------------------
/02.restful-web-services/backup02-after-hello-world-path-param.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup02-after-hello-world-path-param.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup03-after-two-retrieve-user-services.md:
--------------------------------------------------------------------------------
1 |
2 | ## Complete Code Example
3 |
4 |
5 | ### /pom.xml
6 |
7 | ```xml
8 |
9 |
11 | 4.0.0
12 |
13 | com.in28minutes.rest.webservices
14 | restful-web-services
15 | 0.0.1-SNAPSHOT
16 | jar
17 |
18 | restful-web-services
19 | Demo project for Spring Boot
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-parent
24 | 2.0.0.RELEASE
25 |
26 |
27 |
28 |
29 | UTF-8
30 | UTF-8
31 | 1.8
32 |
33 |
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-data-jpa
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-web
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-devtools
49 | runtime
50 |
51 |
52 |
53 | com.h2database
54 | h2
55 | runtime
56 |
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-starter-test
61 | test
62 |
63 |
64 |
65 |
66 |
67 |
68 | org.springframework.boot
69 | spring-boot-maven-plugin
70 |
71 |
72 |
73 |
74 |
75 |
76 | spring-snapshots
77 | Spring Snapshots
78 | https://repo.spring.io/snapshot
79 |
80 | true
81 |
82 |
83 |
84 | spring-milestones
85 | Spring Milestones
86 | https://repo.spring.io/milestone
87 |
88 | false
89 |
90 |
91 |
92 |
93 |
94 |
95 | spring-snapshots
96 | Spring Snapshots
97 | https://repo.spring.io/snapshot
98 |
99 | true
100 |
101 |
102 |
103 | spring-milestones
104 | Spring Milestones
105 | https://repo.spring.io/milestone
106 |
107 | false
108 |
109 |
110 |
111 |
112 |
113 |
114 | ```
115 | ---
116 |
117 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldBean.java
118 |
119 | ```java
120 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld;
121 |
122 | public class HelloWorldBean {
123 |
124 | private String message;
125 |
126 | public HelloWorldBean(String message) {
127 | this.message = message;
128 | }
129 |
130 | public String getMessage() {
131 | return message;
132 | }
133 |
134 | public void setMessage(String message) {
135 | this.message = message;
136 | }
137 |
138 | @Override
139 | public String toString() {
140 | return String.format("HelloWorldBean [message=%s]", message);
141 | }
142 |
143 | }
144 | ```
145 | ---
146 |
147 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/helloworld/HelloWorldController.java
148 |
149 | ```java
150 | package com.in28minutes.rest.webservices.restfulwebservices.helloworld;
151 |
152 | import org.springframework.web.bind.annotation.GetMapping;
153 | import org.springframework.web.bind.annotation.PathVariable;
154 | import org.springframework.web.bind.annotation.RestController;
155 |
156 | //Controller
157 | @RestController
158 | public class HelloWorldController {
159 |
160 | @GetMapping(path = "/hello-world")
161 | public String helloWorld() {
162 | return "Hello World";
163 | }
164 |
165 | @GetMapping(path = "/hello-world-bean")
166 | public HelloWorldBean helloWorldBean() {
167 | return new HelloWorldBean("Hello World");
168 | }
169 |
170 | ///hello-world/path-variable/in28minutes
171 | @GetMapping(path = "/hello-world/path-variable/{name}")
172 | public HelloWorldBean helloWorldPathVariable(@PathVariable String name) {
173 | return new HelloWorldBean(String.format("Hello World, %s", name));
174 | }
175 |
176 | }
177 | ```
178 | ---
179 |
180 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java
181 |
182 | ```java
183 | package com.in28minutes.rest.webservices.restfulwebservices;
184 |
185 | import org.springframework.boot.SpringApplication;
186 | import org.springframework.boot.autoconfigure.SpringBootApplication;
187 |
188 | @SpringBootApplication
189 | public class RestfulWebServicesApplication {
190 |
191 | public static void main(String[] args) {
192 | SpringApplication.run(RestfulWebServicesApplication.class, args);
193 | }
194 | }
195 | ```
196 | ---
197 |
198 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/user/User.java
199 |
200 | ```java
201 |
202 | package com.in28minutes.rest.webservices.restfulwebservices.user;
203 |
204 | import java.util.Date;
205 |
206 | public class User {
207 |
208 | private Integer id;
209 |
210 | private String name;
211 |
212 | private Date birthDate;
213 |
214 | public User(Integer id, String name, Date birthDate) {
215 | super();
216 | this.id = id;
217 | this.name = name;
218 | this.birthDate = birthDate;
219 | }
220 |
221 | public Integer getId() {
222 | return id;
223 | }
224 |
225 | public void setId(Integer id) {
226 | this.id = id;
227 | }
228 |
229 | public String getName() {
230 | return name;
231 | }
232 |
233 | public void setName(String name) {
234 | this.name = name;
235 | }
236 |
237 | public Date getBirthDate() {
238 | return birthDate;
239 | }
240 |
241 | public void setBirthDate(Date birthDate) {
242 | this.birthDate = birthDate;
243 | }
244 |
245 | @Override
246 | public String toString() {
247 | return String.format("User [id=%s, name=%s, birthDate=%s]", id, name, birthDate);
248 | }
249 |
250 | }
251 | ```
252 | ---
253 |
254 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/user/UserDaoService.java
255 |
256 | ```java
257 | package com.in28minutes.rest.webservices.restfulwebservices.user;
258 |
259 | import java.util.ArrayList;
260 | import java.util.Date;
261 | import java.util.List;
262 |
263 | import org.springframework.stereotype.Component;
264 |
265 | @Component
266 | public class UserDaoService {
267 | private static List users = new ArrayList<>();
268 |
269 | private static int usersCount = 3;
270 |
271 | static {
272 | users.add(new User(1, "Adam", new Date()));
273 | users.add(new User(2, "Eve", new Date()));
274 | users.add(new User(3, "Jack", new Date()));
275 | }
276 |
277 | public List findAll() {
278 | return users;
279 | }
280 |
281 | public User save(User user) {
282 | if (user.getId() == null) {
283 | user.setId(++usersCount);
284 | }
285 | users.add(user);
286 | return user;
287 | }
288 |
289 | public User findOne(int id) {
290 | for (User user : users) {
291 | if (user.getId() == id) {
292 | return user;
293 | }
294 | }
295 | return null;
296 | }
297 |
298 | }
299 | ```
300 | ---
301 |
302 | ### /src/main/java/com/in28minutes/rest/webservices/restfulwebservices/user/UserResource.java
303 |
304 | ```java
305 | package com.in28minutes.rest.webservices.restfulwebservices.user;
306 |
307 | import java.util.List;
308 |
309 | import org.springframework.beans.factory.annotation.Autowired;
310 | import org.springframework.web.bind.annotation.GetMapping;
311 | import org.springframework.web.bind.annotation.PathVariable;
312 | import org.springframework.web.bind.annotation.RestController;
313 |
314 | @RestController
315 | public class UserResource {
316 |
317 | @Autowired
318 | private UserDaoService service;
319 |
320 | @GetMapping("/users")
321 | public List retrieveAllUsers() {
322 | return service.findAll();
323 | }
324 |
325 | @GetMapping("/users/{id}")
326 | public User retrieveUser(@PathVariable int id) {
327 | return service.findOne(id);
328 | }
329 |
330 | }
331 | ```
332 | ---
333 |
334 | ### /src/main/resources/application.properties
335 |
336 | ```properties
337 | logging.level.org.springframework = info
338 | #This is not really needed as this is the default after 2.0.0.RELEASE
339 | spring.jackson.serialization.write-dates-as-timestamps=false
340 | spring.messages.basename=messages
341 | ```
342 | ---
343 |
344 | ### /src/test/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplicationTests.java
345 |
346 | ```java
347 | package com.in28minutes.rest.webservices.restfulwebservices;
348 |
349 | import org.junit.Test;
350 | import org.junit.runner.RunWith;
351 | import org.springframework.boot.test.context.SpringBootTest;
352 | import org.springframework.test.context.junit4.SpringRunner;
353 |
354 | @RunWith(SpringRunner.class)
355 | @SpringBootTest
356 | public class RestfulWebServicesApplicationTests {
357 |
358 | @Test
359 | public void contextLoads() {
360 | }
361 |
362 | }
363 | ```
364 | ---
365 |
--------------------------------------------------------------------------------
/02.restful-web-services/backup03-after-two-retrieve-user-services.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup03-after-two-retrieve-user-services.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup04-basic-create-service.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup04-basic-create-service.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup05-after-creating-delete-method-on-user-resource.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup05-after-creating-delete-method-on-user-resource.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup06-after-implementing-validation.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup06-after-implementing-validation.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup07-improving-documentation-with-swagger.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup07-improving-documentation-with-swagger.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup08-completed-filtering.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup08-completed-filtering.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup09-completed-versioning.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup09-completed-versioning.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup09-z-completed-security.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup09-z-completed-security.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup10-configure-jpa-and-repository.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup10-configure-jpa-and-repository.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup11-added-create-post-resource.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup11-added-create-post-resource.zip
--------------------------------------------------------------------------------
/02.restful-web-services/backup12-migrated-to-jpa.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/backup12-migrated-to-jpa.zip
--------------------------------------------------------------------------------
/02.restful-web-services/code-21July2017.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/in28minutes/spring-microservices/b88121cffa5a70a72880bc084db0bb35fa3756e5/02.restful-web-services/code-21July2017.zip
--------------------------------------------------------------------------------
/02.restful-web-services/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 |
--------------------------------------------------------------------------------
/02.restful-web-services/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 |
--------------------------------------------------------------------------------
/02.restful-web-services/notes.md:
--------------------------------------------------------------------------------
1 |
2 | # RESTful Web Services
3 |
4 | ## Social Media Application Resource Mappings
5 |
6 | ### User -> Posts
7 |
8 | - Retrieve all Users - GET /users
9 | - Create a User - POST /users
10 | - Retrieve one User - GET /users/{id} -> /users/1
11 | - Delete a User - DELETE /users/{id} -> /users/1
12 |
13 | - Retrieve all posts for a User - GET /users/{id}/posts
14 | - Create a posts for a User - POST /users/{id}/posts
15 | - Retrieve details of a post - GET /users/{id}/posts/{post_id}
16 |
17 | ## Error in the Log
18 | ```
19 | Resolved exception caused by Handler execution:
20 | org.springframework.http.converter.HttpMessageNotWritableException:
21 | No converter found for return value of type:
22 | class com.in28minutes.rest.webservices.restfulwebservices.HelloWorldBean
23 | ```
24 | - This happened because there were no getters in HelloWorldBean class
25 |
26 | ## Questions to Answer
27 |
28 | - What is dispatcher servlet?
29 | - Who is configuring dispatcher servlet?
30 | - What does dispatcher servlet do?
31 | - How does the HelloWorldBean object get converted to JSON?
32 | - Who is configuring the error mapping?
33 |
34 | - Mapping servlet: 'dispatcherServlet' to [/]
35 |
36 | - Mapped "{[/hello-world],methods=[GET]}" onto
37 | public java.lang.String com.in28minutes.rest.webservices.restfulwebservices.HelloWorldController.helloWorld()
38 | - Mapped "{[/hello-world-bean],methods=[GET]}" onto
39 | public com.in28minutes.rest.webservices.restfulwebservices.HelloWorldBean com.in28minutes.rest.webservices.restfulwebservices.HelloWorldController.helloWorldBean()
40 | - Mapped "{[/error]}" onto
41 | public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
42 | - Mapped "{[/error],produces=[text/html]}" onto
43 | public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
44 |
45 | ### Example Requests
46 |
47 | #### GET http://localhost:8080/users
48 | ```json
49 | [
50 | {
51 | "id": 1,
52 | "name": "Adam",
53 | "birthDate": "2017-07-19T04:40:20.796+0000"
54 | },
55 | {
56 | "id": 2,
57 | "name": "Eve",
58 | "birthDate": "2017-07-19T04:40:20.796+0000"
59 | },
60 | {
61 | "id": 3,
62 | "name": "Jack",
63 | "birthDate": "2017-07-19T04:40:20.796+0000"
64 | }
65 | ]
66 | ```
67 | #### GET http://localhost:8080/users/1
68 | ```json
69 | {
70 | "id": 1,
71 | "name": "Adam",
72 | "birthDate": "2017-07-19T04:40:20.796+0000"
73 | }
74 | ```
75 | #### POST http://localhost:8080/users
76 | ```json
77 | {
78 | "name": "Ranga",
79 | "birthDate": "2000-07-19T04:29:24.054+0000"
80 | }
81 | ```
82 |
83 | #### GET http://localhost:8080/users/1000
84 | - Get request to a non existing resource.
85 | - The response shows default error message structure auto configured by Spring Boot.
86 |
87 | ```json
88 | {
89 | "timestamp": "2017-07-19T05:28:37.534+0000",
90 | "status": 404,
91 | "error": "Not Found",
92 | "message": "id-500",
93 | "path": "/users/500"
94 | }
95 | ```
96 |
97 | #### GET http://localhost:8080/users/1000
98 | - Get request to a non existing resource.
99 | - The response shows a Customized Message Structure
100 | ```json
101 | {
102 | "timestamp": "2017-07-19T05:31:01.961+0000",
103 | "message": "id-500",
104 | "details": "Any details you would want to add"
105 | }
106 | ```
107 |
108 | #### POST http://localhost:8080/users with Validation Errors
109 |
110 | ##### Request
111 | ```json
112 | {
113 | "name": "R",
114 | "birthDate": "2000-07-19T04:29:24.054+0000"
115 | }
116 | ```
117 | ##### Response - 400 Bad Request
118 | ```json
119 | {
120 | "timestamp": "2017-07-19T09:00:27.912+0000",
121 | "message": "Validation Failed",
122 | "details": "org.springframework.validation.BeanPropertyBindingResult: 1 errors\nField error in object 'user' on field 'name': rejected value [R]; codes [Size.user.name,Size.name,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.name,name]; arguments []; default message [name],2147483647,2]; default message [Name should have atleast 2 characters]"
123 | }
124 | ```
125 | #### GET http://localhost:8080/users/1 with HATEOAS
126 | ```json
127 | {
128 | "id": 1,
129 | "name": "Adam",
130 | "birthDate": "2017-07-19T09:26:18.337+0000",
131 | "_links": {
132 | "all-users": {
133 | "href": "http://localhost:8080/users"
134 | }
135 | }
136 | }
137 | ```
138 | #### Internationalization
139 |
140 | ##### Configuration
141 | - LocaleResolver
142 | - Default Locale - Locale.US
143 | - ResourceBundleMessageSource
144 |
145 | ##### Usage
146 | - Autowire MessageSource
147 | - @RequestHeader(value = "Accept-Language", required = false) Locale locale
148 | - messageSource.getMessage("helloWorld.message", null, locale)
149 |
150 | ### XML Representation of Resources
151 |
152 | #### GET http://localhost:8080/users
153 | - Accept application/xml
154 | ```xml
155 |
156 | -
157 | 2
158 | Eve
159 | 2017-07-19T10:25:20.450+0000
160 |
161 | -
162 | 3
163 | Jack
164 | 2017-07-19T10:25:20.450+0000
165 |
166 | -
167 | 4
168 | Ranga
169 | 2017-07-19T10:25:20.450+0000
170 |
171 |
172 | ```
173 |
174 | #### POST http://localhost:8080/users
175 | - Accept : application/xml
176 | - Content-Type : application/xml
177 |
178 | Request
179 | ```xml
180 | -
181 | Ranga
182 | 2017-07-19T10:25:20.450+0000
183 |
184 | ```
185 |
186 | Response
187 | - Status - 201 Created
188 |
189 | ## Generating Swagger Documentation
190 |
191 |
192 | ```java
193 | public static final Contact DEFAULT_CONTACT = new Contact(
194 | "Ranga Karanam", "http://www.in28minutes.com", "in28minutes@gmail.com");
195 |
196 | public static final ApiInfo DEFAULT_API_INFO = new ApiInfo(
197 | "Awesome API Title", "Awesome API Description", "1.0",
198 | "urn:tos", DEFAULT_CONTACT,
199 | "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0");
200 |
201 | private static final Set DEFAULT_PRODUCES_AND_CONSUMES =
202 | new HashSet(Arrays.asList("application/json",
203 | "application/xml"));
204 |
205 | @Bean
206 | public Docket api() {
207 | return new Docket(DocumentationType.SWAGGER_2)
208 | .apiInfo(DEFAULT_API_INFO)
209 | .produces(DEFAULT_PRODUCES_AND_CONSUMES)
210 | .consumes(DEFAULT_PRODUCES_AND_CONSUMES);
211 | }
212 |
213 | ```
214 |
215 | ### Resource Method description
216 | ```java
217 | @GetMapping("/users/{id}")
218 | @ApiOperation(value = "Finds Users by id",
219 | notes = "Also returns a link to retrieve all users with rel - all-users")
220 | public Resource retrieveUser(@PathVariable int id) {
221 | ```
222 |
223 | ### API Model
224 | ```java
225 |
226 | @ApiModel(value="User Details", description="Contains all details of a user")
227 | public class User {
228 |
229 | @Size(min=2, message="Name should have atleast 2 characters")
230 | @ApiModelProperty(notes = "Name should have atleast 2 characters")
231 | private String name;
232 |
233 | @Past
234 | @ApiModelProperty(notes = "Birth Date should be in the Past")
235 | private Date birthDate;
236 | ```
237 |
238 | #### Filtering
239 |
240 | ##### Code
241 | ```java
242 | @JsonIgnoreProperties(value={"field1"})
243 | public class SomeBean {
244 |
245 | private String field1;
246 |
247 | @JsonIgnore
248 | private String field2;
249 |
250 | private String field3;
251 |
252 | ```
253 | ##### Response
254 | ```json
255 | {
256 | "field3": "value3"
257 | }
258 | ```
259 |
260 | ### Versioning
261 | - Media type versioning (a.k.a “content negotiation” or “accept header”)
262 | - GitHub
263 | - (Custom) headers versioning
264 | - Microsoft
265 | - URI Versioning
266 | - Twitter
267 | - Request Parameter versioning
268 | - Amazon
269 | - Factors
270 | - URI Pollution
271 | - Misuse of HTTP Headers
272 | - Caching
273 | - Can we execute the request on the browser?
274 | - API Documentation
275 | - No Perfect Solution
276 |
277 | #### More
278 | - https://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown
279 | - http://urthen.github.io/2013/05/09/ways-to-version-your-api/
280 | - http://stackoverflow.com/questions/389169/best-practices-for-api-versioning
281 | - http://www.lexicalscope.com/blog/2012/03/12/how-are-rest-apis-versioned/
282 | - https://www.3scale.net/2016/06/api-versioning-methods-a-brief-reference/
283 |
284 |
285 | #### Table Structure
286 |
287 | ```sql
288 | create table user (
289 | id integer not null,
290 | birth_date timestamp,
291 | name varchar(255),
292 | primary key (id)
293 | );
294 |
295 | create table post (
296 | id integer not null,
297 | description varchar(255),
298 | user_id integer,
299 | primary key (id)
300 | );
301 |
302 | alter table post
303 | add constraint post_to_user_foreign_key
304 | foreign key (user_id) references user;
305 | ```
--------------------------------------------------------------------------------
/02.restful-web-services/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.in28minutes.rest.webservices
7 | restful-web-services
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | restful-web-services
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.5.0
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 | 3.1.1
26 |
27 |
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-data-jpa
33 |
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-web
38 |
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-validation
44 |
45 |
46 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-actuator
54 |
55 |
56 |
57 | org.springframework.data
58 | spring-data-rest-hal-explorer
59 |
60 |
61 |
62 |
63 | org.springframework.boot
64 | spring-boot-starter-hateoas
65 |
66 |
67 |
78 |
79 |
80 | org.springdoc
81 | springdoc-openapi-ui
82 | 1.5.9
83 |
84 |
85 |
86 | org.springframework.boot
87 | spring-boot-devtools
88 | runtime
89 |
90 |
91 |
92 | com.h2database
93 | h2
94 | runtime
95 |
96 |
97 |
98 | org.springframework.boot
99 | spring-boot-starter-test
100 | test
101 |
102 |
103 |
104 |
105 |
106 |
107 | org.springframework.boot
108 | spring-boot-maven-plugin
109 |
110 |
111 |
112 |
113 |
114 |
115 | spring-snapshots
116 | Spring Snapshots
117 | https://repo.spring.io/snapshot
118 |
119 | true
120 |
121 |
122 |
123 | jfrog-snapshots
124 | JFROG Snapshots
125 | http://oss.jfrog.org/artifactory/oss-snapshot-local
126 |
127 | true
128 |
129 |
130 |
131 | spring-milestones
132 | Spring Milestones
133 | https://repo.spring.io/milestone
134 |
135 | false
136 |
137 |
138 |
139 |
140 |
141 |
142 | spring-snapshots
143 | Spring Snapshots
144 | https://repo.spring.io/snapshot
145 |
146 | true
147 |
148 |
149 |
150 | spring-milestones
151 | Spring Milestones
152 | https://repo.spring.io/milestone
153 |
154 | false
155 |
156 |
157 |
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/02.restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/RestfulWebServicesApplication.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.rest.webservices.restfulwebservices;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class RestfulWebServicesApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(RestfulWebServicesApplication.class, args);
11 | }
12 |
13 | // @Bean
14 | // public LocaleResolver localeResolver() {
15 | // AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
16 | // localeResolver.setDefaultLocale(Locale.US);
17 | // return localeResolver;
18 | // }
19 | }
20 |
--------------------------------------------------------------------------------
/02.restful-web-services/src/main/java/com/in28minutes/rest/webservices/restfulwebservices/exception/CustomizedResponseEntityExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.in28minutes.rest.webservices.restfulwebservices.exception;
2 |
3 | import java.util.Date;
4 |
5 | import org.springframework.http.HttpHeaders;
6 | import org.springframework.http.HttpStatus;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.web.bind.MethodArgumentNotValidException;
9 | import org.springframework.web.bind.annotation.ControllerAdvice;
10 | import org.springframework.web.bind.annotation.ExceptionHandler;
11 | import org.springframework.web.bind.annotation.RestController;
12 | import org.springframework.web.context.request.WebRequest;
13 | import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
14 |
15 | import com.in28minutes.rest.webservices.restfulwebservices.user.UserNotFoundException;
16 |
17 | @ControllerAdvice
18 | @RestController
19 | public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
20 |
21 | @ExceptionHandler(Exception.class)
22 | public final ResponseEntity