├── .gitignore ├── README.md ├── build.gradle └── src └── main ├── java └── com │ └── codetutr │ ├── controller │ └── PersonController.java │ ├── domain │ └── Person.java │ ├── service │ ├── PersonService.java │ └── PersonServiceImpl.java │ └── springconfig │ └── WebConfig.java └── webapp └── WEB-INF ├── view ├── formPage.jsp └── home.jsp └── web.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.jar 3 | *.war 4 | *.ear 5 | 6 | .DS_Store 7 | 8 | bin 9 | build 10 | 11 | .settings 12 | .gradle 13 | 14 | .classpath 15 | 16 | .project 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | spring-mvc-ajax 2 | ======================== 3 | 4 | Sample Spring MVC Application demonstrating JSON AJAX requests with jQuery front-end and Spring MVC back-end. 5 | 6 | This code is a companion to a tutorial, _Easy REST-Based JSON Services with @ResponseBody_, that used to live on my Java/Spring tutorials site, codetutr.com. 7 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'war' 2 | apply plugin: 'jetty' 3 | apply plugin: 'eclipse-wtp' 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | dependencies { 10 | providedCompile 'javax.servlet:servlet-api:2.5' 11 | compile 'org.springframework:spring-webmvc:3.2.2.RELEASE' 12 | compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.12' 13 | runtime 'javax.servlet:jstl:1.2' 14 | } 15 | 16 | 17 | jettyRunWar.contextPath = '' //otherwise defaults to name of project -------------------------------------------------------------------------------- /src/main/java/com/codetutr/controller/PersonController.java: -------------------------------------------------------------------------------- 1 | package com.codetutr.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | 11 | import com.codetutr.domain.Person; 12 | import com.codetutr.service.PersonService; 13 | 14 | @Controller 15 | @RequestMapping("api") 16 | public class PersonController { 17 | 18 | PersonService personService; 19 | 20 | @Autowired 21 | public PersonController(PersonService personService) { 22 | this.personService = personService; 23 | } 24 | 25 | @RequestMapping("person/random") 26 | @ResponseBody 27 | public Person randomPerson() { 28 | return personService.getRandom(); 29 | } 30 | 31 | @RequestMapping("person/{id}") 32 | @ResponseBody 33 | public Person getById(@PathVariable Long id) { 34 | return personService.getById(id); 35 | } 36 | 37 | /* same as above method, but is mapped to 38 | * /api/person?id= rather than /api/person/{id} 39 | */ 40 | @RequestMapping(value="person", params="id") 41 | @ResponseBody 42 | public Person getByIdFromParam(@RequestParam("id") Long id) { 43 | return personService.getById(id); 44 | } 45 | 46 | /** 47 | * Saves new person. Spring automatically binds the name 48 | * and age parameters in the request to the person argument 49 | * @param person 50 | * @return String indicating success or failure of save 51 | */ 52 | @RequestMapping(value="person", method=RequestMethod.POST) 53 | @ResponseBody 54 | public String savePerson(Person person) { 55 | personService.save(person); 56 | return "Saved person: " + person.toString(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/codetutr/domain/Person.java: -------------------------------------------------------------------------------- 1 | package com.codetutr.domain; 2 | 3 | 4 | public class Person { 5 | 6 | private String name; 7 | private Integer age; 8 | 9 | public String getName() { 10 | return name; 11 | } 12 | 13 | public void setName(String name) { 14 | this.name = name; 15 | } 16 | 17 | public Integer getAge() { 18 | return age; 19 | } 20 | 21 | public void setAge(Integer age) { 22 | this.age = age; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "Person [name=" + name + ", age=" + age + "]"; 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/codetutr/service/PersonService.java: -------------------------------------------------------------------------------- 1 | package com.codetutr.service; 2 | 3 | import com.codetutr.domain.Person; 4 | 5 | public interface PersonService { 6 | public Person getRandom(); 7 | public Person getById(Long id); 8 | public void save(Person person); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/codetutr/service/PersonServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.codetutr.service; 2 | 3 | import java.util.Random; 4 | 5 | import org.springframework.stereotype.Service; 6 | 7 | import com.codetutr.domain.Person; 8 | 9 | @Service 10 | public class PersonServiceImpl implements PersonService { 11 | 12 | String[] names = {"Nikolaus Otto", "Robert Ford", "Gottlieb Daimler", "Lt. General Masaharu Homma"}; 13 | 14 | @Override 15 | public Person getRandom() { 16 | Person person = new Person(); 17 | person.setName(randomName()); 18 | person.setAge(randomAge()); 19 | return person; 20 | } 21 | 22 | @Override 23 | public Person getById(Long id) { 24 | Person person = new Person(); 25 | person.setName(names[id.intValue()]); 26 | person.setAge(50); 27 | return person; 28 | } 29 | 30 | @Override 31 | public void save(Person person) { 32 | // Save person to database ... 33 | } 34 | 35 | private Integer randomAge() { 36 | Random random = new Random(); 37 | return 10 + random.nextInt(100); 38 | } 39 | 40 | private String randomName() { 41 | Random random = new Random(); 42 | return names[random.nextInt(names.length)]; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/codetutr/springconfig/WebConfig.java: -------------------------------------------------------------------------------- 1 | package com.codetutr.springconfig; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.ComponentScan; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 7 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 9 | import org.springframework.web.servlet.view.InternalResourceViewResolver; 10 | 11 | @Configuration 12 | @EnableWebMvc 13 | @ComponentScan(basePackages="com.codetutr") 14 | public class WebConfig extends WebMvcConfigurerAdapter { 15 | 16 | /** 17 | * Since we don't have any controller logic, simpler to just 18 | * define controller for page using View Controller. Note: 19 | * had to extend WebMvcConfigurerAdapter to get this functionality 20 | * @param registry 21 | */ 22 | @Override 23 | public void addViewControllers(ViewControllerRegistry registry) { 24 | registry.addViewController("/").setViewName("home"); 25 | } 26 | 27 | @Bean 28 | public InternalResourceViewResolver viewResolver() { 29 | InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 30 | resolver.setPrefix("/WEB-INF/view/"); 31 | resolver.setSuffix(".jsp"); 32 | return resolver; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/formPage.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 3 | 4 | 5 | 6 | 7 | Sample Application 8 | 9 | 17 | 18 | 19 | 20 |
21 | 22 |

Create Person!

23 |
${message}
24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | 32 |
33 | 34 | 35 | 36 | Select Sex 37 | Male 38 | Female 39 | 40 |
41 | 42 | 43 | 44 |
45 | 46 | 47 | Select Newsletter Frequency: 48 | 49 | ${frequency} 50 | 51 | 52 |
53 | 54 |
55 | 56 |
57 | 58 |

59 |
60 |

Random Person Generator

61 | 62 |
63 |
64 | 65 | 66 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/home.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 3 | 4 | 5 | 6 | 7 | Spring MVC - Ajax 8 | 9 | 18 | 19 | 20 | 21 |
22 | 23 |

Person Page

24 |

This page demonstrates Spring MVC's powerful Ajax functionality. Retrieve a 25 | random person, retrieve a person by ID, or save a new person, all without page reload. 26 |

27 | 28 |

Random Person Generator

29 |

30 |
31 | 32 |
33 | 34 |

Get By ID

35 |
36 |
Please enter a valid ID in range 0-3
37 | 38 |

39 |
40 |
41 | 42 |
43 | 44 |

Submit new Person

45 |
46 | 47 | 48 |
49 | 50 | 51 | 52 |
53 |

54 |
55 |
56 |
57 | 58 | 59 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | sample 8 | 9 | org.springframework.web.servlet.DispatcherServlet 10 | 11 | 12 | contextClass 13 | org.springframework.web.context.support.AnnotationConfigWebApplicationContext 14 | 15 | 16 | contextConfigLocation 17 | com.codetutr.springconfig 18 | 19 | 20 | 21 | 22 | sample 23 | / 24 | 25 | 26 | 27 | / 28 | 29 | 30 | --------------------------------------------------------------------------------