本篇文章,我们会教你通过maven和spring mvc + bootstrap创建一个Java web项目的欢迎页,并通过Ajax方式提交一个表单,并实现前台与后台的连接。
开发环境:
1.jdk 1.7
2.Maven 3.3.9
3.Eclipse Mars.1
4.Spring 4.2.1.RELEASE
5.Bootstrap
6.
jQuery
7.
Tomcat7
8.Jackson 2.6.3
Tips: 如果在项目中有Jackson的jar包,Spring会用Jackson自动处理json数据(将json各式的数据转换为object类型,或者将object类型的数据转为json格式的)。
1.目录结构,一个标准的maven项目目录结构(前面文章已经说明如何用maven创建项目)
2.pom文件
<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>org.thinkingingis</groupId>
<artifactId>SpringmvcAjax</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringmvcAjax Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<jdk.version>1.7</jdk.version>
<spring.version>4.2.2.RELEASE</spring.version>
<jackson.version>2.6.3</jackson.version>
<logback.version>1.1.3</logback.version>
<jcl.slf4j.version>1.7.12</jcl.slf4j.version>
<jstl.version>1.2</jstl.version>
<servletapi.version>3.1.0</servletapi.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Need this for json to/from object -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- JSTL for views -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${jcl.slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- compile only, runtime container will provide this -->
<!-- Need this for config annotation -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servletapi.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>SpringmvcAjax</finalName>
</build>
</project>
3.Sping组件
3.1 通过 @RestController
截获Ajax请求
AjaxController.java
package org.thinkingingis.web.controller;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thinkingingis.web.jsonview.Views;
import org.thinkingingis.web.model.AjaxResponseBody;
import org.thinkingingis.web.model.SearchCriteria;
import org.thinkingingis.web.model.User;
import com.fasterxml.jackson.annotation.JsonView;
@RestController
@RequestMapping("search")
public class AjaxController {
List<User> users;
// @ResponseBody, not necessary, since class is annotated with @RestController
// @RequestBody - Convert the json data into object (SearchCriteria) mapped by field name.
// @JsonView(Views.Public.class) - Optional, filters json data to display.
@JsonView(Views.Public.class)
@RequestMapping("getSearchResult")
public AjaxResponseBody getSearchResultViaAjax(@RequestBody SearchCriteria search) {
AjaxResponseBody result = new AjaxResponseBody();
if (isValidSearchCriteria(search)) {
List<User> users = findByUserNameOrEmail(search.getUsername(), search.getEmail());
if (users.size() > 0) {
result.setCode("200");
result.setMsg("Found the user!");
result.setResult(users);
} else {
result.setCode("204");
result.setMsg("No user!");
}
} else {
result.setCode("400");
result.setMsg("Search criteria is empty!");
}
//AjaxResponseBody will be converted into json format and send back to the request.
return result;
}
private boolean isValidSearchCriteria(SearchCriteria search) {
boolean valid = true;
if (search == null) {
valid = false;
}
if ((StringUtils.isEmpty(search.getUsername())) && (StringUtils.isEmpty(search.getEmail()))) {
valid = false;
}
return valid;
}
// Init some users for testing
@PostConstruct
private void iniDataForTesting() {
users = new ArrayList<User>();
User user1 = new User("ThinkingInGIS", "gis123", "twicethoughts@gmail.com", "13520527365", "BJ");
User user2 = new User("Thinking", "gis456", "twicethoughts@gmail.com", "13520527365", "bj");
User user3 = new User("In", "gis789", "twicethoughts@gmail.com", "13520527365", "bj");
User user4 = new User("GIS", "gis789", "twicethoughts@gmail.com", "13520527365", "bj");
users.add(user1);
users.add(user2);
users.add(user3);
users.add(user4);
}
// Simulate the search function
private List<User> findByUserNameOrEmail(String username, String email) {
List<User> result = new ArrayList<User>();
for (User user : users) {
if ((!StringUtils.isEmpty(username)) && (!StringUtils.isEmpty(email))) {
if (username.equals(user.getUsername()) && email.equals(user.getEmail())) {
result.add(user);
continue;
} else {
continue;
}
}
if (!StringUtils.isEmpty(username)) {
if (username.equals(user.getUsername())) {
result.add(user);
continue;
}
}
if (!StringUtils.isEmpty(email)) {
if (email.equals(user.getEmail())) {
result.add(user);
continue;
}
}
}
return result;
}
}
3.2 通过@ResponseBody , json格式的数据会转成SearchCriteria类型
SearchCriteria.java
package org.thinkingingis.web.model;
public class SearchCriteria {
private String username;
private String email;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Views.java
package org.thinkingingis.web.jsonview;
public class Views {
public static class Public {
}
}
AjaxResponseBody.java
package org.thinkingingis.web.model;
import java.util.List;
import org.thinkingingis.web.jsonview.Views;
import com.fasterxml.jackson.annotation.JsonView;
public class AjaxResponseBody {
@JsonView(Views.Public.class)
String msg;
@JsonView(Views.Public.class)
String code;
@JsonView(Views.Public.class)
List<User> result;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public List<User> getResult() {
return result;
}
public void setResult(List<User> result) {
this.result = result;
}
}
User.java
package org.thinkingingis.web.model;
import org.thinkingingis.web.jsonview.Views;
import com.fasterxml.jackson.annotation.JsonView;
public class User {
@JsonView(Views.Public.class)
String username;
String password;
@JsonView(Views.Public.class)
String email;
@JsonView(Views.Public.class)
String phone;
String address;
public User(String username, String password, String email, String phone, String address) {
this.username = username;
this.password = password;
this.email = email;
this.phone = phone;
this.address = address;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
4.Spring 装载配置(通过java代码来进行配置)
SpringWebConfig.java
package org.thinkingingis.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
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 org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@EnableWebMvc
@Configuration
@ComponentScan({ "org.thinkingingis.web" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
5.servlet初始化配置
MyWebInitializer.java
package org.thinkingingis.servlet3;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.thinkingingis.config.SpringWebConfig;
public class MyWebInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringWebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
}
6.index.jsp
<%@page session="false"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Spring MVC + Ajax</title>
<link href="./resources/css/bootstrap.min.css" rel="stylesheet">
<script type="text/javascript" src="./resources/js/jquery.js"></script>
<script type="text/javascript" src="./resources/js/bootstrap.min.js"></script>
</head>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Spring MVC Ajax</a>
</div>
</div>
</nav>
<div class="container" style="min-height: 500px">
<div class="starter-template">
<h1>Search Form</h1>
<br>
<div id="feedback"></div>
<form class="form-horizontal" id="search-form" action="search/getSearchResult">
<div class="form-group form-group-lg">
<label class="col-sm-2 control-label">Username</label>
<div class="col-sm-10">
<input type=text class="form-control" id="username">
</div>
</div>
<div class="form-group form-group-lg">
<label class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="email">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" id="bth-search"
class="btn btn-primary btn-lg">Search</button>
</div>
</div>
</form>
</div>
</div>
<div class="container">
<footer>
<p>
© <a href="">SOURCE CODE</a>
</p>
</footer>
</div>
<script>
jQuery(document).ready(function($) {
$("#search-form").submit(function(event) {
// Disble the search button
enableSearchButton(false);
// Prevent the form from submitting via the browser.
event.preventDefault();
searchViaAjax();
});
});
function searchViaAjax() {
var search = {}
search["username"] = $("#username").val();
search["email"] = $("#email").val();
$.ajax({
type : "POST",
contentType : "application/json",
url : "search/getSearchResult",
data : JSON.stringify(search),
dataType : 'json',
timeout : 100000,
success : function(data) {
console.log("SUCCESS: ", data);
display(data);
},
error : function(e) {
console.log("ERROR: ", e);
display(e);
},
done : function(e) {
console.log("DONE");
enableSearchButton(true);
}
});
}
function enableSearchButton(flag) {
$("#btn-search").prop("disabled", flag);
}
function display(data) {
var json = "<h4>Ajax Response</h4><pre>"
+ JSON.stringify(data, null, 4) + "</pre>";
$('#feedback').html(json);
}
</script>
</body>
</html>
7.启动项目
浏览器中输入:http://localhost:8080/SpringmvcAjax/
通过已有用户名进行搜索
对不存在的用户名进行搜索:
至此,一个通过简单的spring mvc + bootstrap + ajax的小程序就完成啦。
thinkingingis@qq.com)
微信公众号:ThinkingInGIS
欢迎大家关注:)