├── LICENSE ├── README.md ├── pom.xml └── src └── main ├── java └── com │ └── mkyong │ ├── config │ └── SpringWebConfig.java │ ├── servlet3 │ └── MyWebInitializer.java │ └── web │ ├── controller │ ├── AjaxController.java │ └── WelcomeController.java │ ├── jsonview │ └── Views.java │ └── model │ ├── AjaxResponseBody.java │ ├── SearchCriteria.java │ └── User.java ├── resources └── logback.xml └── webapp ├── WEB-INF └── views │ └── jsp │ └── welcome.jsp └── resources └── core ├── css └── bootstrap.min.css └── js ├── bootstrap.min.js └── jquery.1.10.2.min.js /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Yong Mook Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Spring 4 MVC Ajax Example 2 | =============================== 3 | Template for Spring 4 MVC + jQuery Ajax + Jackson2, using Maven build tool. 4 | 5 | ###1. Technologies used 6 | * Spring 4.2.2.RELEASE 7 | * Jackson 2.6.3 8 | * jQuery 1.10.2 9 | * Boostrap 3 10 | * Maven 3 11 | 12 | ###2. To Run this project locally 13 | ```shell 14 | $ git clone https://github.com/mkyong/spring4-mvc-ajax-example 15 | $ mvn jetty:run 16 | ``` 17 | Access ```http://localhost:8080/spring4ajax``` 18 | 19 | ###3. To import this project into Eclipse IDE 20 | 1. ```$ mvn eclipse:eclipse``` 21 | 2. Import into Eclipse via **existing projects into workspace** option. 22 | 3. Done. 23 | 24 | ###4. Project Demo 25 | Please refer to this article [Spring 4 Ajax Example](http://www.mkyong.com/spring-mvc/spring-4-mvc-ajax-hello-world-example/) 26 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.mkyong 5 | spring4-mvc-maven-ajax-example 6 | war 7 | 1.0-SNAPSHOT 8 | spring4 mvc maven ajax example 9 | 10 | 11 | 1.8 12 | 4.2.2.RELEASE 13 | 2.6.3 14 | 1.1.3 15 | 1.7.12 16 | 1.2 17 | 3.1.0 18 | 19 | 20 | 21 | 22 | 23 | org.springframework 24 | spring-webmvc 25 | ${spring.version} 26 | 27 | 28 | commons-logging 29 | commons-logging 30 | 31 | 32 | 33 | 34 | 35 | 36 | com.fasterxml.jackson.core 37 | jackson-core 38 | ${jackson.version} 39 | 40 | 41 | 42 | com.fasterxml.jackson.core 43 | jackson-databind 44 | ${jackson.version} 45 | 46 | 47 | 48 | 49 | javax.servlet 50 | jstl 51 | ${jstl.version} 52 | 53 | 54 | 55 | 56 | org.slf4j 57 | jcl-over-slf4j 58 | ${jcl.slf4j.version} 59 | 60 | 61 | 62 | ch.qos.logback 63 | logback-classic 64 | ${logback.version} 65 | 66 | 67 | 68 | 69 | 70 | javax.servlet 71 | javax.servlet-api 72 | ${servletapi.version} 73 | provided 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | org.apache.maven.plugins 83 | maven-compiler-plugin 84 | 3.3 85 | 86 | ${jdk.version} 87 | ${jdk.version} 88 | 89 | 90 | 91 | 92 | org.eclipse.jetty 93 | jetty-maven-plugin 94 | 9.2.11.v20150529 95 | 96 | 10 97 | 98 | /spring4ajax 99 | 100 | 101 | 102 | 103 | 104 | org.apache.maven.plugins 105 | maven-eclipse-plugin 106 | 2.10 107 | 108 | true 109 | true 110 | 2.0 111 | spring4ajax 112 | 113 | 114 | 115 | 116 | org.apache.maven.plugins 117 | maven-war-plugin 118 | 2.6 119 | 120 | false 121 | 122 | 123 | 124 | 125 | 126 | org.wildfly.plugins 127 | wildfly-maven-plugin 128 | 1.1.0.Alpha5 129 | 130 | 127.0.0.1 131 | 9990 132 | admin 133 | admin 134 | spring4ajax.war 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /src/main/java/com/mkyong/config/SpringWebConfig.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.config; 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.ResourceHandlerRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 9 | import org.springframework.web.servlet.view.InternalResourceViewResolver; 10 | import org.springframework.web.servlet.view.JstlView; 11 | 12 | @EnableWebMvc 13 | @Configuration 14 | @ComponentScan({ "com.mkyong.web" }) 15 | public class SpringWebConfig extends WebMvcConfigurerAdapter { 16 | 17 | @Override 18 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 19 | registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); 20 | } 21 | 22 | @Bean 23 | public InternalResourceViewResolver viewResolver() { 24 | InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 25 | viewResolver.setViewClass(JstlView.class); 26 | viewResolver.setPrefix("/WEB-INF/views/jsp/"); 27 | viewResolver.setSuffix(".jsp"); 28 | return viewResolver; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /src/main/java/com/mkyong/servlet3/MyWebInitializer.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.servlet3; 2 | 3 | import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 4 | 5 | import com.mkyong.config.SpringWebConfig; 6 | 7 | public class MyWebInitializer extends 8 | AbstractAnnotationConfigDispatcherServletInitializer { 9 | 10 | @Override 11 | protected Class>[] getServletConfigClasses() { 12 | return new Class[] { SpringWebConfig.class }; 13 | } 14 | 15 | @Override 16 | protected String[] getServletMappings() { 17 | return new String[] { "/" }; 18 | } 19 | 20 | @Override 21 | protected Class>[] getRootConfigClasses() { 22 | return null; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/main/java/com/mkyong/web/controller/AjaxController.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.web.controller; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.PostConstruct; 7 | 8 | import org.springframework.util.StringUtils; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import com.fasterxml.jackson.annotation.JsonView; 14 | import com.mkyong.web.jsonview.Views; 15 | import com.mkyong.web.model.AjaxResponseBody; 16 | import com.mkyong.web.model.SearchCriteria; 17 | import com.mkyong.web.model.User; 18 | 19 | @RestController 20 | public class AjaxController { 21 | 22 | List users; 23 | 24 | // @ResponseBody, not necessary, since class is annotated with @RestController 25 | // @RequestBody - Convert the json data into object (SearchCriteria) mapped by field name. 26 | // @JsonView(Views.Public.class) - Optional, limited the json data display to client. 27 | @JsonView(Views.Public.class) 28 | @RequestMapping(value = "/search/api/getSearchResult") 29 | public AjaxResponseBody getSearchResultViaAjax(@RequestBody SearchCriteria search) { 30 | 31 | AjaxResponseBody result = new AjaxResponseBody(); 32 | 33 | if (isValidSearchCriteria(search)) { 34 | List users = findByUserNameOrEmail(search.getUsername(), search.getEmail()); 35 | 36 | if (users.size() > 0) { 37 | result.setCode("200"); 38 | result.setMsg(""); 39 | result.setResult(users); 40 | } else { 41 | result.setCode("204"); 42 | result.setMsg("No user!"); 43 | } 44 | 45 | } else { 46 | result.setCode("400"); 47 | result.setMsg("Search criteria is empty!"); 48 | } 49 | 50 | //AjaxResponseBody will be converted into json format and send back to client. 51 | return result; 52 | 53 | } 54 | 55 | private boolean isValidSearchCriteria(SearchCriteria search) { 56 | 57 | boolean valid = true; 58 | 59 | if (search == null) { 60 | valid = false; 61 | } 62 | 63 | if ((StringUtils.isEmpty(search.getUsername())) && (StringUtils.isEmpty(search.getEmail()))) { 64 | valid = false; 65 | } 66 | 67 | return valid; 68 | } 69 | 70 | // Init some users for testing 71 | @PostConstruct 72 | private void iniDataForTesting() { 73 | users = new ArrayList(); 74 | 75 | User user1 = new User("mkyong", "pass123", "mkyong@yahoo.com", "012-1234567", "address 123"); 76 | User user2 = new User("yflow", "pass456", "yflow@yahoo.com", "016-7654321", "address 456"); 77 | User user3 = new User("laplap", "pass789", "mkyong@yahoo.com", "012-111111", "address 789"); 78 | users.add(user1); 79 | users.add(user2); 80 | users.add(user3); 81 | 82 | } 83 | 84 | // Simulate the search function 85 | private List findByUserNameOrEmail(String username, String email) { 86 | 87 | List result = new ArrayList(); 88 | 89 | for (User user : users) { 90 | 91 | if ((!StringUtils.isEmpty(username)) && (!StringUtils.isEmpty(email))) { 92 | 93 | if (username.equals(user.getUsername()) && email.equals(user.getEmail())) { 94 | result.add(user); 95 | continue; 96 | } else { 97 | continue; 98 | } 99 | 100 | } 101 | if (!StringUtils.isEmpty(username)) { 102 | if (username.equals(user.getUsername())) { 103 | result.add(user); 104 | continue; 105 | } 106 | } 107 | 108 | if (!StringUtils.isEmpty(email)) { 109 | if (email.equals(user.getEmail())) { 110 | result.add(user); 111 | continue; 112 | } 113 | } 114 | 115 | } 116 | 117 | return result; 118 | 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/mkyong/web/controller/WelcomeController.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.web.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.ui.ModelMap; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | 8 | @Controller 9 | public class WelcomeController { 10 | 11 | @RequestMapping(value = "/", method = RequestMethod.GET) 12 | public String printWelcome(ModelMap model) { 13 | return "welcome"; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/mkyong/web/jsonview/Views.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.web.jsonview; 2 | 3 | public class Views { 4 | public static class Public {} 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/mkyong/web/model/AjaxResponseBody.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.web.model; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonView; 6 | import com.mkyong.web.jsonview.Views; 7 | 8 | public class AjaxResponseBody { 9 | 10 | @JsonView(Views.Public.class) 11 | String msg; 12 | @JsonView(Views.Public.class) 13 | String code; 14 | @JsonView(Views.Public.class) 15 | List result; 16 | 17 | public String getMsg() { 18 | return msg; 19 | } 20 | 21 | public void setMsg(String msg) { 22 | this.msg = msg; 23 | } 24 | 25 | public String getCode() { 26 | return code; 27 | } 28 | 29 | public void setCode(String code) { 30 | this.code = code; 31 | } 32 | 33 | public List getResult() { 34 | return result; 35 | } 36 | 37 | public void setResult(List result) { 38 | this.result = result; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "AjaxResponseResult [msg=" + msg + ", code=" + code + ", result=" + result + "]"; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/mkyong/web/model/SearchCriteria.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.web.model; 2 | 3 | public class SearchCriteria { 4 | 5 | String username; 6 | String email; 7 | 8 | public String getUsername() { 9 | return username; 10 | } 11 | 12 | public void setUsername(String username) { 13 | this.username = username; 14 | } 15 | 16 | public String getEmail() { 17 | return email; 18 | } 19 | 20 | public void setEmail(String email) { 21 | this.email = email; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "SearchCriteria [username=" + username + ", email=" + email + "]"; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/mkyong/web/model/User.java: -------------------------------------------------------------------------------- 1 | package com.mkyong.web.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonView; 4 | import com.mkyong.web.jsonview.Views; 5 | 6 | public class User { 7 | 8 | @JsonView(Views.Public.class) 9 | String username; 10 | String password; 11 | @JsonView(Views.Public.class) 12 | String email; 13 | @JsonView(Views.Public.class) 14 | String phone; 15 | String address; 16 | 17 | public User() { 18 | } 19 | 20 | public User(String username, String password, String email, String phone, String address) { 21 | super(); 22 | this.username = username; 23 | this.password = password; 24 | this.email = email; 25 | this.phone = phone; 26 | this.address = address; 27 | } 28 | 29 | public String getUsername() { 30 | return username; 31 | } 32 | 33 | public void setUsername(String username) { 34 | this.username = username; 35 | } 36 | 37 | public String getPassword() { 38 | return password; 39 | } 40 | 41 | public void setPassword(String password) { 42 | this.password = password; 43 | } 44 | 45 | public String getEmail() { 46 | return email; 47 | } 48 | 49 | public void setEmail(String email) { 50 | this.email = email; 51 | } 52 | 53 | public String getPhone() { 54 | return phone; 55 | } 56 | 57 | public void setPhone(String phone) { 58 | this.phone = phone; 59 | } 60 | 61 | public String getAddress() { 62 | return address; 63 | } 64 | 65 | public void setAddress(String address) { 66 | this.address = address; 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return "User [username=" + username + ", password=" + password + ", email=" + email + ", phone=" + phone 72 | + ", address=" + address + "]"; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/jsp/welcome.jsp: -------------------------------------------------------------------------------- 1 | <%@page session="false"%> 2 | <%@taglib prefix="spring" uri="http://www.springframework.org/tags"%> 3 | <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 4 | 5 | 6 | 7 | Spring MVC 4 + Ajax Hello World 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Spring 4 MVC Ajax Hello World 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Search Form 34 | 35 | 36 | 37 | 38 | 39 | 40 | Username 41 | 42 | 43 | 44 | 45 | 46 | Email 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Search 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 70 | 71 | 72 | 128 | 129 | 130 |