"Welcome To Ashok IT" "Spring Boot & Microservices" Topic : Rest API Mini Project Development Date : 02/01/2025 (Session - 98) _____________________________________________________________________________________________________________________________ Mini Project Setup ================== 1) Creating the Spring boot Starter Project using below starter * Web Starter * Oracle Driver * Lombok * ModelMapper(Collect From Maven Repoistory) * Spring Boot Dev Tools 2) Creating the Following packages to organize our classes in project com.ashokit |-> Application.java com.ashokit.constants |-> ApplicationConstants.java com.ashokit.controller |-> PersonController.java com.ashokit.dao |-> PersonDao.java com.ashokit.service |-> PersonService.java |-> PersonServiceImpl.java com.ashokit.dto |-> PersonDTO.java com.ashokit.entity |-> Person.java com.ashokit.exeception |-> ResourceNotFoundException.java com.ashokit.response |-> PageResponse.java 3) Source Code ============== PersonController.java ====================== package com.ashokit.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ashokit.dto.PersonDTO; import com.ashokit.exceptions.ResourceNotFoundException; import com.ashokit.service.PersonService; @RestController @RequestMapping("/api/persons") public class PersonController { @Autowired private PersonService personService; @GetMapping("/") public ResponseEntity> getAllPersonsInformation(){ List allPersons = personService.getAllPersons(); return new ResponseEntity>(allPersons,HttpStatus.OK); } @PostMapping("/") public ResponseEntity createNewPerson(@RequestBody PersonDTO personDTO){ try { PersonDTO savedPersonDTO = personService.createNewPerson(personDTO); return new ResponseEntity(savedPersonDTO,HttpStatus.CREATED); } catch (Exception e) { e.printStackTrace(); return new ResponseEntity("Error Occured While Created Person....",HttpStatus.INTERNAL_SERVER_ERROR); } } @PutMapping("/") public ResponseEntity modifyPersonDetails(@RequestBody PersonDTO personDTO){ try { PersonDTO updatedPersonDetails = personService.updatePersonDetails(personDTO); return new ResponseEntity(updatedPersonDetails,HttpStatus.OK); }catch(ResourceNotFoundException rnfe) { return new ResponseEntity(rnfe.getMessage(),HttpStatus.BAD_REQUEST); }catch(Exception e) { e.printStackTrace(); return new ResponseEntity(e.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR); } } @PatchMapping("/{personId}/{newLocation}") public ResponseEntity updatePersonLocationDetails(@PathVariable("personId") Integer personId, @PathVariable("newLocation") String newLocation){ try { PersonDTO updatedPersonDetails = personService.updatePersonLocationDetails(personId, newLocation); return new ResponseEntity(updatedPersonDetails,HttpStatus.OK); }catch(ResourceNotFoundException rnfe) { return new ResponseEntity(rnfe.getMessage(),HttpStatus.BAD_REQUEST); }catch(Exception e) { e.printStackTrace(); return new ResponseEntity(e.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR); } } @DeleteMapping("/{personId}") public ResponseEntity deletePersonDetails(@PathVariable("personId") Integer personId) { try { String deleteStatus = personService.deletePersonDetailsById(personId); return new ResponseEntity(deleteStatus, HttpStatus.OK); } catch (ResourceNotFoundException rnfe) { return new ResponseEntity(rnfe.getMessage(), HttpStatus.BAD_REQUEST); } catch (Exception e) { e.printStackTrace(); return new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } } PersonDao.java ============== package com.ashokit.dao; import org.springframework.data.jpa.repository.JpaRepository; import com.ashokit.entity.Person; public interface PersonDao extends JpaRepository { } PersonService.java ================== package com.ashokit.service; import java.util.List; import com.ashokit.dto.PersonDTO; public interface PersonService { //creating the new Person public PersonDTO createNewPerson(PersonDTO personDTO) throws Exception; //Getting all Persons public List getAllPersons(); //Updating the Person Details public PersonDTO updatePersonDetails(PersonDTO personDTO); //Updating the Person Location field only public PersonDTO updatePersonLocationDetails(Integer personId,String newLocation); //Deleting the Person Details public String deletePersonDetailsById(Integer personId); } PersonServiceImpl.java ======================= package com.ashokit.service; import java.time.LocalDate; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ashokit.dao.PersonDao; import com.ashokit.dto.PersonDTO; import com.ashokit.entity.Person; import com.ashokit.exceptions.ResourceNotFoundException; @Service public class PersonServiceImpl implements PersonService { @Autowired private PersonDao personDao; @Autowired private ModelMapper modelMapper; @Override public PersonDTO createNewPerson(PersonDTO personDTO) throws Exception { //Input Received as DTO and we need to Convert into Entity Class i.e.,Person Person personObj = this.modelMapper.map(personDTO, Person.class); //Setting Current Data While inserting the record personObj.setCreatedDate(LocalDate.now()); //save the personObj into Database Person savedPersonObj = personDao.save(personObj); //Converting Back from Entity Class Object into DTO Class Object PersonDTO savedPersonDetails = this.modelMapper.map(savedPersonObj, PersonDTO.class); return savedPersonDetails; } @Override public List getAllPersons() { List allPersons = personDao.findAll(); //converting from List into List List allPersonDtos = allPersons.stream().map(eachPerson ->{ return new PersonDTO(eachPerson.getId(),eachPerson.getName(), eachPerson.getLocation(),eachPerson.getEmailId(), eachPerson.getAddress(),eachPerson.getCreatedDate()); }).collect(Collectors.toList()); return allPersonDtos; } @Override public PersonDTO updatePersonDetails(PersonDTO personDTO)throws ResourceNotFoundException{ //Fetching Existing Person Details Optional existinPersonDetails = personDao.findById(personDTO.getId()); if(existinPersonDetails.isPresent()) { //convert from DTO to Entity Person personDetails = this.modelMapper.map(personDTO, Person.class); //updating the record personDetails.setCreatedDate(existinPersonDetails.get().getCreatedDate()); Person updatedPersonDetails = personDao.save(personDetails); //Converting from Entity To DTO PersonDTO updatePersonDTODetails = this.modelMapper.map(updatedPersonDetails, PersonDTO.class); return updatePersonDTODetails; }else { throw new ResourceNotFoundException("Person", "PersonID", personDTO.getId()); } } @Override public PersonDTO updatePersonLocationDetails(Integer personId, String newLocation) { //Fetching Existing Person Details Optional existingPersonDetails = personDao.findById(personId); if(existingPersonDetails.isPresent()) { Person personDetails= existingPersonDetails.get(); //Setting the newLocation into Old Location personDetails.setLocation(newLocation); //saving the person information Person updatedPersonDetails = personDao.save(personDetails); //converting from entity class into DTO Class return this.modelMapper.map(updatedPersonDetails, PersonDTO.class); }else { throw new ResourceNotFoundException("Person", "PersonID", personId); } } @Override public String deletePersonDetailsById(Integer personId) { //Fetching Existing Person Details Optional existingPersonDetails = personDao.findById(personId); if(existingPersonDetails.isPresent()) { personDao.deleteById(personId); return String.format("%s Deleted Successfully", personId); }else { throw new ResourceNotFoundException("Person", "PersonID", personId); } } } package com.ashokit.entity; import java.time.LocalDate; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; Person.java ============ @Entity @Table(name="ashokit_persons") @NoArgsConstructor @AllArgsConstructor @Getter @Setter @ToString public class Person { @Id @Column(name="person_id",nullable = false) @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(name="person_name") private String name; @Column(name="location") private String location; @Column(name="email_id") private String emailId; @Column(name="address") private String address; @Column(name="created_dt") @Temporal(TemporalType.DATE) private LocalDate createdDate; } PersonDTO.java ============== package com.ashokit.dto; import java.time.LocalDate; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class PersonDTO { private Integer id; private String name; private String location; private String emailId; private String address; private LocalDate createdDate; } ResourceNotFoundException.java =============================== package com.ashokit.exceptions; import lombok.Getter; import lombok.Setter; @Getter @Setter public class ResourceNotFoundException extends RuntimeException { private String resourceName; private String fieldName; private long fieldValue; public ResourceNotFoundException() { // TODO Auto-generated constructor stub } // parameterized Constructor public ResourceNotFoundException(String resourceName, String fieldName) { // Person not found with personId super(String.format("%s not found with %s ", resourceName, fieldName)); this.resourceName = resourceName; this.fieldName = fieldName; } // parameterized Constructor public ResourceNotFoundException(String resourceName, String fieldName, long fieldValue) { // Person not found with personId : 1256 super(String.format("%s not found with %s : %s", resourceName, fieldName, fieldValue)); this.resourceName = resourceName; this.fieldName = fieldName; this.fieldValue = fieldValue; } } Application.java ================= package com.ashokit; import org.modelmapper.ModelMapper; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } //Making ModelMapper as SpringBean @Bean public ModelMapper getModelMapper() { return new ModelMapper(); } } application.properties ====================== #server port changing server.port=8899 #Database Configuration spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe spring.datasource.username=system spring.datasource.password=manager #Hibernate Configuration spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true OUTPUT ====== 1) open the POSTMAN Tool and create new collection and add the below POST Request Post Request URL : http://localhost:8899/api/persons/ Request Body ============ { "name":"Satish", "location":"Delhi", "emailId":"satish.ashokit@gmail.com", "address":"ZZZZZZ" } OUTPUT (STATUS:201) ====== { "id": 52, "name": "Satish", "location": "Delhi", "emailId": "satish.ashokit@gmail.com", "address": "ZZZZZZ", "createdDate": "2023-09-13" } 2) Add one More Request for Existing PostMan Collection as below GET Request URL : http://localhost:8899/api/persons/ OUTPUT ====== [ { "id": 1, "name": "Mahesh", "location": "Hyderabad", "emailId": "mahesh.ashokit@gmail.com", "address": "Ameerpet", "createdDate": "2023-09-12" }, { "id": 2, "name": "Ashok", "location": "Hyderabad", "emailId": "ashokitschools@gmail.com", "address": "Ameerpet", "createdDate": "2023-09-12" }, { "id": 3, "name": "Suresh", "location": "Pune", "emailId": "suresh.ashokit@gmail.com", "address": "XYZ", "createdDate": "2023-09-12" }, { "id": 4, "name": "Ramesh", "location": "Delhi", "emailId": "ramesh.ashokit@gmail.com", "address": "ABCABCABC", "createdDate": "2023-09-12" }, { "id": 5, "name": "Rajesh", "location": "Pune", "emailId": "rajesh.ashokit@gmail.com", "address": "BBBB", "createdDate": "2023-09-12" }, { "id": 6, "name": "Nagesh", "location": "Delhi", "emailId": "nagesh.ashokit@gmail.com", "address": "ZZZZZZ", "createdDate": "2023-09-12" } ] 3) Add one More Request for existing COllection PUT Request URL ::: http://localhost:8899/api/persons/ RequesBody ========== { "id":4, "name":"Ramesh", "location":"Pune", "emailId": "ramesh.ashokit@gmail.com", "address":"ABCABCABC" } OUTPUT ====== { "id":4, "name":"Ramesh", "location":"Pune", "emailId": "ramesh.ashokit@gmail.com", "address":"ABCABCABC" "createdDate":2023-09-12 } Second Scenario =============== RequesBody ========== { "id":44, "name":"Ramesh", "location":"Pune", "emailId": "ramesh.ashokit@gmail.com", "address":"ABCABCABC" } OUTPUT (Status-400) ====== Person not found with PersonID : 44 4) Add one More Request for existing COllection patch Request URL ::: http://localhost:8899/api/persons/4/Delhi OUTPUT(STATUS-200) ====== { "id": 4, "name": "Ramesh", "location": "Delhi", "emailId": "ramesh.ashokit@gmail.com", "address": "ABCABCABC", "createdDate": "2023-09-12" } Second Scenario =============== patch Request URL ::: http://localhost:8899/api/persons/44/Delhi OUTPUT (Status-400) ====== Person not found with PersonID : 44 5) Add one More Request for existing COllection Delete Request URL :::http://localhost:8899/api/persons/52 Output ====== 52 Person Deleted Successfully Delete Request URL :::http://localhost:8899/api/persons/522 Output ====== Person not found with PersonID : 522 Source Code Available ::: https://github.com/maheshashokit/47_SBMS_Workspace_Apps/ Choose Project from list :::: 35_SpringBootRest_MiniProject_App Exception Handling in Spring MVC/SpringBootMVC/SpringRest/SpringBootRest ======================================================================== * In Spring framework/SpringBoot having two techniques to Handle Exceptions 1) Global Exception handling (or) Application level exception handler 2) Controller level exception handler * If exception handler method defined in seperate java class with annotation of "@RestControllerAdvice/@ControllerAdvice" will comes under Global exception handling. Example ======= package com.ashokit.exceptions; import java.time.LocalDateTime; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; //Global Exception Handling (or) Application level Exception Handling @RestControllerAdvice public class ApplicationErrorHandling { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity handlingResourceNotFoundException(ResourceNotFoundException rnfe){ ErrorDetails errorDetails = ErrorDetails.builder().errorTime(LocalDateTime.now()) .errorMessage(rnfe.getMessage()) .errorStatus("Resource Not Found.....") .build(); return new ResponseEntity(errorDetails,HttpStatus.NOT_FOUND); } @ExceptionHandler(Exception.class) public ResponseEntity handlingException(Exception e){ ErrorDetails errorDetails = ErrorDetails.builder().errorTime(LocalDateTime.now()) .errorMessage(e.getMessage()) .errorStatus("Problem Occured while Executing Resource") .build(); return new ResponseEntity(errorDetails,HttpStatus.INTERNAL_SERVER_ERROR); } } * If exception handler method(@ExceptionHandler) defined inside the controller then will comes under "Controller level exception handler". Example ======= //Controller level Exception Handler @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity handlingResourceNotFoundException(ResourceNotFoundException rnfe){ ErrorDetails errorDetails = ErrorDetails.builder().errorTime(LocalDateTime.now()) .errorMessage(rnfe.getMessage()) //Person not found with personId : 1256 .errorStatus("Resource Not Found.....") .build(); return new ResponseEntity(errorDetails,HttpStatus.NOT_FOUND); } +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++