Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Spring Framework 7: Beginner to Guru
## Spring 7 Rest MVC

This repository is for an example application built in my [Spring Framework 7 - Beginner to Guru](https://www.udemy.com/course/spring-framework-6-beginner-to-guru/?referralCode=2BD0B7B7B6B511D699A9) online course

Expand All @@ -9,20 +10,20 @@ As you work through the course, please feel free to fork this repository to your
to source code changes. If you encounter a problem you can compare your code to the lesson code. [See this link for help with compares](https://github.com/springframeworkguru/spring5webapp/wiki#getting-an-error-but-cannot-find-what-is-different-from-lesson-source-code)

## Spring Framework 7: Beginner to Guru Course Wiki
Got a question about your Spring Framework 7 course? [Checkout these FAQs!](https://github.com/springframeworkguru/spring5webapp/wiki)
Got a question about your Spring Framework 6 course? [Checkout these FAQs!](https://github.com/springframeworkguru/spring5webapp/wiki)

## Getting Your Development Environment Setup
### Recommended Versions
| Recommended | Reference | Notes |
|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Oracle Java 25 JDK | [Download](https://www.oracle.com/java/technologies/downloads/#java25) | Java 17 or higher is required for Spring Framework 6+. Java 25 is recommended for the course. |
| IntelliJ 2024 or Higher | [Download](https://www.jetbrains.com/idea/download/) | Ultimate Edition recommended. Students can get a free 120 trial license [here](https://github.com/springframeworkguru/spring5webapp/wiki/Which-IDE-to-Use%3F#how-do-i-get-the-free-120-day-trial-to-intellij-ultimate) |
| Maven 3.9.11 or higher | [Download](https://maven.apache.org/download.cgi) | [Installation Instructions](https://maven.apache.org/install.html) |
| Gradle 8.14 or higher | [Download](https://gradle.org/install/) | |
| Git 2.39 or higher | [Download](https://git-scm.com/downloads) | |
| Git GUI Clients | [Downloads](https://git-scm.com/downloads/guis) | Not required. But can be helpful if new to Git. SourceTree is a good option for Mac and Windows users. |
| Recommended | Reference | Notes |
|-------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Oracle Java 25 JDK | [Download](https://www.oracle.com/java/technologies/downloads/#java21) | Java 17 or higher is required for Spring Framework 6+. Java 25 is recommended for the course. |
| IntelliJ 2025 or Higher | [Download](https://www.jetbrains.com/idea/download/) | Ultimate Edition recommended. Students can get a free 120 trial license [here](https://github.com/springframeworkguru/spring5webapp/wiki/Which-IDE-to-Use%3F#how-do-i-get-the-free-120-day-trial-to-intellij-ultimate) |
| Maven 3.9.11 or higher | [Download](https://maven.apache.org/download.cgi) | [Installation Instructions](https://maven.apache.org/install.html) |
| Gradle 8.14 or higher | [Download](https://gradle.org/install/) | |
| Git 2.39 or higher | [Download](https://git-scm.com/downloads) | |
| Git GUI Clients | [Downloads](https://git-scm.com/downloads/guis) | Not required. But can be helpful if new to Git. SourceTree is a good option for Mac and Windows users. |

## All Spring Framework Guru Courses

### AI Courses
* [Spring AI: Beginner to Guru](https://www.udemy.com/course/spring-ai-beginner-to-guru/?referralCode=EF8DB31C723FFC8E2751)
* [Vibe Coding FullStake with Spring Boot and React Using Junie](https://www.udemy.com/course/jetbrains-junie/?referralCode=74BE8C5825CB296D2C57)
Expand All @@ -32,6 +33,7 @@ Got a question about your Spring Framework 7 course? [Checkout these FAQs!](http

### Spring Framework 6
* [Spring AI: Beginner to Guru](https://www.udemy.com/course/spring-ai-beginner-to-guru/?referralCode=EF8DB31C723FFC8E2751)
* [Spring AI: Beginner to Guru](https://www.udemy.com/course/spring-ai-beginner-to-guru/?referralCode=EF8DB31C723FFC8E2751)
* [Hibernate and Spring Data JPA: Beginner to Guru](https://www.udemy.com/course/hibernate-and-spring-data-jpa-beginner-to-guru/?referralCode=251C4C865302C7B1BB8F)
* [API First Engineering with Spring Boot](https://www.udemy.com/course/api-first-engineering-with-spring-boot/?referralCode=C6DAEE7338215A2CF276)
* [Introduction to Kafka with Spring Boot](https://www.udemy.com/course/introduction-to-kafka-with-spring-boot/?referralCode=15118530CA63AD1AF16D)
Expand Down
60 changes: 46 additions & 14 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,30 @@
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>guru.springframework</groupId>
<artifactId>spring-7-webapp</artifactId>
<artifactId>spring-7-rest-mvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-7-webapp</name>
<description>Spring 7 Web App</description>

<name>spring-7-rest-mvc</name>
<description>Spring 7 Rest MVC</description>
<properties>
<java.version>25</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa-test</artifactId>
<scope>test</scope>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand All @@ -46,10 +43,45 @@

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<!-- this configuration is needed for Java 23 and higher-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>


</project>
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package guru.springframework.spring7webapp;
package guru.springframework.spring7restmvc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Spring7WebappApplication {
public class Spring7RestMvcApplication {

public static void main(String[] args) {
SpringApplication.run(Spring7WebappApplication.class, args);
SpringApplication.run(Spring7RestMvcApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package guru.springframework.spring7restmvc.controller;

import guru.springframework.spring7restmvc.services.BeerService;
import guru.springframework.spring7restmvc.model.Beer;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;

/**
* Created by jt, Spring Framework Guru.
*/
@Slf4j
@RequiredArgsConstructor
@RestController
public class BeerController {

public static final String BEER_PATH = "/api/v1/beer";
public static final String BEER_PATH_ID = BEER_PATH + "/{beerId}";

private final BeerService beerService;

@PatchMapping(BEER_PATH_ID)
public ResponseEntity updateBeerPatchById(@PathVariable("beerId")UUID beerId, @RequestBody Beer beer){

beerService.patchBeerById(beerId, beer);

return new ResponseEntity(HttpStatus.NO_CONTENT);
}

@DeleteMapping(BEER_PATH_ID)
public ResponseEntity deleteById(@PathVariable("beerId") UUID beerId){

beerService.deleteById(beerId);

return new ResponseEntity(HttpStatus.NO_CONTENT);
}

@PutMapping(BEER_PATH_ID)
public ResponseEntity updateById(@PathVariable("beerId")UUID beerId, @RequestBody Beer beer){

beerService.updateBeerById(beerId, beer);

return new ResponseEntity(HttpStatus.NO_CONTENT);
}

@PostMapping(BEER_PATH)
public ResponseEntity handlePost(@RequestBody Beer beer){

Beer savedBeer = beerService.saveNewBeer(beer);

HttpHeaders headers = new HttpHeaders();
headers.add("Location", BEER_PATH + "/" + savedBeer.getId().toString());

return new ResponseEntity(headers, HttpStatus.CREATED);
}

@GetMapping(value = BEER_PATH)
public List<Beer> listBeers(){
return beerService.listBeers();
}


@GetMapping(value = BEER_PATH_ID)
public Beer getBeerById(@PathVariable("beerId") UUID beerId){

log.debug("Get Beer by Id - in controller");

return beerService.getBeerById(beerId).orElseThrow(NotFoundException::new);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package guru.springframework.spring7restmvc.controller;

import guru.springframework.spring7restmvc.model.Customer;
import guru.springframework.spring7restmvc.services.CustomerService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;

/**
* Created by jt, Spring Framework Guru.
*/

@RequiredArgsConstructor
@RestController
public class CustomerController {
public static final String CUSTOMER_PATH = "/api/v1/customer";
public static final String CUSTOMER_PATH_ID = CUSTOMER_PATH + "/{customerId}";

private final CustomerService customerService;

@PatchMapping(CUSTOMER_PATH_ID)
public ResponseEntity patchCustomerById(@PathVariable("customerId") UUID customerId,
@RequestBody Customer customer){

customerService.patchCustomerById(customerId, customer);

return new ResponseEntity(HttpStatus.NO_CONTENT);
}

@DeleteMapping(CUSTOMER_PATH_ID)
public ResponseEntity deleteCustomerById(@PathVariable("customerId") UUID customerId){

customerService.deleteCustomerById(customerId);

return new ResponseEntity(HttpStatus.NO_CONTENT);
}

@PutMapping(CUSTOMER_PATH_ID)
public ResponseEntity updateCustomerByID(@PathVariable("customerId") UUID customerId,
@RequestBody Customer customer){

customerService.updateCustomerById(customerId, customer);

return new ResponseEntity(HttpStatus.NO_CONTENT);
}

@PostMapping(CUSTOMER_PATH)
public ResponseEntity handlePost(@RequestBody Customer customer){
Customer savedCustomer = customerService.saveNewCustomer(customer);

HttpHeaders headers = new HttpHeaders();
headers.add("Location", CUSTOMER_PATH + "/" + savedCustomer.getId().toString());

return new ResponseEntity(headers, HttpStatus.CREATED);
}

@GetMapping(CUSTOMER_PATH)
public List<Customer> listAllCustomers(){
return customerService.getAllCustomers();
}

@GetMapping(value = CUSTOMER_PATH_ID)
public Customer getCustomerById(@PathVariable("customerId") UUID id){
return customerService.getCustomerById(id).orElseThrow(NotFoundException::new);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package guru.springframework.spring7restmvc.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
* Created by jt, Spring Framework Guru.
*/
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(NotFoundException.class)
public ResponseEntity handleNotFoundException(){
return ResponseEntity.notFound().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package guru.springframework.spring7restmvc.controller;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
* Created by jt, Spring Framework Guru.
*/
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Value Not Found")
public class NotFoundException extends RuntimeException {
public NotFoundException() {
}

public NotFoundException(String message) {
super(message);
}

public NotFoundException(String message, Throwable cause) {
super(message, cause);
}

public NotFoundException(Throwable cause) {
super(cause);
}

public NotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
43 changes: 43 additions & 0 deletions src/main/java/guru/springframework/spring7restmvc/model/Beer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package guru.springframework.spring7restmvc.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
import tools.jackson.databind.annotation.JsonDeserialize;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

/**
* Created by jt, Spring Framework Guru.
*/
@JsonDeserialize(builder = Beer.BeerBuilder.class)
@Builder
@Data
public class Beer {

@JsonProperty("id")
private UUID id;

@JsonProperty("version")
private Integer version;

@JsonProperty("beerName")
private String beerName;

@JsonProperty("beerStyle")
private BeerStyle beerStyle;

@JsonProperty("upc")
private String upc;

@JsonProperty("quantityOnHand")
private Integer quantityOnHand;

@JsonProperty("price")
private BigDecimal price;

private LocalDateTime createdDate;
private LocalDateTime updateDate;
}
Loading