SpringBoot
How to test private method? If you have somewhat of a legacy Java application, and you're not allowed to change the visibility of your methods, the best way to test private methods is to use reflection.
Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);
And for fields:
Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
Contents
- 1 SpringBoot - Maven - Pom.xml
- 2 SpringBoot - Application Boot
- 3 SpringBoot - Controller Class - GET, POST, PUT, DELETE
- 4 SpringBoot - Service Class
- 5 Spring Cloud
- 6 API Gateway
- 7 Netflix
- 8 Others
- 9 JPA - Java Persistance API
- 10 Error Handling for REST with Spring & SpringBoot
- 11 Spring Boot Interview Questions and Answers
SpringBoot - Maven - Pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.oasissoftech.springboot</groupId>
<artifactId>SpringBoot-Tutorial-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot-Tutorial-1</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
to get latest Spring Boot Starter Parent pom.xml configurations visit : https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent
to get latest Spring Boot Web Starter pom.xml configurations visit : https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
SpringBoot - Application Boot
Spring Boot application startup class :
package com.oasissofttech.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootTutorial1App {
public static void main(String[] args) {
SpringApplication.run(SpringBootTutorial1App.class,args);
}
}
SpringBoot - Controller Class - GET, POST, PUT, DELETE
package com.oasissofttech.springboot.brand;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BrandController {
@Autowired
private BrandService brandService;
@RequestMapping("/brands")
public List<Brand> getAllBrands() {
return brandService.getAllBrands();
}
@RequestMapping("/brand/{brandId}")
public Brand getBrand(@PathVariable("brandId") int id) {
return brandService.getBrand(id);
}
@RequestMapping(method=RequestMethod.POST,value="/brands")
public void addBrand(@RequestBody Brand brand) {
brandService.addBrand(brand);
}
@RequestMapping(method=RequestMethod.PUT,value="/brands/{id}")
public void addBrand(@RequestBody Brand brand,@PathVariable int id) {
brandService.updateBrand(brand,id);
}
@RequestMapping(method=RequestMethod.DELETE,value="/brands/{id}")
public void deleteBrand(@PathVariable int id) {
brandService.deleteBrand(id);
}
}
SpringBoot - Service Class
package com.oasissofttech.springboot.brand;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public class BrandService {
private List<Brand> brands = new ArrayList<>(Arrays.asList(
new Brand(1,"Aston Martin","(1913–present)"),
new Brand(2,"Bentley","(1919–present)"),
new Brand(3,"Jaguar Land Rover","(2013-present)"),
new Brand(4,"Lotus","(1952–present)"),
new Brand(5,"Rolls Royce","(1904–present)")
));
public List<Brand> getAllBrands(){
return brands;
}
public Brand getBrand(int id) {
return brands.stream().filter(b->b.getId()==id).findFirst().get();
}
public void addBrand(Brand brand) {
brands.add(brand);
}
public void updateBrand(Brand brand, int id) {
int c = brands.size();
for(int i=0;i<c;i++) {
if(brands.get(i).getId()==id) {
brands.set(i, brand);
return;
}
}
}
public void deleteBrand(int id) {
brands.removeIf(t->t.getId()==id);
}
}
Spring Cloud
API Gateway
The API Gateway encapsulates the internal system architecture and provides an API that is tailored to each client. It might have other responsibilities such as authentication, monitoring, load balancing, caching, request shaping and management, and static response handling.
Netflix
Euroka
Chaos Monkey
Others
package com.oasissofttech.springboot.brand;
public class Brand {
private int id;
private String brandName;
private String description;
public Brand() {
}
public Brand(int id, String brandName, String description) {
super();
this.id = id;
this.brandName = brandName;
this.description = description;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Common application properties
application.properties file
#===========================================
#=== application.properties file content ===
server.port=3000 #server HTTP port.
#===================end=====================
springboot properties file manual : https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
JPA - Java Persistance API
ORM - Object Relational Mapping
Spring Data JPA
manual : https://docs.spring.io/spring-data/jpa/docs/current/reference/html/
Features
- Sophisticated support to build repositories based on Spring and JPA
- Support for Querydsl predicates and thus type-safe JPA queries
- Transparent auditing of domain class
- Pagination support, dynamic query execution, ability to integrate custom data access code
- Validation of @Query annotated queries at bootstrap time
- Support for XML based entity mapping
- JavaConfig based repository configuration by introducing @EnableJpaRepositories.
Gradle Dependencies
dependencies {
compile 'org.springframework.data:spring-data-jpa:2.0.10.RELEASE'
}repositories {
maven {
url 'https://repo.spring.io/libs-release'
}
}
Making CRUD Operation with Repository
@Repository
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.lse.library.model.Books;
@Repository
public interface LseLibraryRepository extends CrudRepository<Books,Long> {
//ID,ISBN_NO,SUBJECT,AUTHOR,TITLE
@Query(value="SELECT * FROM LSE_LIBRARY_BOOKS s where s.SHELF_NO = :shelfNo", nativeQuery = true)
List<Books> findBooksByShelfNo(@Param("shelfNo") String shelfNo);
//LOCATION_NO
@Query(value="SELECT * FROM LSE_LIBRARY_BOOKS s where s.ISBN_NO = :IsbnNo", nativeQuery = true)
Books findLocationByIsbnNo(@Param("IsbnNo") String IsbnNo);
//STACK_NO,SHELF_NO
@Query(value="SELECT * FROM LSE_LIBRARY_BOOKS s where s.SUBJECT like CONCAT('%',:subject,'%')", nativeQuery = true)
List<Books> findStacksAndShelvesBySubject(@Param("subject") String subject);
@Query(value="SELECT count(*) ID FROM LSE_LIBRARY_BOOKS s where s.SHELF_NO = :shelfNo", nativeQuery = true)
int findCountOfBooksByShelfNo(@Param("shelfNo") String shelfNo);
//SHELF_NO
@Query(value="SELECT * FROM LSE_LIBRARY_BOOKS s where s.SUBJECT = :subject1 or s.SUBJECT = :subject2 ", nativeQuery = true)
List<Books> findShelvesBySubjects(@Param("subject1") String subject1,@Param("subject2") String subject2);
//SHELF_NO
@Query(value="SELECT * FROM LSE_LIBRARY_BOOKS s where s.SUBJECT = :subject", nativeQuery = true)
List<Books> findShelvesByOneSubject(@Param("subject") String subject);
}
BrandRepository interface
package com.oasissofttech.springboot.brand;
import org.springframework.data.repository.CrudRepository;
@Repository
public interface BrandRepository extends CrudRepository<Brand, Integer> {
}
BrandService Class
package com.oasissofttech.springboot.brand;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BrandService {
@Autowired
private BrandRepository brandRepository;
public List<Brand> getAllBrands(){
List<Brand> brands = new ArrayList<>();
brandRepository.findAll()
.forEach(brands::add);
return brands;
}
public Optional<Brand> getBrand(int id) {
return brandRepository.findById(id);
}
public void addBrand(Brand brand) {
brandRepository.save(brand);
}
public void updateBrand(Brand brand, int id) {
brandRepository.save(brand);
}
public void deleteBrand(int id) {
brandRepository.deleteById(id);
}
}
What is WireMock?
https://www.ontestautomation.com/getting-started-with-wiremock/
From the WireMock.org website: WireMock is a flexible library for stubbing and mocking web services. Unlike general purpose mocking tools it works by creating an actual HTTP server that your code under test can connect to as it would a real web service. It supports HTTP response stubbing, request verification, proxy/intercept, record/playback of stubs and fault injection, and can be used from within a unit test or deployed into a test environment. Although it’s written in Java, there’s also a JSON API so you can use it with pretty much any language out there.
Error Handling for REST with Spring & SpringBoot
Overview
Before Spring 3.2, the two main approaches to handling exceptions in a Spring MVC application were: HandlerExceptionResolver or the @ExceptionHandler annotation. Both of these have some clear downsides.
After 3.2 we now have the new @ControllerAdvice annotation to address the limitations of the previous two solutions.
All of these do have one thing in common – they deal with the separation of concerns very well. The app can throw exception normally to indicate a failure of some kind – exceptions which will then be handled separately.
The Controller level @ExceptionHandler
The New @ControllerAdvice (Spring 3.2 And Above)
Spring 3.2 brings support for a global @ExceptionHandler with the new @ControllerAdvice annotation. This enables a mechanism that breaks away from the older MVC model and makes use of ResponseEntity along with the type safety and flexibility of @ExceptionHandler:
@ControllerAdvice
public class RestResponseEntityExceptionHandler
extends ResponseEntityExceptionHandler {
@ExceptionHandler(value
= { IllegalArgumentException.class, IllegalStateException.class })
protected ResponseEntity<Object> handleConflict(
RuntimeException ex, WebRequest request) {
String bodyOfResponse = "This should be application specific";
return handleExceptionInternal(ex, bodyOfResponse,
new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}
The new annotation allows the multiple scattered @ExceptionHandler from before to be consolidated into a single, global error handling component.
The actual mechanism is extremely simple but also very flexible:
- it allows full control over the body of the response as well as the status code
- it allows mapping of several exceptions to the same method, to be handled together
- it makes good use of the newer RESTful ResposeEntity response
One thing to keep in mind here is to match the exceptions declared with @ExceptionHandler with the exception used as the argument of the method. If these don’t match, the compiler will not complain – no reason it should, and Spring will not complain either.
However, when the exception is actually thrown at runtime, the exception resolving mechanism will fail with:
java.lang.IllegalStateException: No suitable resolver for argument [0] [type=...]
HandlerMethod details: ...
http://www.baeldung.com/exception-handling-for-rest-with-spring
Spring Boot Interview Questions and Answers
- Spring Boot Interview Questions and Answers-1 - http://www.javainuse.com/spring/SpringBootInterviewQuestions
- Spring Boot Interview Questions and Answers-2 - http://www.springboottutorial.com/spring-boot-interview-questions
What is OAuth2? How to implement it using Spring Boot?
Spring Boot + OAuth2 implementation : http://www.javainuse.com/spring/spring-boot-oauth-introduction
OAuth (Open Authorization) is a simple way to publish and interact with protected data. It is an open standard for token-based authentication and authorization on the Internet. It allows an end user's account information to be used by third-party services, such as Facebook, without exposing the user's password.
The OAuth specification describes five grants for acquiring an access token:
- Authorization code grant
- Implicit grant
- Resource owner credentials grant
- Client credentials grant
- Refresh token grant