Thursday 3 January 2019

swagger ui


swagger 2 ui

how to implement spring rest api with swagger 2 example 

Swagger 2 implementation with Spring

Spring and Swagger 2 play together very well.... Spring makes developing RESTful services ridiculously easy — and using Swagger makes documenting your RESTful services easy.... In this post, I’ll cover how to use Swagger 2 to generate REST API documentation for a Spring 



API Design

Design is the foundation of your API development. Swagger makes API design a breeze, with easy-to-use tools for developers, architects, and product owners.

API Development

Protocols, error handling, and code modularity are just some of the questions your teams need to address before building a great API. Swagger provides tools for quickly prototyping and building your API’s functionality.

API Documentation


Swagger takes the manual work out of API documentation, with a range of solutions for generating, visualizing, and maintaining API docs.

API Testing

Start your functional, security, and performance testing right from the OpenAPI Spec. Swagger tooling and the ReadyAPI platform make it easy to rapidly create, manage, & execute API tests in your pipeline.

API Mocking and Virtualization

Reduce dependencies in your development and testing cycles and stand-up realistic, dynamic mocks in seconds with Swagger and ServiceV Pro.

API Monitoring

Monitor API availability, speed, and functionality starting from your OpenAPI Specification (OAS) with AlertSite for OAS. Automate monitor creation and instantly track API behavior to ensure everything runs smoothly in production.

Below have example .

  1. Create a Configuration Class.

package com.xavient.configuration;


import javax.naming.NamingException;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jndi.JndiTemplate;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableWebMvc
@EnableSwagger2
@ComponentScan(basePackages = "com.xavient")
public class HelloWorldConfiguration extends WebMvcConfigurerAdapter {
@Bean
    public DataSource dataSource() throws NamingException {
        return (DataSource) new JndiTemplate().lookup("java:jboss/datasources/mysqldb");
    }
@Bean
public Docket api() {                
     return new Docket(DocumentationType.SWAGGER_2)          
       .select()                                       
       .apis(RequestHandlerSelectors.basePackage("com.xavient.controller"))
       .paths(PathSelectors.any())                     
       .build();
}
 
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
 
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}


2. Create Initialiser Class.

package com.xavient.configuration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { HelloWorldConfiguration.class };
    }
  
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }
  
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
    
   
}

3. Create Controller Class 

package com.xavient.controller;

import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
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 org.springframework.web.util.UriComponentsBuilder;

import com.xavient.model.User;
import com.xavient.service.UBUserService;
import com.xavient.service.UserService;
import com.xavient.serviceimpl.UBUserServiceImpl;

@RestController
@RequestMapping(value = "/myappuser")
public class HelloWorldRestController {
private static final Logger log = LoggerFactory.getLogger(UBUserServiceImpl.class);
@Autowired
UserService userService;  //Service which will do all data retrieval/manipulation work
@Autowired
UBUserService ubUserService;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "/user";
}
//-------------------Retrieve All Users--------------------------------------------------------
@RequestMapping(value = "/user", method = RequestMethod.GET)
public ResponseEntity<List<User>> listAllUsers() {
List<User> users = ubUserService.findAllUsers();
if(users.isEmpty()){
return new ResponseEntity<List<User>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
}
return new ResponseEntity<List<User>>(users, HttpStatus.OK);
}


//-------------------Retrieve Single User--------------------------------------------------------
@RequestMapping(value = "/user/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<User> getUser(@PathVariable("id") long id) {
log.info("Fetching User with id " + id);
User user = ubUserService.findById(id);
if (user == null) {
log.info("User with id " + id + " not found");
return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}

//-------------------Create a User--------------------------------------------------------
@RequestMapping(value = "/user", method = RequestMethod.POST)
public ResponseEntity<Void> createUser(@RequestBody User user, UriComponentsBuilder ucBuilder) {
log.info("Creating User " + user.getName());
if (ubUserService.isUserExist(user)) {
log.info("A User with name " + user.getName() + " already exist");
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}

ubUserService.saveUser(user);

HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri());
return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}

//------------------- Update a User --------------------------------------------------------
@RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
public ResponseEntity<User> updateUser(@PathVariable("id") long id, @RequestBody User user) {
log.info("Updating User " + id);
User currentUser = ubUserService.findById(id);
if (currentUser==null) {
log.info("User with id " + id + " not found");
return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
}

currentUser.setName(user.getName());
currentUser.setAge(user.getAge());
currentUser.setSalary(user.getSalary());
ubUserService.updateUser(currentUser);
return new ResponseEntity<User>(currentUser, HttpStatus.OK);
}

//------------------- Delete a User --------------------------------------------------------
@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
public ResponseEntity<User> deleteUser(@PathVariable("id") long id) {
log.info("Fetching & Deleting User with id " + id);

User user = ubUserService.findById(id);
if (user == null) {
log.info("Unable to delete. User with id " + id + " not found");
return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
}

ubUserService.deleteUserById(id);
return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
}

//------------------- Delete All User --------------------------------------------------------
@RequestMapping(value = "/user ", method = RequestMethod.DELETE)
public ResponseEntity<User> deleteAllUsers() {
log.info("Deleting All Users");

ubUserService.deleteAllUsers();
return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
}

}

4 . Create Dao 

public interface UserDao {

User findById(long id);
User findByName(String name);
void saveUser(User user);
void updateUser(User user);
void deleteUserById(long id);

List<User> findAllUsers(); 
void deleteAllUsers();
public boolean isUserExist(User user);
}

5. Create Dao Implementation class.

package com.xavient.daoimp;

import java.util.List;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.xavient.dao.UserDao;
import com.xavient.model.User;

@Repository
public class UserDaoImpl implements UserDao {
private static final Logger log = LoggerFactory.getLogger(UserDaoImpl.class);
JdbcTemplate jdbcTemplate;
boolean flag;
    @Autowired    // tried @Autowired also
    public void setDataSource(DataSource datasource) {
        this.jdbcTemplate = new JdbcTemplate(datasource);
    }
@Override
public User findById(long id) {
log.info("Querying for user records by Id");
User user = new User();
jdbcTemplate.query("SELECT id,name,age,salary FROM user WHERE id = ?",new Object[] { id }, rs -> {
            if(rs.next()){
                user.setId(rs.getLong("id"));
                user.setName(rs.getString("name"));
                user.setAge(rs.getInt("age"));
                user.setSalary(rs.getDouble("salary"));
                return user;
            }
            else {
                return null;
            }
    });
return user;
}

@Override
public User findByName(String name) {
log.info("Querying for user records by Name");
User user = new User();
jdbcTemplate.query("SELECT id,name,age,salary FROM user WHERE name = ?",new Object[] { name }, rs -> {
            if(rs.next()){
                user.setId(rs.getLong("id"));
                user.setName(rs.getString("name"));
                user.setAge(rs.getInt("age"));
                user.setSalary(rs.getDouble("salary"));
                return user;
            }
            else {
                return null;
            }
    });
return user;
}


@Override
public void saveUser(User user) {
jdbcTemplate.update("INSERT INTO user(id,name,age,salary) VALUES (?,?,?,?)",user.getId(),user.getName(),user.getAge(),user.getSalary());
// jdbcTemplate.update("INSERT INTO user(name) VALUES (?)", user);
}

@Override
public void updateUser(User user) {
String sqlUpdate = "UPDATE user set name=?,age=?,salary=? where id=?";
        jdbcTemplate.update(sqlUpdate, user.getName(),user.getAge(),user.getSalary(), user.getId());

}

@Override
public void deleteUserById(long id) {
jdbcTemplate.update("delete from user where id=?",id);

}

@Override
public List<User> findAllUsers() {
log.info("Querying for user records where name like 'Josh %':");
        List<User> user=(List<User>) jdbcTemplate.query("SELECT id,name,age,salary FROM user",
                (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name"), rs.getInt("age"),rs.getDouble("salary")));
        return user;
}

@Override
public void deleteAllUsers() {
jdbcTemplate.execute("delete from user");

}

@Override
public boolean isUserExist(User user) {
log.info("Querying for user records by Name");
User u = new User();
jdbcTemplate.query("SELECT id,name,age,salary FROM user WHERE id = ?",new Object[] { user.getId() }, rs -> {
            if(rs.next()){
                u.setId(rs.getLong("id"));
                u.setName(rs.getString("name"));
                u.setAge(rs.getInt("age"));
                u.setSalary(rs.getDouble("salary"));
             
                return true;
            }
            else {
            flag=false;
                return false;
            }
    });
return flag;
}
}

6. Create Model Class.\

package com.xavient.model;

public class User {

private long id;
private String name;
private int age;
private double salary;

public User(){
id=0;
}
public User(long id, String name, int age, double salary){
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
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 getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public double getSalary() {
return salary;
}

public void setSalary(double salary) {
this.salary = salary;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (id != other.id)
return false;
return true;
}

@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age
+ ", salary=" + salary + "]";
}


}
8. Create Service Interface 

public interface UserService {
void createTable();
User findById(long id);
User findByName(String name);
void saveUser(User user);
void updateUser(User user);
void deleteUserById(long id);

List<User> findAllUsers(); 
void deleteAllUsers();
public boolean isUserExist(User user);
}


public interface UBUserService {
void createTable();
User findById(long id);
User findByName(String name);
void saveUser(User user);
void updateUser(User user);
void deleteUserById(long id);

List<User> findAllUsers(); 
void deleteAllUsers();
public boolean isUserExist(User user);
}


9. Create Service Impl.
package com.xavient.serviceimpl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xavient.model.User;
import com.xavient.service.UserService;

@Service("userService")
@Transactional
public class UserServiceImpl implements UserService{
private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
private static final AtomicLong counter = new AtomicLong();
    JdbcTemplate jdbcTemplate;

    @Autowired    // tried @Autowired also
    public void setDataSource(DataSource datasource) {
        this.jdbcTemplate = new JdbcTemplate(datasource);
    }
private static List<User> users;
static{
users= populateDummyUsers();
}

public List<User> findAllUsers() {
//createTable();
return users;
}
public User findById(long id) {
for(User user : users){
if(user.getId() == id){
return user;
}
}
return null;
}
public User findByName(String name) {
for(User user : users){
if(user.getName().equalsIgnoreCase(name)){
return user;
}
}
return null;
}
public void saveUser(User user) {
user.setId(counter.incrementAndGet());
users.add(user);
}

public void updateUser(User user) {
int index = users.indexOf(user);
users.set(index, user);
}

public void deleteUserById(long id) {
for (Iterator<User> iterator = users.iterator(); iterator.hasNext(); ) {
    User user = iterator.next();
    if (user.getId() == id) {
        iterator.remove();
    }
}
}

public boolean isUserExist(User user) {
return findByName(user.getName())!=null;
}

private static List<User> populateDummyUsers(){
List<User> users = new ArrayList<User>();
users.add(new User(counter.incrementAndGet(),"Sam",30, 70000));
users.add(new User(counter.incrementAndGet(),"Tom",40, 50000));
users.add(new User(counter.incrementAndGet(),"Jerome",45, 30000));
users.add(new User(counter.incrementAndGet(),"Silvia",50, 40000));
return users;
}

public void deleteAllUsers() {
users.clear();
}

@Override
public void createTable() {
log.info("Creating tables");
System.out.println("hello");
      //  jdbcTemplate.execute("DROP TABLE user IF EXISTS");
        jdbcTemplate.execute("CREATE TABLE user(" +
                "id long, name VARCHAR(255), age int, salary double)");

        // Split up the array of whole names into an array of first/last names
        List<Object[]> splitUpNames = Arrays.asList("John Woo", "Jeff Dean", "Josh Bloch", "Josh Long").stream()
                .map(name -> name.split(","))
                .collect(Collectors.toList());

        // Use a Java 8 stream to print out each tuple of the list
        splitUpNames.forEach(name -> log.info(String.format("Inserting user record for %s ", name[0])));

        // Uses JdbcTemplate's batchUpdate operation to bulk load data
        jdbcTemplate.batchUpdate("INSERT INTO user(name) VALUES (?)", splitUpNames);

        log.info("Querying for user records where name = 'Josh':");
        jdbcTemplate.query(
                "SELECT id,name, age,salary FROM user WHERE name = ?", new Object[] { "Josh" },
                (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name"), rs.getInt("age"),rs.getDouble("salary"))
        ).forEach(customer -> log.info(customer.toString()));
    }

}

package com.xavient.serviceimpl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xavient.daoimp.UserDaoImpl;
import com.xavient.model.User;
import com.xavient.service.UBUserService;

@Service
public class UBUserServiceImpl implements UBUserService {
private static final Logger log = LoggerFactory.getLogger(UBUserServiceImpl.class);
@Autowired
UserDaoImpl userDao;
@Override
public void createTable() {
// TODO Auto-generated method stub

}

@Override
public User findById(long id) {
log.info("findById method called whith id :"+id);
return userDao.findById(id);
}

@Override
public User findByName(String name) {
log.info("findByName method called whith Name :"+name);
return userDao.findByName(name);
}

@Override
public void saveUser(User user) {
log.info("saveUser method called whith user :"+user);
userDao.saveUser(user);

}

@Override
public void updateUser(User user) {
log.info("updateUser method called whith user :"+user);
userDao.updateUser(user);

}

@Override
public void deleteUserById(long id) {
log.info("deleteUserById method called whith user :"+id);
userDao.deleteUserById(id);
}

@Override
public List<User> findAllUsers() {
log.info("findAllUsers method called");
return userDao.findAllUsers();
}

@Override
public void deleteAllUsers() {
log.info("deleteAllUsers method called");
userDao.deleteAllUsers();
}

@Override
public boolean isUserExist(User user) {
log.info("isUserExist method called");
return userDao.isUserExist(user);
}

}

10. Create Log4j.xml to maintain the log

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<appender name="file" class="org.apache.log4j.RollingFileAppender">
    <param name="append" value="false" />
    <param name="maxFileSize" value="10MB" />
    <param name="maxBackupIndex" value="10" />
    <param name="file" value="D:/stsworkspace/restdemo/logs/restdemo.log" />
    <layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
    </layout>
</appender>
<!-- Application Loggers -->
<logger name="com.ub.myapp">
<level value="info" />
</logger>
<!-- 3rdparty Loggers -->
<logger name="org.springframework.core">
<level value="info" />
</logger>
<logger name="org.springframework.beans">
<level value="info" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>

<logger name="org.springframework.web">
<level value="info" />
</logger>

<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="file" />
<appender-ref ref="console" />
</root>
</log4j:configuration>

11. Create deployment descriptor to build the project 
pom.xml

<?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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ub</groupId>
<artifactId>myapp</artifactId>
<name>myapp</name>
<packaging>war</packaging>
<version>1.0</version>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.0.RELEASE</org.springframework-version>
<jackson.version>2.9.4</jackson.version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>

<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>

<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>

<!-- Servlet -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<!-- <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency> -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.197</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.hateoas/spring-hateoas -->
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.24.0.RELEASE</version>
</dependency>

</dependencies>
<build>
<plugins>
<!-- <plugin> <artifactId>maven-eclipse-plugin</artifactId> <version>3.2</version> 
<configuration> <additionalProjectnatures> <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature> 
</additionalProjectnatures> <additionalBuildcommands> <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand> 
</additionalBuildcommands> <downloadSources>true</downloadSources> <downloadJavadocs>true</downloadJavadocs> 
</configuration> </plugin> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>myapp</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
<finalName>myapp</finalName>
</build>
</project>

 To test the swagger out put type the below URL in browser address bar 

http://localhost:8080/myapp/swagger-ui.html#/



javascript asynchronous callback

JAVASCRIPT ASYNCHRONOUS PROGRAMMING AND CALLBACKS


JavaScript is synchronous by default, and is single threaded. This means that code cannot create new threads and run in parallel. Find out what asynchronous code means and how it looks like



  • Asynchronicity in Programming Languages
  • JavaScript
  • Callbacks
  • Handling errors in callbacks
  • The problem with callbacks
  • Alternatives to callbacks

ASYNCHRONICITY IN PROGRAMMING LANGUAGES

Computers are asynchronous by design.

Asynchronous means that things can happen independently of the main program flow.

In the current consumer computers, every program runs for a specific time slot, and then it stops its execution to let another program continue its execution. This thing runs in a cycle so fast that’s impossible to notice, and we think our computers run many programs simultaneously, but this is an illusion (except on multiprocessor machines).

Programs internally use interrupts, a signal that’s emitted to the processor to gain the attention of the system.

I won’t go into the internals of this, but just keep in mind that it’s normal for programs to be asynchronous, and halt their execution until they need attention, and the computer can execute other things in the meantime. When a program is waiting for a response from the network, it cannot halt the processor until the request finishes.

Normally, programming languages are synchronous, and some provide a way to manage asynchronicity, in the language or through libraries. C, Java, C#, PHP, Go, Ruby, Swift, Python, they are all synchronous by default. Some of them handle async by using threads, spawning a new process.

JAVASCRIPT

JavaScript is synchronous by default and is single threaded. This means that code cannot create new threads and run in parallel.

Lines of code are executed in series, one after another, for example:
const a = 1
const b = 2
const c = a * b
console.log(c)
doSomething()
But JavaScript was born inside the browser, its main job, in the beginning, was to respond to user actions, like onClick, onMouseOver, onChange, onSubmit and so on. How could it do this with a synchronous programming model?

The answer was in its environment. The browser provides a way to do it by providing a set of APIs that can handle this kind of functionality.

More recently, Node.js introduced a non-blocking I/O environment to extend this concept to file access, network calls and so on.


CALLBACKS

You can’t know when a user is going to click a button, so what you do is, you define an event handler for the click event. This event handler accepts a function, which will be called when the event is triggered:

document.getElementById('button').addEventListener('click', () => {
  //item clicked
})

This is the so-called callback.

A callback is a simple function that’s passed as a value to another function, and will only be executed when the event happens. We can do this because JavaScript has first-class functions, which can be assigned to variables and passed around to other functions (called higher-order functions)

It’s common to wrap all your client code in a load event listener on the window object, which runs the callback function only when the page is ready:
window.addEventListener('load', () => {
  //window loaded
  //do what you want
})

Callbacks are used everywhere, not just in DOM events.
One common example is by using timers:

setTimeout(() => {
  // runs after 2 seconds
}, 2000)

XHR requests also accept a callback, in this example by assigning a function to a property that will be called when a particular event occurs (in this case, the state of the request changes):

const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
  if (xhr.readyState === 4) {
    xhr.status === 200 ? console.log(xhr.responseText) : console.error('error')
  }
}
xhr.open('GET', 'https://yoursite.com')
xhr.send()

HANDLING ERRORS IN CALLBACKS

How do you handle errors with callbacks? One very common strategy is to use what Node.js adopted: the first parameter in any callback function is the error object: error-first callbacks

If there is no error, the object is null. If there is an error, it contains some description of the error and other information.

fs.readFile('/file.json', (err, data) => {
  if (err !== null) {
    //handle error
    console.log(err)
    return
  }

  //no errors, process data
  console.log(data)
})

THE PROBLEM WITH CALLBACKS

Callbacks are great for simple cases!

However every callback adds a level of nesting, and when you have lots of callbacks, the code starts to be complicated very quickly:

window.addEventListener('load', () => {
  document.getElementById('button').addEventListener('click', () => {
    setTimeout(() => {
      items.forEach(item => {
        //your code here
      })
    }, 2000)
  })
})
This is just a simple 4-levels code, but I’ve seen much more levels of nesting and it’s not fun.

How do we solve this?

 ALTERNATIVES TO CALLBACKS

Starting with ES6, JavaScript introduced several features that help us with asynchronous code that do not involve using callbacks:

Promises (ES6)
Async/Await (ES8)