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
16 changes: 16 additions & 0 deletions HELP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Getting Started

### Reference Documentation
For further reference, please consider the following sections:

* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/4.0.3-SNAPSHOT/maven-plugin)
* [Create an OCI image](https://docs.spring.io/spring-boot/4.0.3-SNAPSHOT/maven-plugin/build-image.html)

### Maven Parent overrides

Due to Maven's design, elements are inherited from the parent POM to the project POM.
While most of the inheritance is fine, it also inherits unwanted elements like `<license>` and `<developers>` from the parent.
To prevent this, the project POM contains empty overrides for these elements.
If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# SpringBootMvc
SorokinP

88 changes: 88 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Spring Boot MVC demo</description>

<properties>
<java.version>21</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.20.1</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>

</project>
13 changes: 13 additions & 0 deletions src/main/java/com/example/demo/DemoApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.demo;

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

@SpringBootApplication
public class DemoApplication {

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

}
43 changes: 43 additions & 0 deletions src/main/java/com/example/demo/controller/PetController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.example.demo.controller;

import com.example.demo.model.PetDto;
import com.example.demo.model.UserDto;
import com.example.demo.service.PetService;
import com.example.demo.service.UserService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/pets")
public class PetController {

private final PetService petService;

@GetMapping(path = "/{id}")
public ResponseEntity<PetDto> getPet(@PathVariable long id) {
return ResponseEntity.status(HttpStatus.OK).body(petService.getPet(id));
}

@PostMapping(path = "/add")
public ResponseEntity<PetDto> createPet(@Valid @RequestBody PetDto petDto) {
return ResponseEntity.status(HttpStatus.CREATED).body(petService.createPet(petDto));
}

@PutMapping(path = "/update")
public ResponseEntity<Long> updatePet(@Valid @RequestBody PetDto petDto) {
return ResponseEntity.status(HttpStatus.OK).body(petService.updatePet(petDto));
}

@DeleteMapping(path = "/delete/{id}")
public ResponseEntity<Long> deletePet(@PathVariable long id) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(petService.deletePet(id));
}

}
41 changes: 41 additions & 0 deletions src/main/java/com/example/demo/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.example.demo.controller;

import com.example.demo.model.UserDto;
import com.example.demo.service.UserService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/users")
public class UserController {

private final UserService userService;

@GetMapping(path = "/{id}")
public ResponseEntity<UserDto> getUser(@PathVariable long id) {
return ResponseEntity.status(HttpStatus.OK).body(userService.getUser(id));
}

@PostMapping(path = "/add")
public ResponseEntity<UserDto> createUser(@Valid @RequestBody UserDto userDto) {
return ResponseEntity.status(HttpStatus.CREATED).body(userService.createUser(userDto));
}

@PutMapping(path = "/update")
public ResponseEntity<UserDto> updateUser(@Valid @RequestBody UserDto userDto) {
return ResponseEntity.status(HttpStatus.OK).body(userService.updateUser(userDto));
}

@DeleteMapping(path = "/delete/{id}")
public ResponseEntity<Long> deleteUser(@PathVariable long id) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(userService.deleteUser(id));
}

}
21 changes: 21 additions & 0 deletions src/main/java/com/example/demo/exception/BadRequestException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.demo.exception;

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


@Getter
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class BadRequestException extends RuntimeException {

private final Long resourceId;
private final String operation;

public BadRequestException(Long resourceId, String message, String operation) {
super(message);
this.resourceId = resourceId;
this.operation = operation;
}

}
20 changes: 20 additions & 0 deletions src/main/java/com/example/demo/exception/ErrorMessageResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.demo.exception;

import lombok.Getter;
import java.time.Instant;


@Getter
public class ErrorMessageResponse {

private final String error;
private final Instant timestamp;
private final String operation;

public ErrorMessageResponse(String error, String operation) {
this.error = error;
this.timestamp = Instant.now();
this.operation = operation;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.example.demo.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorMessageResponse> handleValidationException(MethodArgumentNotValidException ex) {
var error = new ErrorMessageResponse("Неверный аргумент: " + ex.getMessage(), "Controller input");
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorMessageResponse> handleResourceNotFoundException(ResourceNotFoundException ex) {
var error = new ErrorMessageResponse(ex.getMessage(), ex.getOperation());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}

@ExceptionHandler(BadRequestException.class)
public ResponseEntity<ErrorMessageResponse> handleBadRequestException(BadRequestException ex) {
var error = new ErrorMessageResponse(ex.getMessage(), ex.getOperation());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorMessageResponse> handleException(Exception ex) {
var error = new ErrorMessageResponse(ex.getMessage(), "Generic");
if (ex instanceof HttpMessageNotReadableException) {
error = new ErrorMessageResponse(ex.getMessage(), "Controller input");
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.demo.exception;

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


@Getter
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {

private final Long resourceId;
private final String operation;

public ResourceNotFoundException(Long resourceId, String message, String operation) {
super(message);
this.resourceId = resourceId;
this.operation = operation;
}

}
22 changes: 22 additions & 0 deletions src/main/java/com/example/demo/model/PetDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.demo.model;

import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;


@Getter
@Setter
@RequiredArgsConstructor
@AllArgsConstructor
public class PetDto {
@NotNull
private Long id;
@NotNull
private String name;
@Positive
private Long userId;
}
31 changes: 31 additions & 0 deletions src/main/java/com/example/demo/model/UserDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.demo.model;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import java.util.List;


@Getter
@Setter
@RequiredArgsConstructor
@AllArgsConstructor
public class UserDto {
@NotNull
private Long id;
@NotNull
private String name;
@Email
private String email;
@Positive
private Integer age;
@NotNull
private List<PetDto> pets;
}

//public record UserDto(Long id, String name, String email, Integer age, List<PetDto> pets) {}
Loading