This project will demonstrate how to create Cascading Dropdown List with Ajax in Spring MVC Framework and Spring Data JPA
package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringMVCFramework {
public static void main(String[] args) {
SpringApplication.run(SpringMVCFramework.class, args);
}
}
package com.demo.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.demo.services.CityService;
import com.demo.services.CountryService;
import com.demo.services.StateService;
import com.google.gson.Gson;
@Controller
@RequestMapping(value = { "", "demo" })
public class DemoController {
@Autowired
private CountryService countryService;
@Autowired
private StateService stateService;
@Autowired
private CityService cityService;
@RequestMapping(method = RequestMethod.GET)
public String index(ModelMap modelMap) {
modelMap.put("countries", countryService.findAll());
return "demo/index";
}
@ResponseBody
@RequestMapping(value = "loadStatesByCountry/{id}", method = RequestMethod.GET)
public String loadStatesByCountry(@PathVariable("id") int id) {
Gson gson = new Gson();
return gson.toJson(stateService.findByCountry(id));
}
@ResponseBody
@RequestMapping(value = "loadCitiesByState/{id}", method = RequestMethod.GET)
public String loadCitiesByState(@PathVariable("id") int id) {
Gson gson = new Gson();
return gson.toJson(cityService.findByState(id));
}
}
package com.demo.entities;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "country")
public class Country implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Set<State> states = new HashSet<State>(0);
public Country() {
}
public Country(String name) {
this.name = name;
}
public Country(String name, Set<State> states) {
this.name = name;
this.states = states;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "name", nullable = false, length = 250)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "country")
public Set<State> getStates() {
return this.states;
}
public void setStates(Set<State> states) {
this.states = states;
}
}
package com.demo.entities;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "state")
public class State implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private Country country;
private String name;
private Set<City> cities = new HashSet<City>(0);
public State() {
}
public State(Country country, String name) {
this.country = country;
this.name = name;
}
public State(Country country, String name, Set<City> cities) {
this.country = country;
this.name = name;
this.cities = cities;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "countryId", nullable = false)
public Country getCountry() {
return this.country;
}
public void setCountry(Country country) {
this.country = country;
}
@Column(name = "name", nullable = false, length = 250)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "state")
public Set<City> getCities() {
return this.cities;
}
public void setCities(Set<City> cities) {
this.cities = cities;
}
}
package com.demo.entities;
import java.io.Serializable;
public class StateEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
public StateEntity() {
}
public StateEntity(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.demo.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "city")
public class City implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private State state;
private String name;
public City() {
}
public City(State state, String name) {
this.state = state;
this.name = name;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "stateId", nullable = false)
public State getState() {
return this.state;
}
public void setState(State state) {
this.state = state;
}
@Column(name = "name", nullable = false, length = 250)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
package com.demo.entities;
import java.io.Serializable;
public class CityEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
public CityEntity() {
}
public CityEntity(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.demo.repositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.demo.entities.Country;
@Repository("countryRepository")
public interface CountryRepository extends CrudRepository<Country, Integer> {
}
package com.demo.repositories;
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.demo.entities.State;
import com.demo.entities.StateEntity;
@Repository("stateRepository")
public interface StateRepository extends CrudRepository<State, Integer> {
@Query("select new com.demo.entities.StateEntity(id, name) from State where country.id = :id")
public List<StateEntity> findByCountry(@Param("id") int id);
}
package com.demo.repositories;
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.demo.entities.City;
import com.demo.entities.CityEntity;
@Repository("cityRepository")
public interface CityRepository extends CrudRepository<City, Integer> {
@Query("select new com.demo.entities.CityEntity(id, name) from City where state.id = :id")
public List<CityEntity> findByState(@Param("id") int id);
}
package com.demo.services;
import com.demo.entities.Country;
public interface CountryService {
public Iterable<Country> findAll();
public Country find(int id);
}
package com.demo.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.demo.entities.Country;
import com.demo.repositories.CountryRepository;
@Service("countryService")
public class CountryServiceImpl implements CountryService {
@Autowired
private CountryRepository countryRepository;
@Override
public Iterable<Country> findAll() {
return countryRepository.findAll();
}
@Override
public Country find(int id) {
return countryRepository.findById(id).get();
}
}
package com.demo.services;
import java.util.List;
import com.demo.entities.StateEntity;
public interface StateService {
public List<StateEntity> findByCountry(int id);
}
package com.demo.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.demo.entities.StateEntity;
import com.demo.repositories.StateRepository;
@Service("stateService")
public class StateServiceImpl implements StateService {
@Autowired
private StateRepository stateRepository;
@Override
public List<StateEntity> findByCountry(int id) {
return stateRepository.findByCountry(id);
}
}
package com.demo.services;
import java.util.List;
import com.demo.entities.CityEntity;
public interface CityService {
public List<CityEntity> findByState(int id);
}
package com.demo.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.demo.entities.CityEntity;
import com.demo.repositories.CityRepository;
@Service("cityService")
public class CityServiceImpl implements CityService {
@Autowired
private CityRepository cityRepository;
@Override
public List<CityEntity> findByState(int id) {
return cityRepository.findByState(id);
}
}
spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp
spring.mvc.static-path-pattern=/resources/**
server.port=9596
spring.datasource.url= jdbc:mysql://localhost:3306/demo5
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Cascading Dropdown List with Ajax in Spring MVC Framework and Spring Data JPA</title>
<script src="${pageContext.request.contextPath }/resources/js/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#comboboxCountry').on('change', function(){
var countryId = $(this).val();
$.ajax({
type: 'GET',
url: '${pageContext.request.contextPath }/demo/loadStatesByCountry/' + countryId,
success: function(result) {
var result = JSON.parse(result);
var s = '';
for(var i = 0; i < result.length; i++) {
s += '<option value="' + result[i].id + '">' + result[i].name + '</option>';
}
$('#comboboxState').html(s);
}
});
});
$('#comboboxState').on('change', function(){
var stateId = $(this).val();
$.ajax({
type: 'GET',
url: '${pageContext.request.contextPath }/demo/loadCitiesByState/' + stateId,
success: function(result) {
var result = JSON.parse(result);
var s = '';
for(var i = 0; i < result.length; i++) {
s += '<option value="' + result[i].id + '">' + result[i].name + '</option>';
}
$('#comboboxCity').html(s);
}
});
});
});
</script>
</head>
<body>
<form>
<table>
<tr>
<td>Country</td>
<td>
<select id="comboboxCountry" style="width:200px">
<c:forEach var="country" items="${countries }">
<option value="${country.id }">${country.name }</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<td>State</td>
<td>
<select id="comboboxState" style="width:200px"></select>
</td>
</tr>
<tr>
<td>City</td>
<td>
<select id="comboboxCity" style="width:200px"></select>
</td>
</tr>
</table>
</form>
</body>
</html>
<?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>2.1.10.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>CascadingDropDownListWithSpringMVC</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>CascadingDropDownListWithSpringMVC</name>
<description>Cascading Drop Down List with Spring MVC and Spring Data JPA</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- JSTL tag lib -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>