Spring MVC中使用JSON,先必需引用两个包:jackson-core-asl-1.9.13.jar、jackson-mapper-asl-1.9.13.jar
因为需要使用到jquery测试,如果在项目中的web.xml配置Spring MVC是“/”,比如:
<servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
意思匹配所有的路径使用Spring MVC做解释的话,那么需要在Spring MVC的配置文件中加入:
<mvc:resources location="/js/" mapping="/js/**" />
用于过滤对指定路径不使用Spring MVC解释器。
先看这个model entity:
package com.my.controller.bean; import org.hibernate.validator.constraints.NotEmpty; public class Account { @NotEmpty(message="{valid.required}") private String userName; @NotEmpty(message="{valid.required}") private String password; 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; } }
这是一个简单的model,使用了annotation做数据验证。
Controller:
package com.my.controller; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.my.controller.bean.Account; @Controller @RequestMapping(value="json") public class TestJsonController { /** * 静态accounts */ private List<Account> accounts = new ArrayList<Account>(); { Account acc1 = new Account(); Account acc2 = new Account(); acc1.setUserName("Robin"); acc1.setPassword("password"); acc2.setUserName("Lucy"); acc2.setPassword("123456"); accounts.add(acc1); accounts.add(acc2); } /** * 默认地址 * @return */ @RequestMapping(method=RequestMethod.GET) public ModelAndView index() { ModelAndView view = new ModelAndView("TestJson/index"); view.addObject("accounts", accounts); return view; } /** * 新增account * @param account * @param model * @return */ @RequestMapping(value="add", method=RequestMethod.POST) @ResponseBody public Map<String, Object> add(@RequestBody @Valid Account account, BindingResult bindingResult) { Map<String, Object> result = new HashMap<String, Object>(); if(bindingResult.hasErrors()) { List<FieldError> errs = bindingResult.getFieldErrors(); Map<String, String> mapErrors = new LinkedHashMap<String, String>(); for(FieldError err : errs) { mapErrors.put(err.getField(), err.getDefaultMessage()); } result.put("success", false); result.put("errors", mapErrors); return result; } accounts.add(account); result.put("success", true); result.put("data", accounts); return result; } /** * 取得所有accounts * @return */ @RequestMapping(value="accounts", method=RequestMethod.GET) @ResponseBody public List<Account> findAccounts() { return accounts; } }
1、初始了一个static的accounts
2、默认index中有一个view
3、add(...) 方法:
- @ResponseBody这个annotation,意思是直接输出
- 在参数中@RequestBody @Valid这两个annotation是json提交时的需要的,@RequestBody是必需的,@Valid是数据验证必需的
- BindingResult,必需要紧跟实体model之后,否则取不到验证结果
- 本例使用了一个Map做数据返回,Spring MVC会直接对这个Map转换成JSON结果字符串
- 如果验证失败,使用一个map加入错误信息返回
4、findAccounts()方法可以直接返回json。注意@ResponseBody
View:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <%@ taglib prefix="st" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.json.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.8.3.js"></script> <title>Test Json</title> <script type="text/javascript"> $(document).ready(function() { getData(); }); //------------------------------------------------- // 取得JSON数据 //------------------------------------------------- function getData() { var url = "${pageContext.request.contextPath}/json/accounts"; $.get(url).success(function(data, status, xhr) { setData(data); }); } //------------------------------------------------- // 设置JSON数据 //------------------------------------------------- function setData(data) { var div = $("#divJson"); div.html(""); $(data).each(function(index, row) { div.append("User_" + index + ":" + row.userName + "<br/>"); }); } //------------------------------------------------- // Add按钮事件 //------------------------------------------------- function addClick() { var url = "${pageContext.request.contextPath}/json/add"; var data = { userName: $("#userName").val(), password: "pass" }; // POST JSON数据到服务器 $.ajax({ url: url, dataType: "json", contentType: "application/json", type: "POST", data: JSON.stringify(data), success: function (data) { if(data.success) { setData(data.data); } else { var text = ""; $(data.errors).each(function(index, row) { text += "<font color='red'>" + row.userName + "</font><br/>"; }); $("#divJson").html(text); } }, error: function () { } }); } </script> </head> <body> <b>HTML:</b><hr/> <c:set scope="page" var="index" value="0"></c:set> <c:forEach items="${accounts}" var="item"> User_<c:set scope="page" value="${index+1}" var="index"></c:set>${index}: <c:out value="${item.userName}"></c:out><br/> </c:forEach> <hr/> <b>Json:</b><hr/> <div id="divJson"></div> <hr/> User name:<input type="text" id="userName" name="userName" value="" /> <input type="button" id="btnAdd" name="btnAdd" value="Call Ajax add account" onclick="addClick()" /> </body> </html>
这里使用正常输出和json输出两种方式。
运行结果:
不输入user name时:
正确输入时: