1.返回json
2.Ajax请求
3.多视图输出
4.MyBatis使用
这是一个Spring MVC 4 实现Ajax 的 post请求用户信息的Demo.
纯注解配置。
1.工程结构
2.pom.xml文件
<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.jeiker.demo</groupId>
<artifactId>springdemo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>springdemo Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<jdk.version>1.8</jdk.version>
<spring.version>4.2.2.RELEASE</spring.version>
<jackson.version>2.8.5</jackson.version>
<logback.version>1.1.7</logback.version>
<jcl.slf4j.version>1.7.21</jcl.slf4j.version>
<jstl.version>1.2</jstl.version>
<servletapi.version>3.1.0</servletapi.version>
<junit.version>3.8.1</junit.version>
</properties>
<dependencies>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- spring-webmvc 排除日志依赖-->
<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>
<!-- json转对象 ,对象转json -->
<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>
<!-- view层的 jsp标准函数库 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- 日志 -->
<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>
<!-- 仅在编译时使用, 布署不用,布署时容器会提供 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servletapi.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>springdemo</finalName>
<plugins>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<!-- 部署至本机 -->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.9.v20160517</version>
<configuration>
<httpConnector>
<port>8080</port>
</httpConnector>
<webAppConfig>
<contextPath>/</contextPath>
</webAppConfig>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.spring配置文件
这里使用了java代码配置的方式:
package com.jeiker.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;
/**
* @Author : xiao
* @Date : 16/12/21 下午3:07
*/
@EnableWebMvc
@Configuration
@ComponentScan({"com.jeiker.web"})
public class SpringWebConfig extends WebMvcConfigurerAdapter{
/**
* 资源访问处理器:注册资源文件
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
/**
* 视图解析器:配置JSP文件作为视图
*/
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
4.servlet配置文件
package com.jeiker.servlet3;
import com.jeiker.config.SpringWebConfig;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* 使用java config 代替 xml config
*/
public class MyWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringWebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
5.MVC相关文件
5.1 Model
AjaxResponseBody.java (ajax响应的模型)
package com.jeiker.web.model;
import com.fasterxml.jackson.annotation.JsonView;
import com.jeiker.web.view.Views;
import java.util.List;
/**
* 返回参数模型
*/
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;
}
@Override
public String toString() {
return "AjaxResponseBody { msg=" + msg + ", code=" + code + ", result=" + result + " }";
}
}
SearchCriteria.java (查询用户的入参模型)
package com.jeiker.web.model;
/**
* 入参模型
*/
public class SearchCriteria {
String username;
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;
}
}
User.java (用户模型实体)
package com.jeiker.web.model;
import com.fasterxml.jackson.annotation.JsonView;
import com.jeiker.web.view.Views;
/**
* 用户模型,实体模型
*/
public class User {
@JsonView(Views.Public.class)
String username;
String password;
@JsonView(Views.Public.class)
String email;
@JsonView(Views.Public.class)
String phone;
@JsonView(Views.Public.class)
String address;
public User() {
}
public User(String username, String password, String email, String phone, String address) {
super();
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;
}
@Override
public String toString() {
return "User {username=" + username + ", password=" + password + ", email=" + email + ", phone=" + phone +
", address=" + address + "}";
}
}
5.2 Controller
WelcomeController.java (欢迎界面的Controller)
package com.jeiker.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @Author : xiao
* @Date : 16/12/21 下午3:49
*/
@Controller
public class WelcomeController {
/**
* "/"路径,GET请求映射,返回welcome.jsp
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
return "welcome";
}
}
AjaxController.java (Ajax请求的Controller)
package com.jeiker.web.controller;
import com.fasterxml.jackson.annotation.JsonView;
import com.jeiker.web.model.AjaxResponseBody;
import com.jeiker.web.model.SearchCriteria;
import com.jeiker.web.model.User;
import com.jeiker.web.view.Views;
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 javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/**
* @Author : xiao
* @Date : 16/12/21 下午3:49
*/
@RestController
public class AjaxController {
List<User> userList;
/**
* @ResponseBody 不再需要,当前类已经注解为 @RestController
* @ResponseBody :将对象(AjaxResponseBody)转为json数据,返回给前端
* @RequestBody :将前端请求的json数据转换为对象(SearchCriteria)
* @JsonView(Views.Public.class) :可选,限制返回给前端的json数据字段(不返回密码等)
*/
@JsonView(Views.Public.class)
@RequestMapping(value = "/search/api/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("");
result.setResult(users);
} else {
result.setCode("204");
result.setMsg("No user!");
}
} else {
result.setCode("400");
result.setMsg("Search criteria is empty!");
}
// AjaxResponseBody 模型将会转化为json数据,并返回给前端.
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;
}
/**
* 初始化一些用户数据作测试
*/
@PostConstruct
private void iniDataForTesting() {
userList = new ArrayList<User>();
User user1 = new User("jeiker", "pass123", "jeiker@126.com", "110-1234567", "address 123");
User user2 = new User("xiao", "pass456", "xiao@163.com", "119-1234567", "address 456");
User user3 = new User("xiaoxiao", "pass789", "jeikerxiao@qq.com", "120-1234567", "address 789");
userList.add(user1);
userList.add(user2);
userList.add(user3);
}
/**
* 查询用户的方法
*/
private List<User> findByUserNameOrEmail(String username, String email) {
List<User> result = new ArrayList<User>();
for (User user : userList) {
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;
}
}
5.3 View
View.java (视图模型,结合User模型看,注意@JsonView(Views.Public.class))
package com.jeiker.web.view;
/**
* @Author : xiao
* @Date : 16/12/21 下午3:36
*/
public class Views {
public static class Public {}
}
6.前端界面
welcome.jsp
<%@page session="false"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Spring MVC 4 + Ajax Hello World</title>
<c:url var="home" value="/" scope="request" />
<spring:url value="/resources/core/css/hello.css" var="coreCss" />
<spring:url value="/resources/core/css/bootstrap.min.css" var="bootstrapCss" />
<link href="${bootstrapCss}" rel="stylesheet" />
<link href="${coreCss}" rel="stylesheet" />
<spring:url value="/resources/core/js/jquery.1.10.2.min.js" var="jqueryJs" />
<script src="${jqueryJs}"></script>
</head>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">Spring 4 MVC Ajax Hello World</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">
<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="#">jeikerxiao.com</a> 2016
</p>
</footer>
</div>
<script>
jQuery(document).ready(function($) {
$("#search-form").submit(function(event) {
// 关闭搜索按钮
enableSearchButton(false);
// 当点击搜索按钮时阻止对表单的提交
event.preventDefault();
// ajax请求后台
searchViaAjax();
});
});
// ajax请求后台
function searchViaAjax() {
var search = {};
search["username"] = $("#username").val();
search["email"] = $("#email").val();
$.ajax({
type : "POST",
contentType : "application/json",
url : "${home}search/api/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);
}
// 显示后台返回的json数据
function display(data) {
var json = "<h4>Ajax Response</h4>"
+ "<pre>"
+ JSON.stringify(data, null, 4)
+ "</pre>";
$('#feedback').html(json);
}
</script>
</body>
</html>
7.运行结果
jetty:run 运行
7.1 运行配置
7.2 Post测试
使用Postman工具查看: