Mega Menu

Showing posts with label SpringBoot. Show all posts
Showing posts with label SpringBoot. Show all posts

Monday, April 13, 2020

SpringBoot - Loggers

By default slf4jcan be used for logging.

Changes required -
1. Define Logger object in the class
2. Use the Logger with appropriate level (info, debug, etc.)
3. Set the file name and path in application.properties to write to a specific file.

application.properties
logging.file.name=logs/restapp.log 
     
all the logs will be writted to restapp.log file under logs folder, of the application.

To change/restrict the log level to be printed in the log files, set the below property in application.properties file

application.properties    
      logging.level.root=error
          or
      logging.level.root=info
      logging.level.com.raj.*=error                         (To enable for a custom package)
           or 
      logging.level.root=info
      logging.level.org.springframework.*=error      (To enable for a framework)


Controller class

package com.raj.springweb.controllers;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;

import com.raj.springweb.model.Product;
import com.raj.springweb.repos.ProductJpaRepository;

@RestController
public class RestProductController {
   
    @Autowired
    ProductJpaRepository productRepo;
   
    private static final Logger LOGGER = LoggerFactory.getLogger(RestProductController.class);
   
    @RequestMapping (value="/productapi/allproducts", method=RequestMethod.GET)
    public List findAllProducts () {
        LOGGER.info("Find All Products");
        return productRepo.findAll();
    }
}

 

SpringBoot Profiles

Profiles enable springboot to maintain environment specific configurations (host names, data source, credentials, properties). This is achieved by creating multiple application.properties files for each of the environment and either enable the profile through a property in default application.xml or a JVM argument.

Eg: application.properties               
      application-DEV.properties
      application-QA.properties

By defining this property in default application.properties, all the properties in application-DEV.properties are loaded.
       spring.profiles.active=DEV 

or even this can be enabled through a JVM property / VM Argument in RunConfigurations
     -Dspring.profiles.active=DEV

SpringBoot Sample Rest Service and Rest Client Code

1. SpringWebApplication.java

package com.raj.springweb;

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

@SpringBootApplication
public class SpringwebApplication {

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

}


2. Simple HelloWorld Rest service Example.

package com.raj.springweb.controllers;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestHelloWorldController {
   
   
    @RequestMapping (value="/helloapi/helloworld", method=RequestMethod.GET)
    public String helloworld () {
        return new String("Hello World");
    }

}



3. Product Service example, which needs below set of files to be created as well.

package com.raj.springweb.controllers;

import java.util.List;
import javax.websocket.server.PathParam;
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;
import com.raj.springweb.model.Product;
import com.raj.springweb.repos.ProductJpaRepository;

@RestController
public class RestProductController {
   
    @Autowired
    ProductJpaRepository productRepo;
   
    @RequestMapping (value="/productapi/allproducts", method=RequestMethod.GET)
    public List findAllProducts () {
        return productRepo.findAll();
    }
   
    @RequestMapping (value="/productapi/product/byId/{id}", method=RequestMethod.GET)
    public Product findProductbyId (@PathVariable("id") long id) {
        return productRepo.findById(id).get();
    }
       
    @RequestMapping (value="/productapi/createproduct", method=RequestMethod.POST)
    public Product createProduct (@RequestBody Product product) {
        return productRepo.save(product);
    }
   
    @RequestMapping (value="/productapi/updateproduct", method=RequestMethod.PUT)
    public Product updateProduct (@RequestBody Product product) {
        return productRepo.save(product);
    }
   
    @RequestMapping (value="/productapi/deleteproduct/byId/{id}", method=RequestMethod.DELETE)
    public void deleteProduct (@PathVariable long id) {
        productRepo.deleteById(id);
    }
   
}


4. Entity class Product with auto-generated primarykey (ID)
 
package com.raj.springweb.model;

import java.math.BigDecimal;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    long id;
   
    String name;
   
    String description;
   
    BigDecimal price;
   

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}


5. Repository Interface

package com.raj.springweb.repos;
import org.springframework.data.jpa.repository.JpaRepository;
import com.raj.springweb.model.Product;

public interface ProductJpaRepository extends JpaRepository {

}


6. Test class with Rest Client

package com.raj.springweb;

import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import com.raj.springweb.model.Product;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import org.junit.Test;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringwebApplicationTests {


    @Test
    public void testGetProduct() {
        RestTemplate restTemplate = new RestTemplate();
        Product product = restTemplate.getForObject("http://localhost:8080/service/productapi/product/byId/4", Product.class);
        assertNotNull(product);
        assertEquals("prod4", product.getName());
    }

   
    @Test
    public void testPostProduct() {
        RestTemplate restTemplate = new RestTemplate();
        Product product = new Product();
        product.setName("prod5");
        product.setDescription("Product Five");
        product.setPrice(BigDecimal.valueOf(12.50));
       
        Product newProd = restTemplate.postForObject("http://localhost:8080/service/productapi/createproduct", product, Product.class);
        assertNotNull(newProd);
        assertEquals("prod5", newProd.getName());
    }
   
 }

          

7. application.xml

server.servlet.context-path=/service/

spring.datasource.url=jdbc:mysql://localhost:3306/springboottestdb
spring.datasource.username=root
spring.datasource.password=password
 

8. POM.xml


 

SpringBoot - Show SQL property

Below property in application properties can be enabled to show the sqls executed in the log file.

application.properties
spring.jpa.show-sql=true

SpringBoot Spring Data JPA with H2 InMemory DB - Sample Code

1. SpringdatajpaApplication.java 

package com.raj.springdatajpa;

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

@SpringBootApplication
public class SpringdatajpaApplication {

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

}


2. Entity class Student.java

package com.raj.springdatajpa.model;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity

public class Student {

    @Id
    private long id;
    private String name;   
    private int testScore;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getTestScore() {
        return testScore;
    }
    public void setTestScore(int testScore) {
        this.testScore = testScore;
    } 
}


3. Repository Interface

package com.raj.springdatajpa.repos;
import org.springframework.data.jpa.repository.JpaRepository;
import com.raj.springdatajpa.model.Student;

public interface StudentRepository extends JpaRepository {

}


5. JUNIT Test class

package com.raj.springdatajpa;
import static org.junit.Assert.*;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.raj.springdatajpa.model.Student;
import com.raj.springdatajpa.repos.StudentRepository;

@RunWith(SpringRunner.class)
@SpringBootTest

public class SpringdatajpaApplicationTests {
   
    @Autowired
    private StudentRepository stdRepo;
   

    @Test

    public void testSaveStudent() {
        Student student = new Student();
        student.setId(1l);
        student.setName("raj");
        student.setTestScore(100);
        stdRepo.save(student);

        Student savedStudent = stdRepo.findById(1l).get();
        assertEquals(savedStudent.getName(), student.getName());
       
    }
}

 

6. POM.xml
 

SpringBoot Basics

Below data as of March 2020 and may have been changed at a later date**

IDE for development - Spring Tool Suite (STS)

Default Embedded Server - Tomcat

During a starter project creation, the pom.xml loads all the mandatory libraries with appropriate and compatible versions.
     Open pom.xml with 'Maven POM Editor' in STS and view the tab 'Effective POM' to check all the libraries included and their versions.

Key Features -
1. Auto Configuration of Dispatcher Servlet, Data source and Transaction Manager, etc.
2. Spring Boot Starters with Module Availability and Version Compatability. Example starters -
                        spring-boot-starter-parent
                        spring-boot-starter-web
                        spring-boot-starter-data-jpa
 3. Embedded Servlet Container. Eg:
                        Tomcat (default)
                         Jetty
                         Undertow
4. SpringBootActuators end points to view -
                         autoconfig
                         mappings
                         info
                         health
                         metrics
5. Class with the annotation @SpringBootApplication has the main method which will be run when the boot is executed. Example -
    @SpringBootApplication
public class SpringwebApplication {

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

}


6. Class with annotation @SpringBootTest is the test class to execute the spring boot application.
     Example -
        package com.raj.springdatajpa;
       import static org.junit.Assert.assertEquals;
       import static org.junit.Assert.assertNotNull;
       import org.junit.Test;
       import org.junit.runner.RunWith;
       import org.springframework.beans.factory.annotation.Autowired;
       import org.springframework.boot.test.context.SpringBootTest;
       import org.springframework.test.context.junit4.SpringRunner;
       import com.raj.springdatajpa.model.Student;
       import com.raj.springdatajpa.repos.StudentRepository;

       @RunWith(SpringRunner.class)
       @SpringBootTest
       public class SpringdatajpaApplicationTests {
   
          @Autowired
          private StudentRepository stdRepo;
   
          @Test
          public void testSaveStudent() {
            Student student = new Student();
            student.setId(1l);
            student.setName("raj");
            student.setTestScore(100);
            stdRepo.save(student);
            Student savedStudent = stdRepo.findById(1l).get();
            assertEquals(savedStudent.getName(), student.getName());
       
       }
   }

                                
  7. Sample POM with spring-starter-parent
         
       


By default this may not include the dependency for junit and needs the below to be added to as to use the junit.